2. 计算机总线与DMA基础

在动手编写网卡驱动之前,必须理解数据如何在CPU、内存和网卡之间高效流动。本章聚焦两大基石:PCIe总线(现代外设连接标准)和DMA控制器(零拷贝数据传输引擎)。掌握这些概念,才能理解为什么环形缓冲区是网卡驱动的核心设计模式。

2.1 PCIe总线简介

PCI Express(PCIe)是当前主流的高速串行总线标准,取代了传统的并行PCI/PCI-X总线。它采用点对点串行连接,每个设备拥有独立的通道(Lane),不再共享带宽。

2.1.1 拓扑结构与分层协议

PCIe系统由根复合体(Root Complex, RC)、交换器(Switch)和端点(Endpoint)组成。RC连接CPU和内存,Switch扩展端口,Endpoint即网卡、GPU等外设。

关键特性: PCIe采用分层协议栈——事务层(TLP)、数据链路层(DLLP)和物理层。驱动开发者主要与事务层交互,通过配置空间和BAR(基地址寄存器)访问设备。
PCIe 系统拓扑结构 CPU Root Complex (RC) 系统内存 PCIe Switch 网卡 (NIC) GPU NVMe SSD 点对点串行连接 每个设备独享通道 不共享总线带宽

2.1.2 配置空间与BAR

每个PCIe设备都有一个4KB配置空间,前64字节是标准头部,包含Vendor ID、Device ID、Class Code等。驱动通过配置空间找到设备,并通过基地址寄存器(BAR)获取设备在内存或I/O空间的映射地址。

配置空间字段偏移说明
Vendor ID0x00厂商编号(如Intel 0x8086)
Device ID0x02设备型号
Class Code0x09设备类型(网卡为0x02)
BAR0 ~ BAR50x10 ~ 0x24基地址寄存器,映射MMIO或I/O端口
驱动开发提示: 网卡通常使用BAR0映射MMIO(内存映射I/O)空间。驱动通过ioremap()将物理地址转为内核虚拟地址,然后直接读写寄存器控制网卡。

2.2 DMA控制器工作原理

直接内存访问(DMA)允许外设绕过CPU直接读写系统内存。对于网卡而言,DMA是性能的命脉——收发包时数据直接在网卡和内存之间传输,CPU仅处理控制面。

2.2.1 传统PIO vs DMA

对比维度PIO(程序控制I/O)DMA(直接内存访问)
数据传输者CPU逐字节搬运DMA控制器/总线主控
CPU占用高(100%占用)低(仅初始化+中断)
吞吐量低(受限于CPU频率)高(接近总线带宽)
适用场景少量控制数据批量数据(网络包、磁盘块)

2.2.2 总线主控DMA(Bus Mastering)

现代网卡都支持总线主控DMA:网卡自身作为PCIe总线主控,直接发起内存读写事务。驱动只需在内存中准备好描述符环(Descriptor Ring),网卡硬件自动从环中取描述符执行DMA传输。

DMA 传输流程(设备到内存) 网卡 (NIC) 收到网络数据包 DMA 引擎 读取描述符环 系统内存 数据缓冲区 描述符环 (Ring) CPU 仅参与初始化 设置描述符 → 启动DMA → 等待中断 ① ② ③

2.3 DMA传输类型

网卡驱动涉及两种基本DMA传输方向,理解它们的差异是正确设计环形缓冲区的关键。

2.3.1 内存到设备(Memory to Device)

用于发送(TX)路径:CPU将待发送的数据包放入内存缓冲区,网卡通过DMA读取这些数据并发送到网络。

  • 驱动职责: 分配DMA缓冲区,将数据拷贝到缓冲区,填写发送描述符(地址+长度),通知网卡。
  • 硬件行为: 网卡从描述符环取出描述符,发起DMA读事务,将数据从内存拉到网卡FIFO,然后编码发送。
  • 同步点: 发送完成后网卡产生TX完成中断,驱动回收描述符和缓冲区。

2.3.2 设备到内存(Device to Memory)

用于接收(RX)路径:网卡从网络收到数据包,通过DMA将数据直接写入内存中的预分配缓冲区。

  • 驱动职责: 预先分配一组接收缓冲区,将地址填入接收描述符环,通知网卡可以接收。
  • 硬件行为: 网卡收到包后,从描述符环取出空闲描述符,发起DMA写事务,将数据写入内存缓冲区。
  • 同步点: 写入完成后网卡更新描述符状态(或写回新数据),产生RX中断,驱动处理数据包。
常见陷阱: DMA缓冲区必须物理连续(或使用SG列表),且不能位于CPU缓存中。驱动必须使用dma_alloc_coherent()或dma_map_single()确保一致性。忘记DMA同步会导致数据损坏!

2.3.3 传输类型对比

属性TX(内存→设备)RX(设备→内存)
DMA方向读(设备读取内存)写(设备写入内存)
缓冲区所有权驱动→网卡→驱动驱动→网卡→驱动
中断触发时机发送完成接收完成
典型描述符字段数据地址、长度、校验和卸载标志数据地址、长度、状态标志
性能瓶颈描述符环空满、PCIe写延迟描述符环空满、中断频率
双向 DMA 传输:TX 与 RX 路径 系统内存 TX 缓冲区 (待发送数据) RX 缓冲区 (已接收数据) 网卡 (NIC) TX FIFO (待发送) RX FIFO (已接收) TX: 内存 → 设备 (DMA读) RX: 设备 → 内存 (DMA写) 环形缓冲区同时管理 TX 和 RX 描述符 驱动与网卡通过描述符环协同工作

2.4 本章小结

  • PCIe总线提供点对点高速连接,网卡通过配置空间和BAR暴露控制接口。
  • DMA控制器(总线主控)让网卡直接访问内存,CPU仅做控制面工作。
  • TX方向是内存到设备的DMA读,RX方向是设备到内存的DMA写。
  • 驱动通过描述符环与网卡硬件交换缓冲区地址和状态,这是下一章环形缓冲区的核心数据结构。
下一站预告: 第3章将深入描述符环的软件设计——如何初始化、如何避免竞态、如何优雅地处理环满和环空。准备好进入真正的驱动编码阶段!