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

标签 linux arm mapping dma

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

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

映射正确完成,并且我已经验证,硬件通过 dma_addr 硬件地址访问的缓冲区对于内核通过 buf_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 分配的缓冲区

最佳答案

我找到了宏 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 从探测函数传递过来的。如果驱动程序支持多个设备,则应将其存储在设备上下文中。

关于linux - 通过 remap_pfn_range 将 dmam_alloc_coherent 分配的内存映射到用户空间会给出指向错误内存区域的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53995151/

相关文章:

python - 如何在新文件名中复制带有日期的图像?

linux - 使用 linux I2C 驱动程序

node.js - 为 ARM6 (Raspberry Pi) 交叉编译 Node.js

打包结构中的变量可以原子读取吗?

gcc - 如何使用单个 GCC(交叉)编译器(交叉)编译为 ARM 硬浮点和软浮点 (softfp)?

c# - 无法从 'method group' 转换为 'System.EventHandler'

创建宏时 VIM 映射无法正常工作

python - 非阻塞键盘输入

java - MapStruct 字符串到列表的映射

linux - 如何在 Ubuntu 上打开一些端口?