0

在现代 X86/X86_64 平台上,由于 MMIO 机制,DMA 操作是在 MMIO 地址空间和内存地址空间之间移动数据吗?在Linux内核中,我看到有一个dma_addr_t定义。这种类型是否用于 MMIO 地址?

4

1 回答 1

0

一般来说,DMA 操作只是指 CPU 以外的设备访问内存。在 x86 上,没有单独的 MMIO 和 RAM 地址空间——一切都是统一的。典型 DMA 操作的一些示例:

  • 网卡可能会从网络接收数据包并使用 DMA 将数据包内容写入系统的 RAM。
  • SATA 控制器可能会收到写入命令并使用 DMA 读取数据以从系统 RAM 发送到硬盘。
  • 显卡可能会使用 DMA 将纹理数据从系统 RAM 读取到自己的视频内存中。系统 CPU 通过 PCI BAR (MMIO) 可以看到显存,但这在这里并不重要。

dma_addr_t类型在 Linux 中拥有一个“总线地址”。例如,PCI 设备(如 NIC/SATA 控制器/GPU)看到映射到的给定内存部分的地址可能与 CPU 使用的地址不同。所以Linux有“DMA映射”的抽象来处理这种差异。

在上面的第一个示例中,网络堆栈将在 RAM 中分配一个缓冲区,然后将其传递给dma_map函数以获取它传递给 NIC 的总线地址。NIC 将使用该地址将数据包写入内存。

在较旧的 x86 系统中,CPU 使用的物理地址和外部设备使用的总线地址之间没有任何区别,而且dma_map功能几乎都是 NOP。但是,对于 VT-d 等现代技术,PCI 设备使用的总线地址可能与 CPU 的物理地址完全不同,因此进行 DMA 映射并将 adma_addr_t用于外部 DMA 使用的所有地址非常重要设备。

于 2012-02-03T19:38:58.120 回答