1. PCIe基础概念:总线拓扑结构、Root Complex与Endpoint、配置空间与BAR空间
PCI Express(PCIe)作为现代计算机系统中主流的高速串行总线标准,取代了传统的并行PCI/PCI-X总线。理解PCIe的拓扑结构、核心组件以及地址映射机制,是开发稳定、高性能PCIe驱动程序的基石。本节将系统梳理这些基础概念,为后续的中断与DMA配置打下坚实的理论基础。
1.1 PCIe总线拓扑结构
PCIe采用点对点串行连接的树形拓扑结构,区别于传统PCI的共享并行总线。每个设备与交换器(Switch)或根复合体(Root Complex)之间拥有独立的物理链路(Link),链路可由多条通道(Lane)组成(×1、×4、×8、×16)。
下图展示了典型的PCIe系统拓扑结构,清晰描述了各组件之间的层级关系:
1.2 Root Complex 与 Endpoint
PCIe体系结构定义了两种核心功能类型:Root Complex (RC) 和 Endpoint (EP)。此外,Switch 和 Bridge 作为扩展和桥接组件存在。
| 组件 | 角色与功能 | 典型位置 |
|---|---|---|
| Root Complex (RC) | 连接 CPU/内存子系统与 PCIe 交换结构;生成配置请求、I/O 请求、内存请求;处理中断和错误上报。 | CPU 内部或芯片组(如 Intel PCH、AMD SoC) |
| Endpoint (EP) | PCIe 总线上的功能设备,发起或接收事务层包(TLP);可以是传统 EP 或支持 DMA 的 EP。 | 独立 PCIe 卡(GPU、NVMe SSD、网卡) |
| Switch | 由一个上游端口和多个下游端口组成,负责数据包路由和转发,扩展总线拓扑。 | 主板或扩展背板 |
| Bridge | 桥接 PCIe 与其他总线(如 PCI、PCI-X),实现协议转换。 | 老式设备兼容场景 |
1.3 PCIe 配置空间与 BAR 空间
每个 PCIe 设备(包括 RC、Switch、Endpoint)都包含一个 配置空间(Configuration Space),这是软件发现、初始化和控制设备的标准机制。配置空间的大小在 PCIe 中扩展到了 4KB(传统 PCI 为 256 字节)。
1.3.1 配置空间结构
前 64 字节为配置空间头部(Header),包含设备标识、命令状态、类代码、基地址寄存器(BAR) 等关键字段。头部类型分为 Type 0(Endpoint)和 Type 1(Bridge/Switch)。
1.3.2 BAR 空间详解
基地址寄存器(BAR) 是配置空间中最关键的字段之一。设备通过 BAR 向系统报告所需的地址空间大小和类型,系统固件(BIOS/UEFI)或操作系统在枚举时分配实际的物理地址范围。
- BAR 类型:
- Memory Space BAR:映射到系统物理内存地址空间,支持 32-bit 或 64-bit 寻址。bit 0 为 0 表示 Memory BAR。
- I/O Space BAR:映射到 I/O 地址空间(x86 架构),bit 0 为 1 表示 I/O BAR。现代 PCIe 设备已很少使用。
- BAR 大小探测: 软件通过向 BAR 写入全 1(0xFFFFFFFF),再读回值来获取设备所需地址空间大小。硬件会返回 0 到所需大小对齐的掩码。
- Prefetchable 属性: Memory BAR 的 bit 3 指示该空间是否可预取(Prefetchable)。可预取空间允许 CPU 缓存合并写入,适合帧缓冲等场景。
pci_resource_start()、pci_resource_len() 和 pci_ioremap_bar() 获取并映射 BAR 空间。例如:// 获取 BAR0 的物理地址和长度
resource_size_t bar0_start = pci_resource_start(pdev, 0);
resource_size_t bar0_len = pci_resource_len(pdev, 0);
// 将 BAR0 映射到内核虚拟地址空间
void __iomem *bar0_virt = pci_ioremap_bar(pdev, 0);
if (!bar0_virt) {
dev_err(&pdev->dev, "Failed to ioremap BAR0\n");
return -ENOMEM;
}
// 通过映射后的虚拟地址读写设备寄存器
u32 val = ioread32(bar0_virt + REG_OFFSET);
iowrite32(val | BIT(0), bar0_virt + REG_OFFSET);
1.4 地址空间与事务路由
PCIe 定义了三种地址空间,对应不同的事务类型:
| 地址空间 | 事务类型 | 用途 | 路由方式 |
|---|---|---|---|
| Memory | Memory Read / Write | 数据交换、DMA、寄存器访问 | 地址路由(基于地址范围) |
| I/O | I/O Read / Write | 传统设备兼容(x86 平台) | 地址路由 |
| Configuration | Configuration Read / Write | 设备枚举、配置空间访问 | ID 路由(Bus:Device:Function) |
1.5 本章小结
本节建立了 PCIe 驱动开发的基础知识框架:
- 拓扑结构:点对点树形拓扑,RC 为根,Switch 扩展,Endpoint 为功能设备。
- 核心组件:RC 连接 CPU/内存,EP 实现具体功能,驱动主要面向 EP 编程。
- 配置空间:4KB 标准空间,前 64 字节包含设备标识、BAR 等关键信息。
- BAR 空间:设备向系统申请地址范围的机制,驱动通过映射后的虚拟地址访问设备寄存器。