DMA 和内存映射 IO 有啥区别?

Posted

技术标签:

【中文标题】DMA 和内存映射 IO 有啥区别?【英文标题】:What is the difference between DMA and memory-mapped IO?DMA 和内存映射 IO 有什么区别? 【发布时间】:2011-04-20 13:59:21 【问题描述】:

DMA 和内存映射 IO 有什么区别?他们都和我很像。

【问题讨论】:

还相关:Linux Device Drivers, 2nd Edition: Chapter 13: mmap and DMA;不过,第一次阅读这里的答案对我有很大帮助。 【参考方案1】:

内存映射 I/O 允许 CPU 通过读写特定的内存地址来控制硬件。通常,这将用于低带宽操作,例如更改控制位。

DMA 允许硬件直接读取和写入内存 不涉及 CPU。通常,这将用于高带宽操作,例如磁盘 I/O 或摄像头视频输入。

这里有一篇论文对 MMIO 和 DMA 进行了彻底的比较。

Design Guidelines for High Performance RDMA Systems

【讨论】:

所以它们基本上是一样的,但方向相反? 不完全是。 DMA 是当两个不是 CPU 的设备使用内存总线进行通信时(一个设备通常是主内存,并且由 CPU 编排进程)。内存映射 IO 是 CPU 与不是主内存的内存总线上的设备通信。 为什么即使设备中有dma引擎也需要映射dma缓冲区? 这是不正确的。您对内存映射 I/O 的假设实际上是编程 I/O。内存映射 I/O 通常与端口映射 I/O 进行比较:CPU 访问设备中数据的方式。【参考方案2】:

直接内存访问 (DMA) 是一种无需 CPU 干预即可将数据从 I/O 传输到内存以及从内存传输到 I/O 的技术。为此,一个名为 DMA 控制器的特殊芯片用于控制所有活动和数据同步。因此,与其他数据传输技术相比,DMA 要快得多。

另一方面,虚拟内存充当主内存和辅助内存之间的缓存。数据预先从辅助存储器(硬盘)提取到主存储器中,以便在需要时数据已经在主存储器中可用。它允许我们在系统上运行比我们有足够的物理内存支持更多的应用程序。

【讨论】:

【参考方案3】:

由于其他人已经回答了这个问题,所以我将添加一点历史。

过去,在 x86 (PC) 硬件上,只有 I/O 空间和内存空间。这是两个不同的地址空间,使用不同的总线协议和不同的 CPU 指令访问,但可以通过同一个插卡槽进行通信。

大多数设备都将 I/O 空间用于控制接口和批量数据传输接口。访问数据的简单方法是执行大量 CPU 指令,一次一个字地将数据从 I/O 地址传输到内存地址(有时称为“bit-banging”)

为了自动将数据从设备移动到主机内存,ISA 总线协议不支持设备启动传输。发明了一种折衷的解决方案:DMA 控制器。这是一个由 CPU 启动并启动传输以将数据从设备的 I/O 地址移动到内存的硬件,反之亦然。因为 I/O 地址是相同的,所以 DMA 控制器执行与 CPU 完全相同的操作,但效率更高一些,并允许在后台继续运行(尽管可能不会持续太久,因为它不能与记忆交谈)。

快进到 PCI 时代,总线协议变得更加智能:任何设备都可以发起传输。因此,例如,RAID 控制器卡可以随时将它喜欢的任何数据移入或移出主机。这被称为“总线主控”模式,尽管旧的 DMA 控制器早已不复存在,但人们仍将这种模式称为“DMA”。与旧的 DMA 传输不同,通常根本没有对应的 I/O 地址,而且总线主控模式通常是设备上唯一存在的接口,根本没有 CPU“bit-banging”模式。

【讨论】:

在 Linux 内核中DMA 在超过 5000 个 C 文件中被提及,这可能是每个人仍在谈论 DMA 的原因。【参考方案4】:

内存映射 IO 意味着设备寄存器映射到机器的内存空间 - 当 CPU 读取或写入这些内存区域时,它是从设备读取或写入设备,而不是实际内存。要将数据从设备传输到实际的内存缓冲区,CPU 必须从内存映射的设备寄存器中读取数据并将其写入缓冲区(将数据传输到设备时反之亦然)。

通过 DMA 传输,设备可以直接将数据传入或传出实际内存缓冲区本身。 CPU 告诉设备缓冲区的位置,然后可以在设备直接访问内存时执行其他工作。

【讨论】:

以上是关于DMA 和内存映射 IO 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

[架构之路-47]:目标系统 - 系统软件 - Linux OS硬件设备驱动 - CPU内存管理单元MMUDMA与IO内存管理单元IOMMU

DMA32映射问题

用于 DMA 的快速映射内存缓冲区

《Linux Device Drivers》第十五章 内存映射和DMA——note

内存映射 IO - 它是如何完成的?

存储映射IO