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(基地址寄存器)访问设备。
2.1.2 配置空间与BAR
每个PCIe设备都有一个4KB配置空间,前64字节是标准头部,包含Vendor ID、Device ID、Class Code等。驱动通过配置空间找到设备,并通过基地址寄存器(BAR)获取设备在内存或I/O空间的映射地址。
| 配置空间字段 | 偏移 | 说明 |
|---|---|---|
| Vendor ID | 0x00 | 厂商编号(如Intel 0x8086) |
| Device ID | 0x02 | 设备型号 |
| Class Code | 0x09 | 设备类型(网卡为0x02) |
| BAR0 ~ BAR5 | 0x10 ~ 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传输。
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写延迟 | 描述符环空满、中断频率 |
2.4 本章小结
- PCIe总线提供点对点高速连接,网卡通过配置空间和BAR暴露控制接口。
- DMA控制器(总线主控)让网卡直接访问内存,CPU仅做控制面工作。
- TX方向是内存到设备的DMA读,RX方向是设备到内存的DMA写。
- 驱动通过描述符环与网卡硬件交换缓冲区地址和状态,这是下一章环形缓冲区的核心数据结构。
下一站预告: 第3章将深入描述符环的软件设计——如何初始化、如何避免竞态、如何优雅地处理环满和环空。准备好进入真正的驱动编码阶段!