1. PCIe 基础概念:从并行到串行的演进

各位同学,咱们今天聊聊 PCIe 的基础。说实话,我做了十几年驱动,接触过不少总线。但 PCIe 给我的印象最深——它把 PC 架构的 I/O 性能彻底翻了个个儿。

先问大家一个问题:为什么 PCI 总线用了二十年,最后被 PCIe 取代了?答案其实很简单——速度。但背后的故事,远不止这么简单。

1.1 PCIe 总线的发展历史

PCI(Peripheral Component Interconnect)总线诞生于 1992 年,由 Intel 主导。那时候的 PC 还是 486 时代,PCI 的 33MHz/32bit 带宽(133MB/s)已经算很快了。

到了 2000 年左右,显卡、网卡、磁盘控制器对带宽的需求暴涨。PCI 的共享总线架构成了瓶颈。于是 PCI-X 出现了——它把频率提到 133MHz,甚至 533MHz。但问题没解决,反而更严重了。

关键转折点:2003 年,Intel 发布了 PCI Express 1.0 规范。从 PCI 到 PCIe,本质上是把并行总线换成了串行差分信号,把共享总线换成了点对点连接。

我当年第一次看到 PCIe 的 spec 时,心里想的是:串行能比并行快?这不是倒退吗?后来才明白,并行总线有信号同步、串扰、布线长度这些老大难问题。频率一高,并行信号根本稳不住。

PCIe 的发展历程大致如下:

版本 发布年份 单 Lane 速率 编码方式 x16 带宽(单向)
PCIe 1.0 2003 2.5 GT/s 8b/10b 4 GB/s
PCIe 2.0 2007 5.0 GT/s 8b/10b 8 GB/s
PCIe 3.0 2010 8.0 GT/s 128b/130b 16 GB/s
PCIe 4.0 2017 16.0 GT/s 128b/130b 32 GB/s
PCIe 5.0 2019 32.0 GT/s 128b/130b 64 GB/s
PCIe 6.0 2022 64.0 GT/s PAM4 + FLIT 128 GB/s

小提示:GT/s 是 Giga Transfers per second,不是 Gbps。PCIe 3.0 之后改用 128b/130b 编码,有效数据率更高。算带宽时记得去掉编码开销。

1.2 PCIe 与 PCI/PCI-X 的区别

说白了,PCI 和 PCIe 是两种完全不同的设计哲学。我列几个关键区别:

  • 拓扑结构:PCI 是共享总线,所有设备挂在同一条线上。PCIe 是点对点,每个设备独享带宽。
  • 信号方式:PCI 用并行信号(32/64 根数据线),PCIe 用差分串行(每个 Lane 一对 TX、一对 RX)。
  • 时钟方式:PCI 有独立时钟线,所有设备同步。PCIe 内嵌时钟,从数据流中恢复时钟。
  • 热插拔:PCI 基本不支持热插拔(服务器版除外)。PCIe 原生支持热插拔。
  • 配置空间:PCI 只有 256 字节配置空间。PCIe 扩展到 4KB,还加了能力结构(Capability Structure)。

避坑提醒:我曾经在一个项目里,把 PCIe 设备当 PCI 设备初始化,结果配置空间只读了前 256 字节,导致扩展能力寄存器没读到,设备死活枚举不出来。后来查了三天才发现——PCIe 的配置空间访问方式跟 PCI 不一样,必须用 ECAM(Enhanced Configuration Access Mechanism)。

还有一个细节:PCI 的地址空间是共享的,所有设备通过 BAR(Base Address Register)映射到同一个地址空间。PCIe 虽然也用了 BAR,但每个设备有自己的独立地址域,通过 RC 的地址转换来访问。

1.3 PCIe 的拓扑结构

PCIe 的拓扑结构,说白了就是一棵树。树根是 Root Complex(RC),树枝是 Switch,树叶是 Endpoint(EP)。

我画了一张图,大家看看:

