通过remap_pfn_range将dmam_alloc_coherent分配的内存映射到用户空间会提供指向错误内存区域的指针

时间:2019-01-01 11:45:13

标签: linux arm mapping dma

我准备在ARM Intel Cyclone V SoC上运行的应用程序。 我需要将DMA相干内存缓冲区映射到用户空间。 使用以下命令在设备驱动程序中分配缓冲区:

buf_addr = dmam_alloc_coherent(&pdev->dev, size, &dma_addr, GFP_KERNEL);

映射正确完成,并且我已经验证了,通过buf_addr指针,内核可以通过dma_addr硬件地址访问由硬件访问的缓冲区。

然后在设备驱动程序的mmap功能中:

unsigned long physical = virt_to_phys(buf_addr);
unsigned long vsize = vma->vm_end - vma->vm_start;
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
remap_pfn_range(vma,vma->vm_start, physical >> PAGE_SHIFT , vsize, vma->vm_page_prot);

应用程序通过以下方式映射缓冲区:

buf = mmap(NULL,buf_size,PROT_READ | PROT_WRITE, dev_file, MAP_SHARED);

我没有从remap_pfn_range函数得到任何错误。应用程序还可以访问映射的内存,但它不是dmam_alloc_coherent分配的缓冲区

1 个答案:

答案 0 :(得分:0)

我发现宏dma_mmap_coherent似乎专门用于此目的。 我已经验证了对mmap函数的以下修改可确保正确运行:

unsigned long vsize = vma->vm_end - vma->vm_start;
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
remap=dma_mmap_coherent(&my_pdev->dev,vma,fdata, dma_addr, vsize);

由于pdev指针没有直接传递给mmap函数,因此它是通过全局变量my_pdev从探测函数传递的。如果驱动程序支持多个设备,则应将其存储在设备上下文中。