DMA原理,步骤超细详解

DMA(Direct Memory Access,直接内存访问)原理与步骤超细详解

DMA 是计算机系统中一种高效的数据传输机制,允许外围设备(如硬盘控制器、网络卡、声卡等)直接访问系统内存,而无需 CPU 的介入,从而减少 CPU 的负担,提高系统整体性能。下面我将从 DMA 的定义、原理、组件、工作模式、详细步骤、优点缺点以及示例等方面进行超细详解。内容基于计算机体系结构的标准知识(如 Intel x86 架构中的 DMA),力求清晰、全面。


1. DMA 的定义与基本原理

  • 定义:DMA 是一种硬件机制,由 DMA 控制器(DMAC,Direct Memory Access Controller)负责管理外围设备与主内存之间的数据传输。传统 I/O 操作(如 PIO,Programmed I/O)需要 CPU 逐字节读写数据,占用 CPU 时间;DMA 则让 DMAC 接管总线控制权,实现“直接”传输。
  • 基本原理
  • 总线控制权转移:CPU 暂时释放系统总线(地址总线、数据总线、控制总线)的控制权给 DMAC。
  • 独立传输:DMAC 根据预设参数(如源地址、目标地址、传输长度)自动生成地址信号和控制信号,实现数据块的批量传输。
  • 中断通知:传输完成后,DMAC 通过中断信号通知 CPU,CPU 再处理后续事宜。
  • 效率提升:DMA 适用于大数据量传输(如磁盘读写、图形渲染),因为 CPU 可以并行处理其他任务,而非等待 I/O。
  • 为什么需要 DMA:在高速外设(如 SSD)中,PIO 会导致 CPU 利用率低下(CPU 忙等待)。DMA 解决了“CPU 瓶颈”问题,支持“零拷贝”传输(数据不经 CPU 寄存器)。

2. DMA 的主要组件

DMA 系统涉及以下硬件组件:

  • DMA 控制器 (DMAC):核心芯片(如 Intel 8237A),包含:
  • 地址寄存器:存储源/目标内存地址。
  • 字计数器:记录传输字节数。
  • 控制寄存器:设置传输模式(读/写、单向/双向)。
  • 通道:DMAC 通常支持多个通道(e.g., 4-8 个),每个通道对应一个外设。
  • 外围设备:如硬盘控制器,支持 DMA 的外设会发出 DMA 请求信号 (DREQ)。
  • 系统总线:地址总线(生成内存地址)、数据总线(传输数据)、控制总线(读/写信号)。
  • CPU:初始化 DMAC,并响应中断。
  • 中断控制器 (e.g., PIC 或 APIC):处理 DMAC 的中断请求 (IRQ)。

3. DMA 的工作模式

DMA 有多种传输模式,根据总线占用方式分类:

  • 突发模式 (Burst Mode):DMAC 一次性获得总线控制权,连续传输整个数据块。适合大数据块传输,但 CPU 完全暂停(总线被独占)。
  • 周期窃取模式 (Cycle Stealing Mode):DMAC 在 CPU 的总线周期间隙“窃取”一个周期传输一个字。CPU 几乎不暂停,适合实时系统,但传输速度稍慢。
  • 透明模式 (Transparent Mode):DMAC 只在 CPU 不使用总线时传输(如 CPU 执行内部操作时)。效率最低,但对 CPU 影响最小。
  • 其他变体
  • 单向传输:外设 → 内存 或 内存 → 外设。
  • 双向传输:如内存 ↔ 内存(内存拷贝)。
  • 链式 DMA:多个传输任务链式执行,支持散布-聚集(Scatter-Gather)模式,用于非连续内存块。

4. DMA 的详细工作步骤

DMA 的过程分为初始化阶段传输阶段结束阶段。以下是超细详解,每步包括信号交互和硬件行为(假设 Intel 8237A DMAC 和 x86 系统)。

步骤 1: CPU 初始化 DMAC(准备阶段)
  • 子步骤 1.1:CPU 通过 I/O 端口或内存映射 I/O(MMIO)向 DMAC 写入配置参数。
    • 设置通道号(e.g., 通道 0 用于 floppy disk)。
    • 写入源地址寄存器(起始内存/外设地址)。
    • 写入目标地址寄存器(结束内存/外设地址)。
    • 写入字计数寄存器(传输字节数,e.g., 4096 字节)。
    • 设置控制寄存器:传输方向(读/写)、模式(突发/周期窃取)、优先级(如果多通道)。
    • 示例:CPU 执行 OUT 指令向 DMAC 的端口 (e.g., 0x00-0x0F) 写入数据。
  • 子步骤 1.2:CPU 使能 DMAC 的通道(设置 MASK 寄存器为 0)。
  • 子步骤 1.3:CPU 通知外设准备数据(e.g., 通过外设控制器设置 DMA 模式)。
  • 信号交互:无 DMA 请求,此时总线仍由 CPU 控制。
  • 时间开销:几个 CPU 周期。
步骤 2: 外设发出 DMA 请求(请求阶段)
  • 子步骤 2.1:外设准备好数据后,向 DMAC 发送 DMA 请求信号 (DREQ,DMA Request)。
    • 示例:硬盘控制器读完一个扇区的数据,激活 DREQ 线。
  • 子步骤 2.2:DMAC 检查通道是否可用(未被掩码),如果可用,向 CPU 发送总线请求信号 (HRQ,Hold Request 或 BUSREQ)。
  • 信号交互:DREQ 高电平 → DMAC 检查 → HRQ 高电平。
  • 注意:如果多个外设同时请求,DMAC 根据优先级仲裁(固定优先级或轮询)。
