news 2026/6/26 8:51:07

PCIe从入门到精通之十八:PCIe设备的初始化枚举过程2

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PCIe从入门到精通之十八:PCIe设备的初始化枚举过程2

0,引言

在上一篇文章《PCIe从入门到精通之十七:PCIe设备的初始化枚举过程1》中我们介绍了PCIe设备的初始化枚举过程一些概念.这一篇我们将具体介绍PCIe设备的初始化枚举一步一步的动态过程,以及Primary Bus Number Register, Secondary Bus Number Register 和Subordinate Bus Number Register的值如何确定。

这一篇内容有点多,请大家耐心看完,看完后对PCIe体系的拓扑和tree的结构会了如指掌。

所有PCIe主题的文章都会收录在《深入浅出聊PCIe》https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzU3NDY3OTA2Nw==&action=getalbum&album_id=4142016342255960068#wechat_redirect合集里,你们的转发和评论是对我最大的支持。

需要下载PCIe学习资料标准的朋友(pdf格式),请关注本微信公众号“硬件工程师宝典”,在对话框内回复“PCIe”,将获取标准下载链接。

一,PCIe 体系架构

1, PCIe 体系架构的物理原型

PCIe体系架构在没有初始化之前如下图一所示。图中所有的设备都没有bus number和device number。

图一、PCIe 体系架构的物理原型

图中有以下三类PCIe设备:位于CPU的PCIe Root Complex(包含Host Bridge,RCiEP0~NRootPort0~2),Endpoint0,PCIe Switch0,PCIe Switch01以及挂载在Switch下的PCIe Endpoint设备SSD0~5Root Complex包含有Virtual PCI-PCI bridge0/1/6和"上游端口"Downstream Root port0/1/2; PCIe Switch包含Virtual PCI-PCI bridge2/3/4/5和Virtual PCI-PCI bridge7/8/9/10以及"上游端口"(Upstream Port)和"下游端口"(Downstream Port)。

2, 初始化完成后的Bus Number 分布

图二是初始化完成后的Bus Number 分布,我们先对此有个预览,下面一节我们将具体介绍PCIe设备的初始化枚举一步一步的动态过程,以及Primary Bus Number Register, Secondary Bus Number Register 和Subordinate Bus Number Register如何确定。

图二、初始化完成后的Bus Number 分布

二,PCIe设备的初始化枚举动态过程

1, 从HOST bridge开始初始化Virtual PCI-PCI Bridge 0

第一步,PCIe Host bridge主桥扫描Bus 0上的设备(在一个PCIe体系结构中,一般将Root complex中与Host Bridge直接相连接的PCIe总线命名为PCIe Bus 0),系统BIOS首先会忽略Bus 0上的Root Complex Integrated Endpoint(RCIEP)和RCEC等不会挂接PCIe bridge的设备,Host bridge发现Virtual PCI-PCI Bridge 0和Root port0后,将Virtual PCI-PCI Bridge 0 下面的PCIe Bus定为 Bus 1,系统将初始化Virtual PCI-PCI Bridge 0的配置空间,并将该桥的Primary Bus Number(PB)和 Secondary Bus Number(SB)寄存器分别设置成0和1,以表明Virtual PCI-PCI Bridge 0的上游总线是0,下游总线是1,由于还无法确定Virtual PCI-PCI Bridge 0下挂载设备的具体情况,系统BIOS不知道整个下游总线范围的上限,先暂时将Subordinate Bus Number(Sub)设为0xFF(最大值)。

即:Virtual PCI-PCI Bridge 0的PB=0;SB=1;Sub=0xFF;如图三所示。

图三、Bus 1枚举过程

第二步,系统BIOS开始扫描Bus 1,将会发现有且只有一个Endpoint 0,没有其它Bus,下游总线范围的上限Subordinate Bus Number也是1。

即:Virtual PCI-PCI Bridge 0的PB=0;SB=1;Sub=1;如图四所示。

