You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无DMA支持时,CPU从NIC读取数据的处理方式及指令序列问询

外设无法使用DMA时的数据传输方案

核心处理逻辑

当NIC这类外设无法通过DMA直接将板载缓冲区数据传输到系统内存时,只能依赖CPU作为中介完成数据搬运——本质是CPU从外设的板载缓冲区(属于内存映射IO,即MMIO区域)读取数据,再写入到系统内存的目标地址。

通用指令序列(x86/ARM通用逻辑)

不管是x86还是ARM,核心流程一致,分为以下步骤:

  1. 确认地址范围:获取外设板载缓冲区的MMIO基址(比如x86的BAR地址、ARM的外设映射基址),以及系统内存的目标缓冲区地址,同时确定待传输的数据长度。
  2. 循环逐单元搬运:
    • 从外设MMIO地址读取一个数据单元(字节/半字/字,取决于外设位宽和传输需求)
    • 将读取到的数据写入系统内存的目标地址
    • 偏移外设源地址和系统内存目标地址,重复操作直到所有数据传输完成
  3. 同步收尾:根据外设规范,可能需要写入特定MMIO寄存器,确认传输完成或清除外设的中断/就绪标记。

x86架构汇编示例

; 假设:外设MMIO地址存于EBX,系统内存目标地址存于ESI,数据长度存于ECX
mov ecx, [data_len]       ; 加载待传输的字节总数
transfer_loop:
    mov al, [ebx]         ; 从外设MMIO读取1字节到AL寄存器
    mov [esi], al         ; 将AL中的字节写入系统内存目标地址
    inc ebx               ; 外设地址偏移+1
    inc esi               ; 系统内存地址偏移+1
    dec ecx               ; 剩余传输长度-1
    jnz transfer_loop     ; 未传输完成则继续循环
; 可选:写入外设控制寄存器,标记传输完成
mov dword [periph_ctrl_reg], 0x1

ARM架构汇编示例(AArch32)

; 假设:外设MMIO地址存于r0,系统内存目标地址存于r1,数据长度存于r2
transfer_loop:
    ldrb r3, [r0]         ; 从外设MMIO读取1字节到r3寄存器
    strb r3, [r1]         ; 将r3中的字节写入系统内存目标地址
    add r0, r0, #1        ; 外设地址偏移+1
    add r1, r1, #1        ; 系统内存地址偏移+1
    subs r2, r2, #1       ; 剩余长度-1并设置标志位
    bne transfer_loop     ; 长度未清零则继续循环
; 可选:写入外设状态寄存器完成同步
mov r3, #0x1
str r3, [periph_status_reg]

操作数类型说明

这个过程仅涉及内存地址引用,不会将数据本身作为立即操作数。因为外设的板载数据是动态存储在MMIO区域的,CPU只能通过内存地址去读取这些数据,再写入到系统内存的对应地址;而立即操作数是指令中编码的固定值,无法适配动态变化的外设数据。

额外注意点

  • CPU介入的传输效率远低于DMA,因为每一次数据读写都会占用CPU周期,还会增加缓存一致性的额外开销。
  • 部分架构支持批量传输指令(比如x86的rep movsb、ARM的LDM/STM),可以减少循环的指令开销,但本质仍是CPU逐单元完成数据搬运。

内容的提问来源于stack exchange,提问作者19216811

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 22:38:17