Reputation: 3
Arch=x86_64
I am working through a DMA solution following the process outlined in this question, Direct Memory Access in Linux
My call to ioremap
successfully returns with an address, pt.
In my call to remap_pfn_range
I use, virt_to_phys(pt) >> PAGE_SHIFT
, to specify the pfn of the area generated by the ioremap
call.
When the userspace application using mmap
executes and the call to remap_pfn_range
is made, the machine crashes. I assume the mapping is off and I am forcing the system to use memory that is already allocated (screen glitches before exit), however I'm not clear on where the mismatch is occurring. The system has 4 Gigs of Ram and I reserved 2Gigs by using the kernel boot option mem=2048M
.
I use BUFFER_SIZE=1024u*1024u*1024u
and BUFFER_OFFSET=2u*1024u*1024u*1024u
.
putting these into pt=ioremap(BUFFER_SIZE,BUFFER_OFFSET)
I believe pt should equal a virtual address to the physical memory located at the 2GB boundary up to the 3GB boundary. Is this assumption accurate?
When I execute my kernel module, but I change my remap_pfn_range
to use vma->vm_pgoff>>PAGE_SHIFT
as the target pfn the code executes with no error and I can read and write to the memory. However this is not using the reserved physical memory that I intended.
Since everything works when using vma->vm_pgoff>>PAGE_SHIFT
I believe my culprit is between my ioremap
and the remap_pfn_range
Thanks for any suggestions!
The motivation behind the use of this kernel module is the need for large contiguous buffers for DMA from a PCI device. In this application, recompiling the kernel isn't an option so I'm trying to accomplish it with a module + hardware.
Upvotes: 0
Views: 1041
Reputation: 3935
My call to ioremap successfully returns with an address, pt.
In my call to remap_pfn_range I use, virt_to_phys(pt) >> PAGE_SHIFT, to specify the pfn of the area generated by the ioremap call.
This is illegal, because ioremap reserves virtual region in vmalloc area. The virt_to_phys() is OK only for linearly mapped part of memory.
putting these into pt=ioremap(BUFFER_SIZE,BUFFER_OFFSET) I believe pt should equal a virtual address to the physical memory located at the 2GB boundary up to the 3GB boundary. Is this assumption accurate?
That is not exactly true, for example on my machine cat /proc/iomem
...
00001000-0009ebff : System RAM
...
00100000-1fffffff : System RAM
...
There may be several memory banks, and the memory not obligatory will start at address 0x0 of physical address space.
This might be usefull for you Dynamic DMA mapping Guide
Upvotes: 1