当一个Virtual PCI-PCI Bridge的SB和Sub相等时,表面下面不在挂载有Virtual PCI-PCI Bridge,PCIe Bus扫描结束。BUS=1至此,系统BIOS完成了对Bus 0的扫描和枚举。

图四、Bus 1枚举完成

2, 返回HOST bridge开始初始化Virtual PCI-PCI Bridge 1

PCIe初始化和枚举过程中采用深度优先遍历算法

深度优先遍历: 分配完Virtual PCI-PCI Bridge 0的Bus Number后,枚举软件会立即进入新创建的次总线(即Virtual PCI-PCI Bridge 0的下游),继续对其进行枚举,然后再返回到上游总线,从Virtual PCI-PCI Bridge 1继续搜索。

在第一步中对Virtual PCI-PCI Bridge 0搜索完毕,系统会回到HOST bridge,接下来第二步对Virtual PCI-PCI Bridge 1和Root port1进行搜索。系统扫描到Virtual PCI-PCI Bridge 1,并将其下面直接连接的Bus分配为PCIe Bus2. 系统将初始化Virtual PCI-PCI Bridge 1的配置空间,并将该桥的Primary Bus Number(PB)和 Secondary Bus Number(SB)寄存器分别设置成0和2,以表明Virtual PCI-PCI Bridge 1的上游总线是0,下游总线是2,由于还无法确定Virtual PCI-PCI Bridge 1下挂载所有设备的具体情况,系统BIOS不知道整个下游总线范围的上限,先暂时将Subordinate Bus Number(Sub)设为0xFF(最大值)。

Virtual PCI-PCI Bridge 1的PB=0;SB=2;Sub=0xFF;如图五所示。

图五、PCIe Switch0下的Virtual PCI-PCI Bridge 3枚举完成

系统继续扫描Bus 2,将会发现PCIe Switch0,并对PCIe Switch0的upstream port和Virtual PCI-PCI Bridge 2进行扫描,将其下面直接连接的Bus分配为PCIe Bus3. 并将该桥的Primary Bus Number(PB)和 Secondary Bus Number(SB)寄存器分别设置成2和3. 由于还无法确定Virtual PCI-PCI Bridge 2下挂载设备的具体情况,Subordinate Bus Number(Sub)还是设为0xFF(最大值)。

继续深度优先遍历继续扫描,系统会先发现PCIe Switch0的Virtual PCI-PCI Bridge 3和upstream port,下面挂载的NVMe SSD0设备,系统将Virtual PCI-PCI Bridge 3下面的PCIe Bus定为Bus 4,并将该桥的Primary Bus Number 和 Secondary Bus Number寄存器分别设置成3和4,因为Virtual PCI-PCI Bridge 3下面挂的是端点设备(叶子节点),下面不会再有下游总线了,因此Virtual PCI-PCI Bridge 3的Subordinate Bus Number的值可以确定为4。

Virtual PCI-PCI Bridge 2的PB=2;SB=3;Sub=0xFF;如图五所示。

Virtual PCI-PCI Bridge 3的PB=3;SB=4;Sub=4;如图五所示。

至此,PCIe Switch0下的Virtual PCI-PCI Bridge 3所有bus和device都扫描完成。但是PCIe Switch0下的Virtual PCI-PCI Bridge 4和Virtual PCI-PCI Bridge 5还没有完成,系统BIOS将返回PCIe Switch0下的Virtual PCI-PCI Bridge2,继续进行深度优先遍历。紧接着PCIe Switch0下的Virtual PCI-PCI Bridge 4和Virtual PCI-PCI Bridge 5被发现,并被初始化。Virtual PCI-PCI Bridge 4下的bus被分配为bus 5,Virtual PCI-PCI Bridge 5下的bus被分配为bus 6。至此PCIe Switch0下的所有bus都被枚举,Subordinate Bus Number(Sub)的最大值被确定为6。之前默认为0xFF的Subordinate Bus Number(Sub)可以最终更新为6.

Virtual PCI-PCI Bridge 1:PB=0;SB=2;Sub=6;如图六所示。

