1. Overview
众说周知,lspci -xxx可以dump出pcie的整个config space,本文介绍其内核实现。
- About lspci lspic用于在系统中显示有关pci总线的信息以及连接到它们的设备,出自pciutils软件包。 Various utilities dealing with the PCI bus. Provides things like setpci and lspci. http://atrey.karlin.mff.cuni.cz/~mj/pciutils.html
2. lspci xxx输出
root@~# lspci -xxx
00:00.0 Host bridge: Red Hat, Inc. QEMU PCIe Host bridge
00: 36 1b 08 00 00 00 00 00 00 00 00 06 00 00 00 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 f4 1a 00 11
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00:01.0 Ethernet controller: Red Hat, Inc Virtio network device
00: f4 1a 00 10 07 04 10 00 00 00 00 02 00 00 00 00
10: 01 10 00 00 00 00 04 10 00 00 00 00 00 00 00 00
20: 0c 00 00 00 80 00 00 00 00 00 00 00 f4 1a 01 00
30: 00 00 00 00 98 00 00 00 00 00 00 00 29 01 00 00
40: 09 00 10 01 04 00 00 00 00 00 00 00 00 10 00 00
50: 09 40 10 03 04 00 00 00 00 10 00 00 00 10 00 00
60: 09 50 10 04 04 00 00 00 00 20 00 00 00 10 00 00
70: 09 60 14 02 04 00 00 00 00 30 00 00 00 10 00 00
80: 04 00 00 00 09 70 14 05 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 11 84 05 80 01 00 00 00
a0: 01 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3. lspic -xxx strace分析
根据strace的log,可以查看命令的系统调用,可以查看其打开了哪些文件,从而帮助分析命令的实现方式。
openat(AT_FDCWD, "/sys/bus/pci/devices/0000:00:00.0/resource", O_RDONLY|O_LARGEFILE) = 4
fstat(4, {st_mode=S_IFREG|0444, st_size=4096, ...}) = 0
read(4, "0x00011b0106000000 0x00011b01060"..., 4096) = 627
close(4) = 0
openat(AT_FDCWD, "/sys/bus/pci/devices/0000:01:00.0/resource", O_RDONLY|O_LARGEFILE) = 4
fstat(4, {st_mode=S_IFREG|0444, st_size=4096, ...}) = 0
read(4, "0x00011b0104800000 0x00011b01049"..., 4096) = 399
close(4)
openat(AT_FDCWD, "/sys/bus/pci/devices/0000:01:00.0/config", O_RDONLY|O_LARGEFILE) = 3
pread64(3, "\253\21\36\310F\5\20\0\0\0\0\2\20\0\0\0\f\0\200\4\1\0\0\0\f\0\0\0\1\0\0\0"..., 64, 2005694592) = 64
close(3) = 0
openat(AT_FDCWD, "/sys/bus/pci/devices/0000:00:00.0/config", O_RDONLY|O_LARGEFILE) = 3
pread64(3, "}\27\226\0F\1\20\0\2p\4\6\20\0\1\0\f\0\0\6\1\0\0\0\0\1\1\0\361\1\0 "..., 64, 2005694592) = 64
fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(0x4, 0x41), ...}) = 0
ioctl(1, TCGETS, {B115200 opost isig icanon echo ...}) = 0
openat(AT_FDCWD, "/usr/share/pci.ids.gz", O_RDONLY|O_LARGEFILE) = 4
可见lspci -xxx命令是从sysfs 文件读取的 config space内容,然后和/usr/share/pci.ids.gz对照解析,得出PCIe设备的类型,厂家等信息。对照这些sysfs文件的内核实现,我们也可以使用cat,hexdump等命令直接读取config space的内容。
3.1 cat resource文件
/usr/share # cat /sys/bus/pci/devices/0000:01:00.0/resource
0x00011b0104800000 0x00011b0104900000 0x000000000014220c
0x0000000000000000 0x0000000000000001 0x0000000000000000
0x00011b0100000000 0x00011b0104000000 0x000000000014220c
0x0000000000000000 0x0000000000000001 0x0000000000000000
0x00011b0104000000 0x00011b0104800000 0x000000000014220c
0x0000000000000000 0x0000000000000001 0x0000000000000000
0x0000000000000000 0x0000000000000001 0x0000000000000000
/usr/share # cat /sys/bus/pci/devices/0000:00:00.0/resource
0x00011b0106000000 0x00011b0106004000 0x000000000014220c
0x0000000000000000 0x0000000000000001 0x0000000000000000
0x0000000000000000 0x0000000000000001 0x0000000000000000
0x0000000000000000 0x0000000000000001 0x0000000000000000
0x0000000000000000 0x0000000000000001 0x0000000000000000
0x0000000000000000 0x0000000000000001 0x0000000000000000
0x00011b00f0000000 0x00011b00f0010000 0x0000000000046200
0x0000000000000000 0x0000000000000001 0x0000000000000000
0x0000000000000000 0x0000000000000001 0x0000000000000000
0x00011b0100000000 0x00011b0106000000 0x0000000000102201
0x0000000000000000 0x0000000000000001 0x0000000000000000
3.2 hexdump config 文件
config文件是由drivers\pci\pci-sysfs.c创建:
static struct bin_attribute pci_config_attr = {
.attr = {
.name = "config",
.mode = S_IRUGO | S_IWUSR,
},
.size = PCI_CFG_SPACE_SIZE,
.read = pci_read_config,
.write = pci_write_config,
};
可看出config文件类型是bin_attribute ,所以用hexdump读取:
/isam/slot_default/run # hexdump /sys/bus/pci/devices/0000:01:00.0/config
0000000 ab11 1ec8 4605 1000 0000 0002 1000 0000
0000010 0c00 8004 0100 0000 0c00 0000 0100 0000
0000020 0c00 0004 0100 0000 0000 0000 ab11 ab11
0000030 0000 0000 4000 0000 0000 0000 6d01 0000
0000040 0150 0306 0000 0000 0000 0000 0000 0000
0000050 0560 8100 b03c 0000 0000 0000 0000 0000
0000060 1000 1200 8080 0000 0f20 0000 12ac 0704
0000070 0000 1110 0000 0000 0000 4000 0000 0000
0000080 0000 0000 0000 0000 0000 0000 0000 0000
0000090 0200 0000 0000 0000 0000 0000 0000 0000
00000a0 0000 0000 0000 0000 0000 0000 0000 0000
*
0000100 0100 0100 0000 0000 0000 0000 1000 0600
0000110 0000 0000 0000 0000 0000 0000 0000 0000
0000120 0000 0000 0000 0000 0000 0000 0700 0000
0000130 0000 0000 0000 0000 0000 0000 0000 0000
*
0001000