FPGA上的DMA无法访问通过GFP_KERNEL标志分配的内核内存

时间:2018-10-12 19:07:58

标签: linux-kernel fpga mmap dma pci-e

我首先要简要介绍我正在研究的方案。

我要完成的工作是从用户空间应用程序加载图像数据,并通过PCIe将其传输到FPGA板内部的自定义加速引擎。

我的主机的规格是:

  • 具有16G ram的Intel Xeon处理器。
  • 内核版本为4.18的64位Debian Linux。

FPGA是Virtex 7 KC705开发板。 FPGA使用PCIe控制器(桥接器)在PCIe基础架构和FPGA的AXI接口之间进行通信。 此外,FPGA配备了DMA引擎,该引擎应该通过PCIe控制器从内核内存中读取数据,并将其转发给加速器。

由于在以后的实现中,我想对多个内核进行最大256M的分配,因此我已将内核配置为支持CMA和DMA连续分配器。 根据dmesg的说法,我可以在启动CMA区域时验证我的系统是否保留。

关于加速过程:

  1. 驱动程序最初通过将dma_alloc_coherent()与GFP_KERNEL标志一起使用来分配4M内核内存。此分配在CMA的范围内。
  2. 然后从用户空间应用程序中,我使用READ_PROT / WRITE_PROT和MAP_SHARED / MAP_LOCKED标志调用mmap,以映射先前分配的CMA内存并在其中加载图像数据。
  3. 一旦加载了图像数据,我就转发CMA分配的内存的dma_addr_t物理地址,然后启动DMA将数据传输到加速器。加速完成后,DMA应该会将处理后的数据写回到同一CMA内核分配的内存中。
  4. 完成后,用户空间应用程序将从CMA存储器读取已处理的数据,并将其保存到.bmp文件。当我检查“已处理”图像时,它与原始图像相同。我想处理过的数据永远不会写入CMA内存。

是否存在某种使用GFP_KERNEL标志时不允许写入CMA内存的内存保护?

一个有趣的事实是,当我使用dma_alloc_coherent分配内核内存但使用GFP_ATOMIC或GFP_DMA分配时,已处理的数据已正确写入内核内存,但不幸的是,分配的内存不属于CMA区域。

我的实现中有什么问题? 请让我知道是否需要更多信息!

1 个答案:

答案 0 :(得分:0)

为了使用mmap(),我采用了debugfs文件操作方法。 最初,我按如下所示打开debugfs文件:

shared_image_data_file = open("/sys/kernel/debug/shared_image_data_mmap_value", O_RDWR);

shared_image_data_mmap_value 是在内核驱动程序中创建的我的debugfs文件,而 shared_image_data_file 只是一个整数。

然后,我从用户空间调用mmap(),如下所示:

    kernel_address = (unsigned int *)mmap(0, (4 * MBYTE), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED, shared_image_data_file, 0);

当我在用户空间中调用mmap()函数时,我的debugfs文件的mmap文件操作在内核驱动程序中执行以下函数:

dma_mmap_coherent(&dev->dev, vma, shared_image_data_virtual_address, shared_image_data_physical_address, length);

shared_image_data_virtual_address 是uint_64_t类型的指针,而 shared_image_data_physical_address 是dma_addr_t类型的指针,当我使用以下代码在内核空间中分配内存时,它们是在前面创建的:

shared_image_data_virtual_address = dma_alloc_coherent(&dev->dev, 4 * MBYTE, &shared_image_data_physical_address, GFP_KERNEL);

我传递给FPGA的DMA的地址是 shared_image_data_physical_address

我希望以上内容对您有所帮助。

谢谢!