1. 查看树状结构
lspci -tv
-+-[0009:00]---00.0-[01-ff]----00.0 Phison Electronics Corporation PS5013 E13 NVMe Controller
+-[0008:00]---00.0-[01-ff]----00.0 Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
+-[0007:00]---00.0-[01-ff]--+-00.0 Intel Corporation I350 Gigabit Network Connection
| +-00.1 Intel Corporation I350 Gigabit Network Connection
| +-00.2 Intel Corporation I350 Gigabit Network Connection
| \-00.3 Intel Corporation I350 Gigabit Network Connection
+-[0004:00]---00.0-[01-ff]--+-[0004:c0]---00.0 Intel Corporation Device 125c
| +-[0004:81]---00.0 Intel Corporation Device 125c
| +-[0004:42]---00.0 Intel Corporation Device 125c
| +-[0004:03]---00.0 Intel Corporation Device 125c
| +-[0004:02]-+-01.0 Pericom Semiconductor PI7C9X2G608GP PCIe2 6-Port/8-Lane Packet Switch
| | +-02.0 Pericom Semiconductor PI7C9X2G608GP PCIe2 6-Port/8-Lane Packet Switch
| | +-03.0 Pericom Semiconductor PI7C9X2G608GP PCIe2 6-Port/8-Lane Packet Switch
| | \-04.0 Pericom Semiconductor PI7C9X2G608GP PCIe2 6-Port/8-Lane Packet Switch
| \-[0004:01]---00.0 Pericom Semiconductor PI7C9X2G608GP PCIe2 6-Port/8-Lane Packet Switch
\-[0000:00]-
1.1 -+ (分支起点 / Root Complex 节点)
- 含义:表示这是一个总线分支的起点。在 PCIe 拓扑中,通常代表一个 Root Complex(根复合体)端口或一个桥接设备(Bridge),它向下衍生出了子设备。
1.2 0009:00 (PCIe 域与总线号)
含义:方括号内的内容代表 Domain(域): Bus(总线号)。
- 0009:代表 PCIe 域(Domain 9)。在一些多路处理器或复杂 SoC(如 NVIDIA Jetson 或多路服务器芯片)中,会有多个独立的 PCIe 域。
- 00:代表总线号(Bus 00)。这通常是该域下的根总线。
1.3 --- (连接线)
含义:纯粹的文本连线符号,用来在视觉上连接上下级层级,无实际硬件意义。
1.4. 00.0 (设备与功能号 - Device.Function)
含义:位于总线上的具体物理设备及其逻辑功能号,格式为 设备号.功能号(DD.F)。
- 前面的 00:代表该总线上的 Device 0(第 0 号设备)。
- 后面的 .0:代表 Function 0(第 0 号功能)。一个物理 PCIe 设备内部可以集成多个功能(例如网卡的 4 个网口),这里指第 0 号功能。
00.0-01-ff 表示一个桥设备;
1.5. -01-ff (子总线范围 - Subordinate Bus Range)
含义:表示该桥接设备或控制器所管辖的子总线编号范围。
- 01-ff:意味着从总线 01 一直到 ff(十六进制,即 255)的下游总线空间,全部归属于这个设备(或其下挂的子设备、Switch 交换芯片)来管理分配。
1.6 ---- (下游连接线)
含义:继续向右延伸,表示连接到具体的终端设备(Endpoint)。
1.7. 00.0 (终端设备的 Device.Function)
含义:这是挂在前面那条总线上的最终端设备自身的 PCI 地址(同样是 设备号.功能号,这里是 0.0)。
0009:00 下面挂了一个桥设备00.0, 这个桥设备 的总线号是01-ff, 这个桥设备下挂了一个00.0 设备
1.8 符号 -- 代表这是从总线 0004:01 延伸出来的主干接入点。
它扮演的角色是"这颗芯片面向 CPU 的大门"。既然是面向上一级(CPU),它在逻辑上自然就是 Upstream Port(上行端口)
PCIe Bridge 与 PCIe Switch 核心概念对比
| 维度 | Bridge(PCIe 桥) | Switch(PCIe 交换机) |
|---|---|---|
| 端口数量 | 通常只有 2个端口(一个上行端口、一个下行端口),属于点对点连接。 | 拥有 多于2个端口(如 4口、6口、8口及以上),属于多路复用。 |
| 拓扑结构 | 用于连接不同的 PCI 总线,形成层级结构 | 将一个上游 PCIe 链路扩展为多个下游链路 |
| 数据转发 | 在不同总线或 PCIe 链路之间转发数据 | 在多个下游端口之间进行 PCIe 事务路由与转发 |
| 并发能力 | 具体取决于桥的类型和链路结构 | 多个端口可以同时传输数据,实际带宽受上游链路及芯片能力限制 |
| 内部结构 | 结构相对简单,负责连接和转发 | 包含多个端口及交换逻辑,结构相对复杂 |
| 典型用途 | PCIe Root Port、PCIe-to-PCI Bridge 等 | PCIe Switch 芯片,例如 Pericom PI7C9X2G608GP |
| 拓扑示例 | Root Port → PCIe Endpoint | Root Port → PCIe Switch → 多个 Endpoint |
要接设备,必须先接一个桥,转换它的电气特性
只要跨越了一个 PCI-to-PCI 桥(Bridge) 或 Root Port(根端口,它本质上也是一个桥),进入桥的"后面"(面向下游设备的一侧),总线号(Bus Number)就会发生改变。因为桥的定义就是: 在不同总线或 PCIe 链路之间转发数据
桥的后面则开启了一片全新的、独立的子总线网段(比如总线 01、02 甚至更大)。
一个物理 PCIe Switch 芯片本身就包含多个虚拟桥
比如一个常见的 PCIe Switch 芯片(PLX/Broadcom/MicroChip 之类的),内部逻辑上会表现为"一个 Upstream Port + 若干 Downstream Port",每个 Port 在配置空间里都是一个独立的 PCI-to-PCI bridge 设备,lspci -tv 看到的就是这些桥节点,不是物理上真的有那么多块板子。
2. 查看所有设备及 PCI 地址
lspci -Dnn
0004:00:00.0 PCI bridge [0604]: NVIDIA Corporation Device [10de:229c] (rev a1)
0004:01:00.0 PCI bridge [0604]: Pericom Semiconductor PI7C9X2G608GP PCIe2 6-Port/8-Lane Packet Switch [12d8:2608]
0004:02:01.0 PCI bridge [0604]: Pericom Semiconductor PI7C9X2G608GP PCIe2 6-Port/8-Lane Packet Switch [12d8:2608]
0004:02:02.0 PCI bridge [0604]: Pericom Semiconductor PI7C9X2G608GP PCIe2 6-Port/8-Lane Packet Switch [12d8:2608]
0004:02:03.0 PCI bridge [0604]: Pericom Semiconductor PI7C9X2G608GP PCIe2 6-Port/8-Lane Packet Switch [12d8:2608]
0004:02:04.0 PCI bridge [0604]: Pericom Semiconductor PI7C9X2G608GP PCIe2 6-Port/8-Lane Packet Switch [12d8:2608]
0004:03:00.0 Ethernet controller [0200]: Intel Corporation Device [8086:125c] (rev 04)
0004:42:00.0 Ethernet controller [0200]: Intel Corporation Device [8086:125c] (rev 04)
0004:81:00.0 Ethernet controller [0200]: Intel Corporation Device [8086:125c] (rev 04)
0004:c0:00.0 Ethernet controller [0200]: Intel Corporation Device [8086:125c] (rev 04)
0007:00:00.0 PCI bridge [0604]: NVIDIA Corporation Device [10de:229a] (rev a1)
0007:01:00.0 Ethernet controller [0200]: Intel Corporation I350 Gigabit Network Connection [8086:1521] (rev 01)
0007:01:00.1 Ethernet controller [0200]: Intel Corporation I350 Gigabit Network Connection [8086:1521] (rev 01)
0007:01:00.2 Ethernet controller [0200]: Intel Corporation I350 Gigabit Network Connection [8086:1521] (rev 01)
0007:01:00.3 Ethernet controller [0200]: Intel Corporation I350 Gigabit Network Connection [8086:1521] (rev 01)
0008:00:00.0 PCI bridge [0604]: NVIDIA Corporation Device [10de:229c] (rev a1)
0008:01:00.0 Ethernet controller [0200]: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller [10ec:8168] (rev 15)
0009:00:00.0 PCI bridge [0604]: NVIDIA Corporation Device [10de:229c] (rev a1)
0009:01:00.0 Non-Volatile memory controller [0108]: Phison Electronics Corporation PS5013 E13 NVMe Controller [1987:5013] (rev 01)
2.1 -D(Domain,显示完整的域号)
默认情况下,普通的 lspci 输出可能只会显示总线号、设备号和功能号(形如 01:00.0)。
加上 -D 后,它会强制打印出完整的 Domain(域号)。
格式会变成形如 0004:c0:00.0 的标准 BDF 地址。对于像 NVIDIA Jetson、多路 PCIe 交换矩阵或高端服务器这种拥有多个独立 PCIe 域的系统,-D 是准确定位设备物理路径必不可少的参数。
2.2. -nn(Numeric Name,同时显示厂商与设备 ID 的十六进制数值与常见名称)
普通的 lspci 只会显示设备被内核识别出来的文字名称(比如 Intel Corporation Device 125c)。
单个 -n:只显示数字 ID(例如 8086:125c,即厂商 ID:设备 ID)。
双写 -nn:既显示文字名称,又在方括号中附带标准的十六进制数字 ID。
效果示例:Intel Corporation Device 125c 8086:125c
PCI 地址的格式是:Domain:Bus:Device.Function
3. 指定Domain:Bus:Device.Function 查看设备详细信息
| 对比项 | lspci -Dvv -s 0004:01:00.0 |
lspci -s 0004:c0:00.0 -v |
|---|---|---|
| 目标设备 | 0004:01:00.0 |
0004:c0:00.0 |
| 设备类型 | Pericom PCIe Switch 上游端口 | Intel 125c 网卡 |
-D |
显示 PCI Domain | 未指定 |
-v |
显示详细设备信息 | 显示详细设备信息 |
-vv |
显示更详细的信息 | 未指定 |
| -s | 指定要查看的 PCI 设备,可以是Domain:Bus:Device.Function,Bus:Device.Function, Bus:Device | |
| 主要用途 | 查看 Switch 端口、PCIe 链路和桥配置 | 查看网卡的 PCIe 链路、设备能力等 |
4. 读取指定 PCIe 设备的 PCI 配置空间
读取指定 PCIe 设备的 PCI 配置空间,并以十六进制形式显示前 256 字节的内容。
lspci -s 0004:c0:00.0 -xxx
| 偏移 | 字段 | 含义 |
|---|---|---|
0x00--0x01 |
Vendor ID | 厂商 ID |
0x02--0x03 |
Device ID | 设备 ID |
0x04--0x05 |
Command | PCI 命令寄存器 |
0x06--0x07 |
Status | PCI 状态寄存器 |
0x08 |
Revision ID | 设备版本号 |
0x09--0x0B |
Class Code | 设备类别代码 |
5. -k:查看设备绑定的内核驱动
lspci -k
# 或配合 -s 只看单个设备
lspci -s 0004:c0:00.0 -k
输出里会多出:
Kernel driver in use: igb
Kernel modules: igb
排查"设备识别到了但驱动没加载/加载了错误驱动"时最常用------直接看 Kernel driver in use 是不是你期望的那个,Kernel modules 是内核认为能 用的驱动(可能没加载)。常和 -vv 一起用:lspci -vvk 是故障排查最高频的组合。
6. -vv/-vvv 里最值得关注的部分:链路协商状态
调 PCIe link/RC 问题时特别有用。lspci -vv -s <BDF> 的输出里有一段 LnkCap/LnkSta:
LnkCap: Port #0, Speed 8GT/s, Width x4, ...
LnkSta: Speed 8GT/s, Width x4 (ok)
LnkCap(Link Capability):这个端口硬件设计上支持的最大速率/带宽。LnkSta(Link Status):当前实际协商上的速率/带宽。
两者不一致(比如 Cap 是 Gen3 x4,Sta 却掉到 Gen1 x1)是链路训练异常、信号质量差、线缆/连接器问题的典型症状,这是比单纯看"设备有没有被枚举出来"更深一层的排查手段。
7. -vvv 看扩展能力(AER、MSI/MSI-X 等)
-vvv(三个 v)会把 PCIe 扩展配置空间里的 Capability 列表全部展开,包括:
Advanced Error Reporting(AER):对应devdrv_mask_ras_aer_fault那类 RAS/AER 相关逻辑,能看到 Correctable/Uncorrectable Error 的状态寄存器。MSI/MSI-X:中断方式和中断向量数。Power Management:电源状态支持情况。
8. -d vendor:device 按厂商/设备 ID 过滤
lspci -d 19e5: # 只看华为(Ascend)厂商 ID 的设备
lspci -d 10de:229c # 精确匹配某个具体设备
lspci -nn -d 8086: # 只看 Intel 的设备,顺便带数字 ID
设备多的时候比用眼睛在 -Dnn 全量输出里找方便很多。
9. -b:以"网卡/设备自己视角"显示中断号和地址
lspci -b
正常 lspci 显示的 IRQ/地址是内核视角分配的,-b 显示的是设备硬件寄存器里实际配置的值(Bus-centric view)。两者理论上应该一致,不一致往往说明 BIOS/固件配置和内核分配对不上,是比较底层的排查手段,用得没那么频繁但遇到诡异中断问题时有用。
10. -x / -xxx / -xxxx 的区别
-x:只 dump 标准配置空间前 64 字节。-xxx:dump 完整 256 字节标准配置空间。-xxxx:dump 4096 字节 ,也就是包含 PCIe 扩展配置空间(AER、SR-IOV 等能力结构体都在这段里)------调扩展能力相关问题时要用这个而不是-xxx。
11. setpci:和 lspci 配对的"写"工具
lspci 只能读,setpci 是用同样的 BDF 寻址方式直接读写PCI 配置空间寄存器:
setpci -s 0004:c0:00.0 COMMAND
setpci -s 0004:c0:00.0 COMMAND=0x0007
调试阶段临时改个寄存器位(比如手动使能 Bus Master、强制关闭某个 capability)会用到,正式驱动代码里当然不会这么干,但现场调试定位问题时很实用。