PCIe BAR空间映射与DMA传输驱动开发实践 - 第1节
1.1 PCIe 总线架构概述
PCI Express(PCIe)是一种高速串行计算机扩展总线标准,旨在替代传统的并行 PCI 和 PCI-X 总线。其核心设计理念是采用点对点串行连接,每个设备都拥有专用的通道(Lane),而非共享并行总线。这种架构从根本上消除了并行总线中因多个设备共享同一总线而产生的仲裁延迟和信号同步问题。
PCIe 总线架构的关键特性包括:
- 点对点连接:每个 PCIe 设备直接与根复合体(Root Complex)或交换器(Switch)相连,无需共享带宽。
- 串行差分信号:使用高速差分信号对(Tx+/Tx-, Rx+/Rx-)进行数据传输,抗干扰能力强,频率高。
- 可扩展带宽:通过组合多个通道(x1, x4, x8, x16)实现灵活的带宽配置。
- 热插拔支持:支持在系统运行时添加或移除设备(需硬件和驱动配合)。
- 高级错误报告:提供从物理层到事务层的完整错误检测与报告机制。
1.2 PCIe 拓扑结构
PCIe 系统采用树形拓扑结构,主要由以下组件构成:
- 根复合体(Root Complex, RC):连接 CPU 和内存子系统到 PCIe 交换结构的桥梁。它通常集成在 CPU 或芯片组中,负责生成事务层数据包(TLP)并处理来自 PCIe 设备的请求。
- 交换器(Switch):扩展 PCIe 端口的逻辑设备,由上游端口(Upstream Port)和多个下游端口(Downstream Port)组成。它负责在多个端点之间路由数据包,实现扇出(Fan-out)功能。
- 端点(Endpoint, EP):位于 PCIe 树末端的设备,如 GPU、NVMe SSD、网卡等。端点可以是传统 PCI 设备(通过桥接器连接)或原生 PCIe 设备。
- 桥接器(Bridge):用于连接不同总线标准(如 PCIe 到 PCI)或扩展总线层级。
下表总结了 PCIe 拓扑中各组件的角色与功能:
| 组件 | 角色 | 关键功能 |
|---|---|---|
| 根复合体 (RC) | CPU/内存与 PCIe 域的接口 | 生成配置请求、内存映射 I/O、中断路由 |
| 交换器 (Switch) | 扩展端口数量,路由数据包 | 基于 BDF 地址的 TLP 转发、流量控制 |
| 端点 (EP) | 功能实现者(存储、显示、网络) | 发起 DMA、响应 MMIO 读写、生成 MSI/MSI-X 中断 |
| 桥接器 (Bridge) | 总线协议转换 | 配置空间映射、地址转换、总线隔离 |
下面是一个典型的 PCIe 系统拓扑结构示意图:
1.3 PCIe 分层协议
PCIe 协议采用分层架构,从下到上依次为:物理层(Physical Layer)、数据链路层(Data Link Layer)和事务层(Transaction Layer)。这种分层设计使得各层职责清晰,便于实现和维护。
1.3.1 事务层(Transaction Layer)
事务层是 PCIe 协议栈的最上层,直接与软件(驱动)交互。它负责:
- TLP 封装与解析:将软件发起的读写请求封装成事务层数据包(TLP),或从接收的 TLP 中提取数据。
- 地址空间管理:支持四种地址空间——内存空间、I/O 空间、配置空间和消息空间。
- 事务排序:遵循 PCIe 排序规则,确保事务的正确执行顺序。
- 流量分类(TC)与虚拟通道(VC):支持服务质量(QoS)管理。
事务层定义了多种 TLP 类型,包括:Memory Read/Write、I/O Read/Write、Configuration Read/Write、Message 以及 Completion(完成包)。
1.3.2 数据链路层(Data Link Layer)
数据链路层位于事务层和物理层之间,主要职责是保证 TLP 在相邻两个 PCIe 设备之间可靠传输。其核心功能包括:
- 数据完整性校验:为每个 TLP 添加 CRC(循环冗余校验)字段,接收端验证数据完整性。
- ACK/NAK 重传机制:接收端发送确认(ACK)或否定确认(NAK)数据链路层数据包(DLLP),发送端根据反馈决定是否重传。
- 流量控制:基于信用(Credit)机制管理接收缓冲区,防止发送端过载。
- 链路管理与错误报告:处理链路状态变化和错误条件。
数据链路层在 TLP 前后添加了序列号(Sequence Number)和 LCRC(链路 CRC),形成数据链路层数据包(DLLP)。
1.3.3 物理层(Physical Layer)
物理层是 PCIe 协议栈的最底层,负责在物理介质上传输比特流。它分为两个子层:
- 逻辑子层:负责字节拆包/打包、加扰/解扰、8b/10b 或 128b/130b 编码(取决于 PCIe 版本)、链路训练与初始化。
- 电气子层:负责差分信号的发送与接收、阻抗匹配、时钟恢复等模拟电路功能。
物理层还负责链路训练过程,包括位锁定、符号锁定、通道对齐和链路宽度协商。
下表总结了 PCIe 各协议层的核心职责与数据单元:
| 协议层 | 核心职责 | 数据单元 | 驱动关注点 |
|---|---|---|---|
| 事务层 | TLP 封装、地址空间映射、事务排序 | TLP (Transaction Layer Packet) | BAR 访问、DMA 描述符、中断消息 |
| 数据链路层 | 可靠传输、CRC 校验、ACK/NAK 重传 | DLLP (Data Link Layer Packet) | 链路错误统计、重传超时处理 |
| 物理层 | 串行/解串、编码、链路训练、电气特性 | PLP (Physical Layer Packet) / 有序集 | 链路状态检测、速率/宽度协商 |
下面是一个 PCIe 分层协议栈的架构示意图:
1.3.4 分层协议的数据流示例
以驱动发起一次 MMIO 读操作 为例,数据在各层之间的流动过程如下:
- 事务层:驱动通过 MMIO 地址发起读操作。事务层生成一个 Memory Read TLP,包含请求者 ID、地址、长度等信息,并传递给数据链路层。
- 数据链路层:为 TLP 添加序列号和 LCRC,形成 DLLP,然后传递给物理层。同时,数据链路层会保留 TLP 副本,等待接收端的 ACK 确认。
- 物理层:对 DLLP 进行编码(如 128b/130b),并通过差分信号对串行发送出去。
- 接收端(设备):物理层接收信号,解码后传递给数据链路层。数据链路层验证 LCRC,发送 ACK DLLP 给发送端。验证通过后,将 TLP 传递给事务层。
- 设备事务层:解析 TLP,执行内存读操作,并生成一个 Completion TLP(包含读取的数据)返回给发送端。
- 返回路径:Completion TLP 同样经过数据链路层和物理层,最终到达驱动,完成读操作。
下表对比了 PCIe 各代的主要性能参数:
| PCIe 版本 | 编码方式 | 单通道速率 (GT/s) | x16 单向带宽 (GB/s) | 引入年份 |
|---|---|---|---|---|
| 1.0 | 8b/10b | 2.5 | 4 | 2003 |
| 2.0 | 8b/10b | 5.0 | 8 | 2007 |
| 3.0 | 128b/130b | 8.0 | 16 | 2010 |
| 4.0 | 128b/130b | 16.0 | 32 | 2017 |
| 5.0 | 128b/130b | 32.0 | 64 | 2019 |