PCIe 拓扑结构示意图 Root Complex (RC) CPU Memory Switch Endpoint (EP1) Endpoint (EP2) Endpoint (EP3) 说明: • Root Complex:连接 CPU、内存和 PCIe 域,负责地址转换和事务路由。 • Switch:由上游端口(Upstream Port)和多个下游端口(Downstream Port)组成, 负责数据包的路由和转发,相当于 PCIe 网络的交换机。 • Endpoint:PCIe 设备终端,如显卡、网卡、NVMe SSD 等。 • 每个连接都是一组 Lane(x1/x2/x4/x8/x16),点对点独立工作。

1.4 三个核心组件详解

Root Complex(RC)

RC 是 PCIe 层次结构的根。它连接 CPU、内存和 PCIe 域。我习惯把 RC 理解成「PCIe 世界的门卫」——所有从 CPU 发往 PCIe 设备的请求,都要经过 RC 转换。

RC 的主要职责:

  • 生成配置请求(Configuration Request),枚举总线上的设备
  • 处理内存映射 I/O(MMIO)访问,把 CPU 的地址转换成 PCIe 事务
  • 处理中断(MSI/MSI-X)和错误报告
  • 管理电源状态

Switch

Switch 是 PCIe 的扩展节点。它有一个上游端口(Upstream Port)连向 RC,多个下游端口(Downstream Port)连向 EP 或下级 Switch。

Switch 的核心能力是路由。它根据数据包中的地址信息,把包转发到正确的端口。我遇到过一个问题:某个 Switch 芯片的转发延迟标称是 150ns,但实际测出来有 300ns。后来发现是配置了错误的 VC(Virtual Channel)映射。嗯,这里要注意——Switch 的延迟跟 VC 配置强相关。

Endpoint(EP)

Endpoint 就是实际的 PCIe 设备。它可以是显卡、网卡、NVMe SSD、FPGA 加速卡等等。EP 通过 BAR 向系统暴露自己的寄存器空间和内存空间。

EP 有三种类型:

  • Legacy Endpoint:支持 PCI 兼容的 I/O 空间和中断
  • PCIe Endpoint:只支持 MMIO 和 MSI/MSI-X
  • RCiEP(Root Complex Integrated Endpoint):直接集成在 RC 内部,不经过外部 PCIe 链路

经验之谈:写 EP 驱动时,第一件事就是读 Vendor ID 和 Device ID。如果读出来全是 0xFFFF,说明链路没起来。如果读出来是 0x0000,说明设备没响应。这两个值能帮你快速定位问题。

1.5 数据流的基本路径

咱们看一个最简单的场景:CPU 写数据到 NVMe SSD。

  1. CPU 执行 store 指令,地址落在 NVMe 的 BAR 空间
  2. CPU 的 Memory Controller 把请求发给 RC
  3. RC 查路由表,发现目标设备在 Switch 下游
  4. RC 封装成 PCIe TLP(Transaction Layer Packet),发给 Switch
  5. Switch 解析 TLP 中的地址,转发到 NVMe 所在的端口
  6. NVMe 收到 TLP,解析出数据,写入内部寄存器或 DMA 引擎

整个过程,从 CPU 到设备,延迟通常在几百纳秒到几微秒之间。如果用了 PCIe 4.0 x4,带宽可以到 8GB/s 左右。

核心要点:PCIe 的拓扑是树形结构,数据流是点对点的。每个设备独享带宽,不会因为其他设备忙而阻塞。这是 PCIe 比 PCI 强的最根本原因。

1.6 小结

这一章咱们讲了 PCIe 的来龙去脉。从 PCI 到 PCI-X 再到 PCIe,本质上是总线架构的彻底重构。PCIe 用串行差分信号、点对点拓扑、内嵌时钟,解决了并行总线的瓶颈。

拓扑结构上,RC 是根,Switch 是枝,EP 是叶。理解这三者的关系,是写 PCIe 驱动的第一步。