Virtual PCI-PCI Bridge 2:PB=2;SB=3;Sub=6;如图六所示。

Virtual PCI-PCI Bridge 3:PB=3;SB=4;Sub=4;如图六所示。

Virtual PCI-PCI Bridge 4:PB=3;SB=5;Sub=5;如图六所示。

Virtual PCI-PCI Bridge 5:PB=3;SB=6;Sub=6;如图六所示。

图六、PCIe Switch0下的所有bus枚举完成

3, 返回HOST bridge开始初始化Virtual PCI-PCI Bridge 6

第三步和第二步高度相似,在第二步对Virtual PCI-PCI Bridge 1和Root port1进行搜索并扫描分配Bus number完毕后,系统BIOS会回到HOST bridge,侦测到Virtual PCI-PCI Bridge6和Root port2,并将其下面直接连接的Bus分配为PCIe Bus7. 系统将初始化Virtual PCI-PCI Bridge 2的配置空间,并将该桥的Primary Bus Number(PB)和 Secondary Bus Number(SB)寄存器分别设置成0和7,以表明Virtual PCI-PCI Bridge 1的上游总线是0,下游总线是7,由于还无法确定Virtual PCI-PCI Bridge 6下挂载所有设备的具体情况,系统BIOS不知道整个下游总线范围的上限,先暂时将Subordinate Bus Number(Sub)设为0xFF(最大值)。

Virtual PCI-PCI Bridge 6的PB=0;SB=7;Sub=0xFF;如图七所示。

图七、PCIe Switch1下的Virtual PCI-PCI Bridge 3枚举完成

系统继续扫描Bus 7,将会发现PCIe Switch1,并对PCIe Switch1的upstream port和Virtual PCI-PCI Bridge 7进行扫描,并将其下面直接连接的Bus分配为PCIe Bus8. 并将该桥的Primary Bus Number(PB)和 Secondary Bus Number(SB)寄存器分别设置成7和8. 由于还无法确定Virtual PCI-PCI Bridge 7下挂载设备的具体情况,Subordinate Bus Number(Sub)还是设为0xFF(最大值)。

继续深度优先遍历继续扫描,系统会先发现PCIe Switch1的Virtual PCI-PCI Bridge 8和upstream port,下面挂载的NVMe SSD3设备,系统将Virtual PCI-PCI Bridge 8下面的PCIe Bus定为Bus 9,并将该桥的Primary Bus Number 和 Secondary Bus Number寄存器分别设置成8和9,因为Virtual PCI-PCI Bridge 8下面挂的是端点设备(叶子节点),下面不会再有下游总线了,因此Virtual PCI-PCI Bridge 8的Subordinate Bus Number的值可以确定为9。

Virtual PCI-PCI Bridge 7的PB=7;SB=8;Sub=0xFF;如图七所示。

Virtual PCI-PCI Bridge 8的PB=8;SB=9;Sub=9;如图七所示。

至此,PCIe Switch1下的Virtual PCI-PCI Bridge 8所有bus和device都扫描完成。但是PCIe Switch1下的Virtual PCI-PCI Bridge 9和Virtual PCI-PCI Bridge 10还没有完成,系统BIOS将继续深度优先遍历。紧接着PCIe Switch1下的Virtual PCI-PCI Bridge 9和Virtual PCI-PCI Bridge 10被发现,并被初始化。Virtual PCI-PCI Bridge 9下的bus被分配为bus 0xa,Virtual PCI-PCI Bridge 10下的bus被分配为bus 0xb。至此PCIe Switch1下的所有bus都被枚举,Subordinate Bus Number(Sub)的最大值被确定为0xb。之前默认为0xFF的Subordinate Bus Number(Sub)可以最终更新为0xb.

Virtual PCI-PCI Bridge 6的PB=0;SB=7;Sub=0xb;如图八所示。

Virtual PCI-PCI Bridge 7的PB=7;SB=8;Sub=0xb;如图八所示。

Virtual PCI-PCI Bridge 8的PB=8;SB=9;Sub=9;如图八所示。

