DMA 是一种硬件机制,它允许外围组件将其 I/O 数据直接传输到主内存或从主内存传输数据,而无需系统处理器参与传输。使用这种机制可以极大地增加进出设备的吞吐量,因为大量的计算开销被消除了。
要利用其硬件的 DMA 功能,设备驱动程序需要能够正确设置 DMA 传输并与硬件同步。不幸的是,由于其硬件性质,DMA 非常依赖于系统。每种体系结构都有自己的技术来管理 DMA 传输,并且每种体系结构的编程接口都不同。内核也不能提供统一的接口,因为驱动程序不能从底层硬件机制中抽象出太多。然而,在最近的内核中,已经朝着这个方向采取了一些步骤。
可以通过两种方式触发数据传输:软件请求数据(通过read等函数)或硬件将数据异步推送到系统。
对于第一种情况,所涉及的步骤可以概括如下:
第二种情况发生在异步使用 DMA 时。例如,即使没有人在读取数据,数据采集设备也会继续推送数据,就会发生这种情况。在这种情况下,驱动程序应该维护一个缓冲区,以便后续的读取调用将所有累积的数据返回到用户空间。这种转移涉及的步骤略有不同:
异步方法的一种变体经常出现在网卡上。这些卡通常希望在与处理器共享的内存中建立一个循环缓冲区(通常称为DMA 环形缓冲区);每个传入的数据包都放在环中的下一个可用缓冲区中,并发出中断信号。然后驱动程序将网络数据包传递给内核的其余部分,并在环中放置一个新的 DMA 缓冲区。
所有这些情况下的处理步骤都强调有效的 DMA 处理依赖于中断报告。虽然可以使用轮询驱动程序实现 DMA,但这没有意义,因为轮询驱动程序会浪费 DMA 提供的性能优势,而不是更简单的处理器驱动 I/O。
这里介绍的另一个相关项目是 DMA 缓冲区。要利用直接内存访问,设备驱动程序必须能够分配一个或多个适合 DMA 的特殊缓冲区。请注意,许多驱动程序在初始化时分配它们的缓冲区并使用它们直到关闭 - 因此,前面列表中的分配一词意味着“获取先前分配的缓冲区”。