要描述一个pci设备,就需要知道设备的厂商号(venderId)、设备号(devId)和class号。那么,在Linux系统中,如何获取这三个数据呢?
既然是一个pci设备,那么首先就得知道BDF——该pci设备在OS中的唯一标识符。以网卡举例,我们可以通过ethtool来得到BDF。其中,bus-info对应的信息就是BDF。
# ethtool -i p12p1
driver: ixgbe
version: 4.0.1-k
firmware-version: 0x800003e1
bus-info: 0000:11:00.0
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: no
厂商号和设备号
可通过lspci命令获取pci设备的厂商号和设备号。
# lspci -n -s 11:00.0
11:00.0 0200: 8086:1528 (rev 01)
其中,8086就是厂商号,1528就是设备号。
# lspci | grep 11:00.0
11:00.0 Ethernet controller: Intel Corporation Ethernet Controller 10-Gigabit X540-AT2 (rev 01)
当然,也可以通过上面的方法直接使用lspci命令来查看该设备的基础信息。上面可以看出,这是一个intel的网卡设备,X540网卡。
class号
一个完整的class号应该包含三个部分:Device class、Device subclass和Program interface,每个部分占2个16进制数字,一个类型的设备,他们的class号是一样的。其实,在上面的lspci命令中已经获取到了部分的class号。下面实例的0200就是class号的前两部分Device class和Device subclass,只是没有Program interface这一部分。要查询完整的class号,可以通过在线网站pci-ids(http://pci-ids.ucw.cz/read/PD)来查询。
# lspci -n -s 11:00.0
11:00.0 0200: 8086:1528 (rev 01)
无Program interface情况
还是以上面的网卡为例,我们已经知道这是个网卡控制器(Ethernet controller)。那么我们就在网页的Jump一栏中输入关键字“Ethernet controller”,就会直接跳转该项。由于该项没有Program interface,因此,最终的class号就是020000。
有Program interface情况
再以三星的ssd磁盘为例。
# lspci | grep Samsung
01:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd Device a802 (rev 01)
0c:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd Device a802 (rev 01)
10:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd Device a802 (rev 01)
# lspci -n -s 01:00.0
01:00.0 0108: 144d:a802 (rev 01)
在pci-ids(http://pci-ids.ucw.cz/read/PD)查询关键字“Non-Volatile memory controller”,进入该项后,了解到该项的Device class和Device subclass为0108。同时,我们还发现该项有两个Program Interface。由于这个ssd是NVMe总线的,所以该ssd的最终class号就是010802。
ps:lspci -D:显示设备的厂商号、设备号、Class号。但这个Class号只是前半部分,还缺少后半部分。
# lspci -Q -s 0c:00.1
0c:00.1 Class 0200: Device 8086:1528 (rev 01)