Forums » Software Development »
Memory Aligned Byte Array
Added by Alexander Block over 10 years ago
Posted on behalf of a customer:
I have a byte array in my Linux application into which I want my DMA firmware to write. I need the byte array to be memory aligned
to a certain offset. From what the compiler is telling me, the most I can align a char[] by is 15 bits (a 32K boundary). Is there a way
to make this boundary larger? How large?
ARMs documentation says its compiler is able to do alignments right up to 32 bits. What am I doing wrong?
Thank you.
Replies (4)
RE: Memory Aligned Byte Array - Added by Michael Williamson over 10 years ago
Not entirely sure what you are up to here.
Is your linux application running in user space? If it is, you may need to deal with the fact that you are working with virtual memory space that's chunked up into 4K page sizes if you are creating data on the heap or with global arrays. Your application pointers are not going to be the same as the physical addresses needed by a DMA controller. Perhaps you already have this sorted out?
Normally for user space control/access of DMA areas, what we do is reserve some memory above the linux kernel (by restricting it to less than 1 GB using the mem= kernel parameter), then mmap it in using /dev/mem. Then you can tell your DMA to transfer in/out using computed physical addresses and if you are using a character pointer just assign it to the address you are working with.
Have you taken a look at this example project?
-Mike
RE: Memory Aligned Byte Array - Added by Julio Liriano over 10 years ago
Mike,
I'm writing a device driver to handle this DMA setup. I want the kernel to give me a chunk of physical memory aligned so that the least significant T bits (I'm not so sure of the exact size I want)
are zero. The reason for the alignment requirement is because my DMA device is going to write user-defined "page" sized bursts of either 16, 32 or 64 bits. I wanted to keep the physical addressing
simple by using a register to offset into the DMA area when writing. This would prevent the FPGA firmware (which I'm still working on) from accidentally writing into areas where it shouldn't because
the range of the offset register will sit perfectly within the bounds of the allocated memory space.
Does the method you listed involve recompiling the kernel?
RE: Memory Aligned Byte Array - Added by Michael Williamson over 10 years ago
Any kernel memory allocation is going to be page aligned (4K), it has to be. That's how the linux kernel memory management / page tables work.
You could have your driver allocate a page (do you need more? you can make continuous physical RAM but it gets a little more complicated to guarantee you will get a contiguous buffer) and implement a mmap() filesystem operator and allow your app to offset anywhere it likes within the buffer. But, you'll also need a method to convert the logical / virtual address (kernel/app) to physical for your DMA.
The method I listed should be achievable without recompiling the kernel.
-Mike
RE: Memory Aligned Byte Array - Added by Julio Liriano over 10 years ago
Mike,
I will definitely need more than a single 4096 byte page. I can
call __get_free_pages() to allocate a continuous chunk of pages
but is there a way of doing so so that the beginning offset is on
a 32K boundary (for example) ?
Can I simply declare an array inside the driver body like this:
uint dataArray4096 attribute ((aligned(32768)));
This doesn't seem to generate any compiler complaints.
I'd then use a virtual-to-physical function to get the physical
address to which the FPGA could DMA and to which the user space
can mmap to.