3. DMA控制器硬件特性:总线主控、描述符链、循环模式、散聚模式

DMA控制器的硬件能力直接决定了数据传输的带宽上限、延迟特性以及CPU的卸载效率。本章深入剖析DMA控制器的四大核心硬件特性:总线主控、描述符链、循环模式和散聚模式。理解这些特性是进行DMA性能调优和驱动开发的基础。

核心观点: 现代高性能DMA控制器本质上是一个专用的、可编程的数据移动引擎。它通过总线主控权直接接管系统总线,利用描述符链实现复杂传输序列,并通过循环与散聚模式最大化吞吐量并最小化CPU干预。

3.1 总线主控 (Bus Mastering)

总线主控是DMA控制器最根本的特性。它允许DMA控制器在不需要CPU介入的情况下,直接向系统总线发起读写事务,从而成为总线上的“主设备”。

  • 传统DMA (Slave DMA / Fly-By DMA): 早期的ISA总线DMA控制器作为“从设备”工作,CPU必须参与每个传输周期的地址和命令生成,效率低下。
  • 总线主控DMA (First-Party DMA / Bus Mastering): 现代PCIe、AHB、AXI总线上的DMA控制器作为“主设备”工作。它内部包含总线接口单元,可以自主驱动地址、数据和控制信号。
性能影响: 总线主控模式消除了CPU在每次数据传输中的参与,将CPU从数据搬运工转变为任务调度者。这是实现高带宽(如PCIe Gen4/Gen5的数十GB/s)和低延迟(亚微秒级)的关键前提。
总线主控模式与非总线主控模式对比 非总线主控 (Slave DMA) CPU DMA控制器 内存/外设 CPU控制每个周期 • 高CPU占用率 • 低带宽 (受限于CPU频率) • 适用于低速设备 (如ISA) 总线主控 (Bus Mastering) CPU DMA控制器 内存/外设 仅初始化 自主传输 • 极低CPU占用率 • 高带宽 (总线速率) • 适用于高速设备 (PCIe)

3.2 描述符链 (Descriptor Chain / Linked List)

描述符链是DMA控制器实现复杂、多段、非连续传输的核心机制。它将多个传输任务(描述符)通过指针链接成一个链表,DMA控制器可以自动遍历并执行整个链,无需CPU逐段干预。

描述符结构

一个典型的DMA描述符包含以下关键字段:

字段 描述 典型位宽
源地址 数据源的内存地址或外设地址 32/64位
目的地址 数据目的地的内存地址或外设地址 32/64位
传输长度 本次传输的字节数 16/32位
控制标志 中断使能、传输方向、地址递增模式等 16/32位
下一个描述符指针 指向链中下一个描述符的物理地址 32/64位
DMA描述符链执行流程 描述符 1 Src: 0x1000 Dst: 0x5000 Len: 1024 Next: &Desc2 描述符 2 Src: 0x2000 Dst: 0x6000 Len: 2048 Next: &Desc3 描述符 3 Src: 0x3000 Dst: 0x7000 Len: 512 Next: NULL 描述符链执行流程 1. CPU将描述符1的地址写入DMA控制器的“链首地址”寄存器。 2. DMA控制器自动读取描述符1,执行传输,然后通过“Next”指针跳转到描述符2。
关键注意事项: 描述符必须位于DMA可访问的内存区域(通常是DMA ZONE或一致性内存)。描述符链的最后一个描述符的“下一个指针”必须设置为NULL或特定的结束标志,否则DMA控制器会陷入无限循环或访问非法地址。

3.3 循环模式 (Circular Mode / Auto-Request Mode)

循环模式是描述符链的一种特殊形式,其中最后一个描述符的“下一个指针”指向链中的第一个描述符,形成一个环形缓冲区。这种模式特别适用于连续的数据流场景,如音频播放、视频采集或网络数据包收发。

  • 工作原理: DMA控制器在完成最后一个描述符的传输后,自动回绕到第一个描述符,开始新一轮传输。整个过程无需CPU重新配置。
  • 典型应用:
    • 音频I2S接口: 持续将音频数据从内存搬运到DAC,或从ADC搬运到内存。
    • 网络MAC: 使用多个描述符构成环形队列,用于接收和发送数据包。
    • 摄像头接口: 连续采集图像帧数据。
DMA循环模式环形缓冲区 Desc 0 Buf: 0x1000 Desc 1 Buf: 0x2000 Desc 2 Buf: 0x3000 Desc 3 Buf: 0x4000 循环模式特点 • Desc 3 的 Next 指针指向 Desc 0,形成闭环。 • 适用于连续数据流,CPU只需在中断中处理“已完成”的描述符。

3.4 散聚模式 (Scatter-Gather Mode)

散聚模式(SG模式)是描述符链的高级应用,它允许DMA控制器在一次操作中处理物理上不连续的内存区域。这对于现代操作系统中的虚拟内存和分页机制至关重要。

核心概念

  • 分散 (Scatter): 将从外设或一个连续源接收的数据,分散写入到多个不连续的内存缓冲区中。
  • 聚集 (Gather): 从多个不连续的内存缓冲区中读取数据,聚合成一个连续的数据流发送给外设。
性能优势: 散聚模式消除了CPU进行内存拷贝(如 memcpy)的需要。例如,网络协议栈中的数据可能分散在多个sk_buff片段中,SG-DMA可以直接将这些片段发送到网卡,无需先拷贝到一个连续缓冲区。
DMA散聚模式工作流程 分散 (Scatter) - 写入 Buf 0 Buf 1 Buf 2 来自外设的连续数据流 聚集 (Gather) - 读取 发送到外设的连续数据流 Buf 0 Buf 1 Buf 2 散聚模式与描述符链的关系 • 每个描述符可以指向一个物理上不连续的缓冲区。 • 描述符链中的多个描述符共同描述了一个完整的、逻辑上连续的传输任务。 • 对于“分散”操作:DMA从源读取连续数据,然后根据每个描述符的地址和长度写入不同缓冲区。 • 对于“聚集”操作:DMA从多个缓冲区读取数据,然后连续写入到目的地址。

3.5 特性对比与选择

特性 适用场景 CPU卸载程度 带宽利用率 实现复杂度
单次传输 简单、低频的数据移动 低 低 低
描述符链 复杂、多段、非连续传输 高 高 中
循环模式 连续数据流(音频、视频、网络) 极高 极高 中
散聚模式 虚拟内存、零拷贝网络、文件系统 极高 极高 高
实践建议: 在Linux内核驱动开发中,struct dma_async_tx_descriptor 是描述符的抽象。使用 dmaengine_prep_slave_sg() 准备散聚传输,使用 dmaengine_prep_dma_cyclic() 准备循环传输。理解这些硬件特性是正确配置DMA引擎和实现高性能数据传输的前提。