【问题标题】:Convert DMA mapping to virtual address将 DMA 映射转换为虚拟地址
【发布时间】:2013-02-19 00:03:31
【问题描述】:

我有一些不寻常的情况,我正在为以太网设备开发一个模拟模块。理想情况下,模拟层在寄存器集方面与真实硬件相同。我遇到的问题是硬件中的 DMA 寄存器加载了数据的 DMA 映射(物理)地址。我需要使用这些物理地址将数据从源设备上的 Tx 缓冲区复制到目标设备上的 Rx 缓冲区。要在模块代码中做到这一点,我需要指向虚拟内存的指针。我查看了 phys_to_virt() 并没有理解手册页中的这条评论:

This function does not handle bus mappings for DMA transfers.

这是否意味着无法使用 phys_to_virt() 将通过 dma_map_single 检索到的物理地址转换回虚拟地址?还有其他方法可以完成这种转换吗?

【问题讨论】:

    标签: linux-kernel linux-device-driver


    【解决方案1】:

    没有任何通用方法可以将 DMA 地址映射到虚拟地址。 dma_map_single() 函数可能正在对 IOMMU(例如 Intel x86 系统上的 VT-d)进行编程,这会导致 DMA 地址与原始物理或虚拟地址完全无关。然而this presentation 和链接的幻灯片提供了一种将模拟硬件模型与真实驱动程序挂钩的方法(基本上,使用虚拟化)。

    【讨论】:

    • 感谢幻灯片的链接。我去看看。
    【解决方案2】:

    我对这个问题不太清楚,但如果你使用"phys_to_virt()" 可能是总线上可用的地址不能被这个函数转换为虚拟的原因。我不确定只是尝试bus_to_virt(bus_addr);function

    【讨论】:

    • 感谢您尝试回答。原来我最初的问题并没有多大意义。由于我正在尝试模拟硬件,因此下面没有真正的总线。如果没有某种底层总线供内核映射,我一开始就无法获得 DMA 地址。
    【解决方案3】:

    试试dma_virt = virt_to_phys(bus_to_virt(dma_handle))

    它对我有用。它提供了与dma_coherent_alloc() 映射的相同虚拟地址。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-10
      • 1970-01-01
      • 2012-02-18
      • 2018-12-04
      • 1970-01-01
      相关资源
      最近更新 更多