【问题标题】:linux driver Data transfer with DMA from userspacelinux驱动程序从用户空间使用DMA进行数据传输
【发布时间】:2014-10-23 15:29:20
【问题描述】:

您好,我正在尝试实现一个 FPGA 加速器,通过 AXI 总线与 ARM 处理器集成。 FPGA 加速器包括一个 DMA,旨在移动输入数据(从内存)和输出数据(到内存)。一切都作为裸机应用程序运行,但我在 Linux 下遇到问题。

这个想法是用户空间进程必须提供输入数据并且必须读取输出数据。为了解决这个问题,我正在编写一个设备驱动程序,但我被困在从虚拟地址到物理地址的地址转换中。当我为 DMA 提供输入和输出基址时,我只能提供对我的目的无用的虚拟地址,因为我不知道如何将其转换为物理地址。结果,我从错误的内存位置读取和写入数据。我还认为与裸机的另一个区别是,在 linux 中数据可以碎片化,而在裸机中它们位于连续的内存区域中。

您对解决这些问题有什么建议或参考吗? 谢谢

【问题讨论】:

标签: linux memory arm driver dma


【解决方案1】:

首先,警告:不要尝试使用virt_to_phys,这是解决此问题的常见建议。 source code itself 表示此函数(实际上是一个宏,但这不是重点)不应用于 DMA 或设备驱动程序。

您应该使用来自dma_alloc 系列的函数。最有可能的候选人是void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag),它会为你做一些事情:

  • 分配size 字节的固定内存(固定可防止操作系统将内存换出到磁盘)
  • dma_handle 分配一个句柄,该句柄可以转换为无符号整数并作为内存的物理地址提供给您的硬件
  • 返回可用于从驱动程序中访问内存的虚拟地址
  • 确保内存是连续的

这里有一些其他资源可供查看,所有这些资源都托管在 kernel.org 上:

Dynamic DMA Mapping Using the Generic Device
DMA Mapping Guide
Guide to the virt_to_phys and phys_to_virt functions(请记住,在这种情况下不应使用它们 - 这仅供参考。)

【讨论】:

    猜你喜欢
    • 2019-11-19
    • 1970-01-01
    • 2021-12-19
    • 2011-07-29
    • 1970-01-01
    • 1970-01-01
    • 2014-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多