步骤 3: CPU 响应并释放总线(授权阶段)
  • 子步骤 3.1:CPU 接收 HRQ 信号后,完成当前总线周期(e.g., 当前指令执行完)。
  • 子步骤 3.2:CPU 发送总线授权信号 (HLDA,Hold Acknowledge 或 BUSACK) 给 DMAC,表示释放总线控制权。
    • CPU 进入“保持”状态,总线三态(高阻态),DMAC 接管总线。
  • 子步骤 3.3:DMAC 发送 DMA 响应信号 (DACK,DMA Acknowledge) 给外设,通知开始传输。
  • 信号交互:HRQ → HLDA 高电平 → DACK 高电平。
  • 时间开销:1-2 个总线周期(取决于 CPU 状态)。
步骤 4: 数据传输(核心阶段)
  • 子步骤 4.1:DMAC 生成内存地址(从地址寄存器读取),并发送到地址总线。
  • 子步骤 4.2:DMAC 发送控制信号(读/写,如 MEMR/MEMW),外设或内存响应。
    • 读操作(外设 → 内存):外设将数据放到数据总线 → DMAC 控制内存写入。
    • 写操作(内存 → 外设):DMAC 从内存读数据 → 放到数据总线 → 外设接收。
  • 子步骤 4.3:每个字传输后,DMAC 更新地址寄存器(+1 或 -1,取决于方向)和字计数器(-1)。
  • 子步骤 4.4:重复子步骤 4.1-4.3,直到字计数器为 0。
    • 在突发模式:连续传输,不释放总线。
    • 在周期窃取模式:传输一个字后,临时释放总线给 CPU,然后再请求。
  • 信号交互:地址总线更新 → 数据总线传输 → 控制信号脉冲。
  • 时间开销:每个字 1-2 个总线周期,总传输时间取决于数据量和模式(e.g., 1MB 数据在 100MHz 总线下约 10ms)。
步骤 5: 传输完成与中断(结束阶段)
  • 子步骤 5.1:字计数器溢出(变为 0)时,DMAC 停止传输,释放总线控制权(HLDA 低电平)。
  • 子步骤 5.2:DMAC 发送终端计数信号 (TC,Terminal Count) 和中断请求 (IRQ) 给中断控制器。
  • 子步骤 5.3:中断控制器通知 CPU(INT 信号),CPU 保存现场,跳转到中断服务程序 (ISR)。
    • ISR 中:CPU 检查 DMAC 状态寄存器,确认传输成功;如果错误(如地址越界),处理异常。
  • 子步骤 5.4:CPU 恢复现场,继续执行原程序。
  • 信号交互:TC 高电平 → IRQ → INT → CPU 响应。
  • 注意:如果链式 DMA,继续下一个任务;否则,通道禁用。
步骤 6: 错误处理与恢复(可选阶段)
  • 如果传输中出错(e.g., 总线错误、奇偶校验失败),DMAC 设置状态寄存器中的错误位,并中断 CPU。
  • CPU 在 ISR 中重试传输或报告错误。

5. DMA 的优点与缺点

  • 优点
  • 减少 CPU 负载:CPU 可并发处理其他任务,提高多任务效率。
  • 高速传输:支持大数据块(e.g., 视频流、文件拷贝)。
  • 低延迟:外设直接访问内存,减少数据拷贝。
  • 缺点
  • 硬件复杂:需要专用 DMAC 芯片,增加成本。
  • 总线争用:突发模式可能导致 CPU 饥饿(长时间暂停)。
  • 安全性风险:外设直接访问内存,可能导致数据泄露(现代系统用 IOMMU 隔离)。
  • 不适合小数据:初始化开销大,对于少量字节不如 PIO 高效。

6. DMA 示例

  • 场景:硬盘读数据到内存(e.g., Windows 系统中的 DMA 磁盘 I/O)。
  1. CPU 初始化 DMAC:设置源(硬盘地址)、目标(内存缓冲区)、长度(4KB)。
  2. 硬盘控制器发出 DREQ。
  3. DMAC 获得总线,传输 4KB 数据(周期窃取模式)。
  4. 完成中断,CPU 处理数据(e.g., 文件系统更新)。
  • 现代变体:在 PCIe 系统中,使用 NVMe DMA(支持 Scatter-Gather),传输速度达 GB/s。

7. 注意事项与扩展知识

  • 与中断的区别:中断是异步通知,DMA 是数据传输机制;DMA 常结合中断使用。
  • 现代 DMA:如 uDMA(USB DMA)、GDMA(GPU DMA),支持虚拟地址(通过 IOMMU)。
  • 编程接口:在 OS 中,通过驱动(如 Linux 的 dmaengine)抽象 DMA 操作。
  • 调试技巧:使用工具如 Wireshark(网络 DMA)或 OS 监控(e.g., Windows PerfMon)查看 DMA 性能。

如果需要特定架构(如 ARM DMA)的细节、代码示例(如 C 语言模拟 DMA)或其他扩展,请进一步说明!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注