Bios实习 学习篇- 5.PCIe学习(1)
1.PCIe概念
PCIe是一种高速通信总线/接口标准,用来连接CPU和各种外部设备。 对 BIOS/UEFI 来说,PCIe 最重要的不是“线有多快”,而是 上电后怎么把链路训起来、怎么枚举设备、怎么给设备分配地址空间和总线号、怎么把这些信息交给操作系统
2.现代计算机结构
CPU
├── 内存(RAM)
└── PCIe总线 ──── GPU
├── 网卡
├── SSD(NVMe)
└── 其他扩展设备
CPU 是“计算核心”,PCIe 是“连接通道”,GPU / 网卡 / SSD 是“外设”
3.PCIe 枚举
PCIe 枚举(PCI Express Enumeration) 是 PCIe 系统启动或初始化过程中,由 Root Complex(RC,通常是 CPU 或芯片组中的主机桥)自动发现、识别并配置所有连接设备的关键机制。它确保操作系统能够正确访问 PCIe 拓扑中的所有 Endpoint(端点设备,如网卡、GPU、SSD)和 Switch(交换机),并为它们分配必要的资源(如总线号、内存地址空间、中断等)。
第一阶段:PEI阶段(硬件初始化)
- 时间点:CPU复位后,内存初始化完成后
- 关键操作:Root Complex初始化:CPU内部PCIe控制器上电MMCONF基地址设置:配置MCFG ACPI表,建立内存映射配置空间基础枚举:仅枚举必须设备(如SATA控制器、USB控制器)
mov eax, 0x80000000 ; PCI配置空间基地址 mov dx, 0xCF8 ; 配置端口 out dx, eax ; 写入配置地址 mov dx, 0xCFC ; 数据端口 in eax, dx ; 读取Vendor ID cmp eax, 0xFFFFFFFF ; 检查设备是否存在
- 约束:此时内存尚未完全初始化,只能使用Cache-as-RAM
第二阶段:DXE阶段(完整枚举)
- 时间点:内存完全初始化后,BDS(Boot Device Selection)阶段前
- 关键操作:深度优先遍历:从Root Complex开始,遍历所有Switch和Endpoint
资源分配:MMIO空间(64位地址)、I/O空间(传统16位)、IRQ线路(MSI/MSI-X向量)、ACPI表生成:_PRT、MCFG、SSDT-PCI
EFI_STATUS PciEnumeration() {
PciRootBridgeEnumeration(); // 枚举根桥
PciBusEnumeration(0); // 从Bus 0开始深度优先遍历
PciResourceAllocation(); // 资源分配
PciProgram(); // 配置设备
return EFI_SUCCESS;
}
枚举过程的技术深度
BDF(Bus/Device/Function)分配机制
- 总线号分配:Root Complex固定为Bus 0、每个PCIe Switch下游端口分配新总线号、动态分配算法:避免总线号冲突
- 设备号分配:传统PCI:由AD[15:11]决定(0-31)、PCIe:由Slot Number决定(1-32)
- 功能号分配:单功能设备:Function 0、多功能设备:Function 0-7(Header Type 0x80)
配置空间访问的底层实现
MMIO方式(现代系统):
配置地址 = (Bus << 20) | (Device << 15) | (Function << 12) | Offset 物理地址 = MMCONF_BASE + 配置地址
传统IO方式(兼容模式):
IO端口CF8h:地址寄存器 2IO端口CFCh:数据寄存器
资源分配的复杂性
- MMIO分配策略:
4GB以下空间:兼容传统设备
4GB以上空间:64位设备(GPU、NVMe)
对齐要求:BAR大小必须2^n对齐
- 冲突处理:
资源重分配:当空间不足时,回溯重新分配
优先级策略:GPU > NVMe > NIC > 其他
PCIe硬件依赖链
CPU复位 ↓ 内存初始化(必须通过PCIe枚举SATA/USB控制器才能访问Boot ROM) ↓ PCIe枚举(发现所有I/O设备) ↓ Option ROM执行(显卡初始化、RAID卡初始化) ↓ 操作系统加载

查看6道真题和解析