lspci是如何工作的

目录

  • 前言
  • lspci
  • 那么系统是怎么知道每个PCIe设备具体是哪个厂商的哪种设备的?

前言

出于好奇,看了看lspci的工作原理,操作系统是怎么认识这么多PCIe设备的;

lspci

lspci用于查看当前系统所连接的所有PCI/PCIe设备;

这里解释一下lspci的输出,比如我这台机子上:

wp@wp-7050:~$ lspci
[...]
01:00.0 Ethernet controller: Netronome Systems, Inc. Device 4000
02:00.0 PCI bridge: Texas Instruments XIO2001 PCI Express-to-PCI Bridge
04:00.0 Ethernet controller: Intel Corporation Ethernet Controller 10G X550T (rev 01)
04:00.1 Ethernet controller: Intel Corporation Ethernet Controller 10G X550T (rev 01)

左边一列是PCI/PCIe的编号,每个设备有三个编号,以04:00.0为例,04是设备的总线编号(Bus Number);00是设备编号(Device Number);0是功能编号(Function Number),需要注意这三个编号在lspci里面的显示都是十六进制的;PCI/PCIe设备还有一个编号,域编号(Domain Number),只不过上面都是0,就忽略了;但一些场景下是会有多个Domain的,我们可以用lspci -D命令显示域编号:

wp@wp-7050:~$ lspci -D
[...]
0000:01:00.0 Ethernet controller: Netronome Systems, Inc. Device 4000
0000:02:00.0 PCI bridge: Texas Instruments XIO2001 PCI Express-to-PCI Bridge
0000:04:00.0 Ethernet controller: Intel Corporation Ethernet Controller 10G X550T (rev 01)
0000:04:00.1 Ethernet controller: Intel Corporation Ethernet Controller 10G X550T (rev 01)

那么系统是怎么知道每个PCIe设备具体是哪个厂商的哪种设备的?

这就涉及PCIe设备的配置空间,简单理解就是PCIe设备遵循标准,在设备中按PCI Configuration Space格式存储相关设备及配置信息;lscpi -x就可以看到PCIe设备的标准config space信息;共64字节,格式定义如下:

lspci是如何工作的_第1张图片

以我主机上的Intel X550T网卡为例,我们顺便加上nn参数,同时在方括号中显示对应的标识码;需要注意显示是小端序(little-endian),比如刚开始的四个字节,Vendor ID是8086,Device ID是1563;

root@wp-7050:/home/wp# lspci -xnn -s 04:00
04:00.0 Ethernet controller [0200]: Intel Corporation Ethernet Controller 10G X550T [8086:1563] (rev 01)
00: 86 80 63 15 06 05 10 00 01 00 00 02 00 00 80 00
10: 0c 00 80 ed 00 00 00 00 00 00 00 00 00 00 00 00
20: 0c 40 c0 ed 00 00 00 00 00 00 00 00 86 80 22 00
30: 00 00 08 f7 40 00 00 00 00 00 00 00 0a 02 00 00

04:00.1 Ethernet controller [0200]: Intel Corporation Ethernet Controller 10G X550T [8086:1563] (rev 01)
00: 86 80 63 15 06 05 10 00 01 00 00 02 00 00 80 00
10: 0c 00 40 ed 00 00 00 00 00 00 00 00 00 00 00 00
20: 0c 00 c0 ed 00 00 00 00 00 00 00 00 86 80 22 00
30: 00 00 00 f7 40 00 00 00 00 00 00 00 0b 01 00 00


系统可以读取(这里具体怎么读取我们就不深挖了)每个PCIe设备的config space,其中一些类型标准和供应商标识都由https://pci-ids.ucw.cz/维护,一般系统中会在/usr/share/hwdata/pci.ids.gz/usr/share/hwdata/pci.ids中有存储

  • Vendor ID是设备的供应商标识,是由PCI SIG授权分配的一个ID,只读。(8086代表Intel Corporation,8086是intel第一款16位处理器型号,有趣);
  • Device ID是供应商指定的设备标识,指定具体的设备型号,只读。(1563代表Ethernet Controller X550);
  • Class CodeSubclass分别指明设备类型和具体功能;(0200分别代表 Network controller和Ethernet controller)

以上这几部分就足够lspci显示PCIe设备了。

注:一开始看Header Type时特别困惑,后来看到有资料提到Header Type第7位是一个标志位,为1表示当前PCI设备为多功能设备,也就是前面介绍到的Function Number会有多个,剩余0~6位表示config space的类型,这里也不多深究。这张网卡可能是把两个接口当做两个Function?不深究了;更直观的例子是显卡,某些显卡有多个功能之类的;

Q: PCIe的config space整个都是只读的对吧,烧录在ROM中?

A: 并不都是只读的,比如Command和BAR就是可配置的;没查到在哪,反正就是一堆寄存器;

你可能感兴趣的:(打破砂锅系列,网络)