3、DMA基础原理:DMA控制器工作原理、描述符环机制、Scatter-Gather列表
DMA(Direct Memory Access,直接存储器访问)是PCIe RC模式驱动中实现高性能数据传输的核心硬件机制。它允许外设(如FPGA、NVMe控制器、网络适配器)绕过CPU,直接与系统内存交换数据,从而将CPU从繁重的数据搬运工作中解放出来,专注于协议处理与上层应用逻辑。本章将深入剖析DMA控制器的内部工作原理、描述符环(Descriptor Ring)的调度机制以及Scatter-Gather(SG)列表如何解决物理内存不连续的问题。
3.1 DMA控制器工作原理
DMA控制器本质上是一个专用的状态机或微引擎,负责管理总线上的数据传输事务。在PCIe RC模式下,RC侧的DMA控制器通常集成在RC硬件内部或由FPGA逻辑实现,其核心工作流程如下:
- 配置阶段:CPU通过MMIO(Memory-Mapped I/O)寄存器配置DMA控制器的源地址、目的地址、传输长度、传输方向(内存→设备/设备→内存)以及触发方式。
- 启动阶段:CPU写入控制寄存器的“启动”位,DMA控制器开始独立执行传输。
- 传输阶段:DMA控制器作为PCIe总线上的Master,发起Memory Read/Write TLP(事务层数据包),直接与系统内存交互。每次传输通常以Max Payload Size(MPS)为单位进行拆分。
- 完成阶段:传输完成后,DMA控制器通过中断或写状态寄存器的方式通知CPU。
3.2 描述符环机制
描述符环(Descriptor Ring)是DMA传输的“任务队列”,它位于系统内存中,由一组固定大小的描述符(Descriptor)组成环形缓冲区。CPU作为生产者向环中填充描述符,DMA控制器作为消费者从环中取出描述符并执行传输。这种机制实现了CPU与DMA控制器的解耦,支持批量提交和流水线处理。
3.2.1 描述符结构
每个描述符通常包含以下关键字段,其具体布局由硬件IP定义:
| 字段 | 偏移(字节) | 描述 |
|---|---|---|
| 源地址 | 0x00 | 数据源物理地址(设备地址或内存地址) |
| 目的地址 | 0x08 | 数据目的物理地址 |
| 传输长度 | 0x10 | 本次传输的字节数(通常为4字节对齐) |
| 控制标志 | 0x14 | 包含中断使能、链式标志、方向位等 |
| 下一个描述符指针 | 0x18 | 链式模式下指向下一个描述符的地址 |
| 状态/完成标志 | 0x20 | 由DMA控制器写入,表示传输完成或错误 |
3.2.2 环的运作流程
- 初始化:驱动在系统内存中分配一段连续物理内存作为描述符环,并将环的基地址和大小写入DMA控制器的寄存器。
- 提交描述符:CPU将待传输任务的描述符写入环的当前“生产者索引”位置,然后更新生产者索引寄存器。
- 硬件消费:DMA控制器轮询或通过门铃(Doorbell)机制感知到新描述符,从“消费者索引”位置读取描述符,解析地址和长度后发起PCIe传输。
- 完成通知:传输完成后,DMA控制器更新描述符中的状态字段,并递增消费者索引。如果描述符设置了中断标志,则触发中断通知CPU。
- 回收描述符:CPU在中断处理或轮询中检查消费者索引,回收已完成的描述符,重新填充新任务。
3.3 Scatter-Gather列表
Scatter-Gather(SG)是DMA传输中解决物理内存碎片问题的关键技术。在操作系统中,通过malloc或kmalloc分配的内存通常是虚拟地址连续的,但其对应的物理页面可能分散在内存的不同位置。SG列表允许DMA控制器在一次传输中访问多个不连续的物理内存块,从而避免昂贵的物理内存拷贝或大块连续内存分配。
3.3.1 SG列表结构
SG列表本质上是一个描述符数组,每个SG条目(SG Entry)描述一个物理连续的内存块:
| 字段 | 说明 |
|---|---|
| 物理地址 | 当前内存块的起始物理地址(必须按DMA对齐要求对齐) |
| 长度 | 当前内存块的字节数 |
| 标记 | 可选:指示是否为最后一个条目、是否需要中断等 |
3.3.2 工作流程
- 构建SG列表:驱动遍历待传输数据的物理页面,将每个页面的物理地址和有效长度填入SG条目。
- 提交SG列表:将SG列表的首地址和条目数量写入DMA控制器的描述符中(或直接使用SG列表作为描述符环的扩展)。
- 硬件遍历:DMA控制器依次读取每个SG条目,对每个条目发起独立的PCIe Memory Read/Write TLP序列。
- 自动拼接:对于设备而言,SG传输表现为一个连续的字节流;硬件在内部自动处理地址跳转,无需软件干预。
3.4 三种机制的协同关系
在实际的PCIe RC驱动中,DMA控制器、描述符环和SG列表三者协同工作,构成完整的DMA传输链路:
- DMA控制器是执行单元,负责解析描述符并驱动PCIe总线事务。
- 描述符环是任务调度队列,实现CPU与DMA控制器的异步解耦。
- SG列表是数据描述方式,解决物理内存碎片问题,提高内存利用率。
典型的传输路径为:CPU构建SG列表 → 将SG列表地址填入描述符 → 描述符入环 → 门铃通知DMA → DMA从环中取出描述符 → DMA遍历SG列表 → 发起PCIe传输 → 更新完成状态 → 中断通知CPU。