Virtual PCI-PCI Bridge 9的PB=8;SB=0xa;Sub=0xa;如图八所示。

Virtual PCI-PCI Bridge 10的PB=8;SB=0xb;Sub=0xb;如图八所示。

图八、PCIe Switch1下的所有bus枚举完成

至此,系统BIOS完成了对该CPU下的PCIe体系内所有的Bus的扫描和编号。枚举过程结束,Host通过这一过程获得了一个完整的PCIe设备拓扑结构和tree。

三,抛砖引玉

在这一章中我们具体介绍了PCIe设备的初始化枚举一步一步的动态过程,以及Primary Bus Number Register, Secondary Bus Number Register 和Subordinate Bus Number Register的值如何确定。

下一章我们将举例对PCIe设备的初始化枚举过程进行实战。

敬请关注下一篇:《PCIe从入门到精通之十九:利用lspci对PCIe设备拓扑结构解析实战1》

四,参考文献:

需要以下参考文献(PCIe标准)的朋友,请关注本微信公众号“硬件工程师宝典”,在对话框内回复“PCIe”,将获取标准下载链接。

百度网盘分享的文件

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/12 14:53:55

Agentic-KGR:多智能体强化学习驱动的知识图谱本体渐进式扩展技术

Agentic-KGR是一种通过多轮强化学习驱动的多智能体交互实现知识图谱本体渐进式自进化的技术框架。该框架遵循"提取→暂存→更新→奖励计算→晋升"的闭环流程,依赖LLM的知识发现能力和反馈闭环机制。系统通过多尺度提示压缩、Neo4j数据库管理、分层决策机制…

作者头像 李华
网站建设 2026/6/19 2:16:44

大模型多智能体架构完全指南:四种模式选择与LangChain实现技巧

在这篇文章中,我们将探讨: 多智能体(Multi-Agent)架构在什么时候变得必要四种主要模式LangChain 如何赋能我们高效地构建多智能体系统 大多数 Agentic(智能体驱动)任务,最佳实践是从配备精心设…

作者头像 李华
网站建设 2026/6/21 11:55:33

基于Springboot+Vue的物品租赁管理系统(源码+lw+部署文档+讲解等)

课题介绍本课题针对物品租赁行业租赁流程繁琐、物品状态难追踪、押金核算复杂、租赁数据零散等痛点,设计并实现基于SpringbootVue的物品租赁管理系统,构建集物品管理、租赁交易、押金管控、数据统计于一体的数字化租赁运营平台。系统以MySQL为数据存储核…

作者头像 李华
网站建设 2026/6/24 18:32:51

基于Springboot+Vue的校园闲置物品租售系统(源码+lw+部署文档+讲解等)

课题介绍 本课题针对校园内闲置物品流转不畅、交易信息分散、供需匹配低效、线下租售安全性不足及模式单一等痛点,设计并开发基于SpringbootVue的校园闲置物品租售系统,构建集物品发布、租售管理、检索匹配、在线沟通、履约追踪于一体的数字化校园服务平…

作者头像 李华
网站建设 2026/6/10 11:48:53

回归测试:软件演进中的质量守护神与实践全指南

回归测试作为软件质量保障的核心支柱,在持续交付和敏捷开发时代的重要性日益凸显。本文系统性地探讨了回归测试的理论基础、技术策略和实施框架,为企业构建高效、可持续的回归测试体系提供了一套完整的方法论。通过分层策略、选择性测试和智能自动化相结…

作者头像 李华
网站建设 2026/6/22 18:24:49

手把手教你学Simulink--电机控制架构与算法实现​场景示例:基于Simulink的电机电流环PI参数整定仿真

目录 手把手教你学Simulink 一、引言:为什么“调不好PI”会让高性能电机变成“抖动机器”? 二、核心原理:电流环的“等效传递函数”建模 1. 电流环简化模型(d/q轴解耦后) 2. 数字控制系统中的关键延迟 3. 电流环闭环结构 三、应用场景:伺服驱动器中的高性能电流环…

作者头像 李华