howto access user space memory from hardware

Jan 24, 2008 5 Replies

Hello,



I'm working on a Linux (2.4.x) driver for an DMA-Controller. My platform is an FPGA with an embedded PowerPC 405.



I want to have the DMA-Controller access a memory block in user space. I already found out that this memory block is organised in pages and there are several translations done to get from a virtual (user space) address to a physical address (by kernel, MMU, ...) ...



How can I get all the physical addresses of these pages and how can I lock(unlock) these pages to prevent swapping while hardware access.



Many thanks! Felix


We have the same issue and coudn't find any reliable method to do that. So we are currently trying to use kernel memory to DMA stuff in to and then using Mmap/Splice to get access to that data from user space. Our DMA engine (SOC on MPC8349) only supports physical addresses. However I read (in this mailing list I think) that some of the DMA engines supports writing to virtual address space. If anyone knows of a way please let us know how.

What we did was reduce the amount of memory Linux uses (mem= command line option). This causes Linux to not claim all the memory, and leaves a part at the top of the memory untouched by Linux and the MMU. You can use this area for your DMA engine, and can get userspace access to it by using mmap.

Kind regards, Johan Borkhuis

Hi,

On a 2.6 PPC system, I use something along the lines of:

  • pass pointer to user memory via an ioctl()
  • get_user_pages() - gives you a set of pointers to the pages in question
  • page_address() gives me a kernel virtual address for a page
  • hardware physical address = virt_to_bus(kernel virtual address)

I didn't bother with pining the memory as I work on diskless systems. However, lxr will probably be your friend or alternatively the rather fun interactive source map at:

formatting link

Oh, and remember to use semaphores around any access to the page table (current->mm->mmap_sem).

Unfortunately, I'm not sure how much of a difference there would be in moving back to 2.4 though.

HTH, John McCallum, Edinburgh

AFAIK, you should register a block of contiguous memory in the driver when the system starts (make the driver start early so that there is large enough a block of contiguous memory available).

Later the user land application by some write() or ioctrl() requests the driver () to map the memory in it's user space, which same can do by some systcall.

-Michael

Thanks guys. Will give this a try! Cheers

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required