lspci 如何找出 PCI(E) 设备的物理插槽号?
How does lspci find out physical slot number of a PCI(E) device?
lspci
可以在详细介绍中显示物理插槽号:
我想了解它是如何做到的。我将在我想修改的 driver 中应用此方法,因此它将枚举设备(具有相同的 ID)并根据物理插槽消除设备文件的歧义。喜欢 /dev/device_physslot 。 driver 将在 Ubuntu 18
上 运行
我试图挖掘源代码。我在 https://github.com/pciutils/pciutils/blob/master/lspci.c:
中找到了相关的第 775 行
if (p->phy_slot)
printf("\tPhysical Slot: %s\n", p->phy_slot);
p 是 struct pci_dev
。这一直很令人困惑,因为标准 linux/pci.h
没有字段 phy_slot
直到我弄清楚那是 their own (re)definition
结构is filled由函数
int
pci_fill_info_v38(struct pci_dev *d, int flags)
{
unsigned int uflags = flags;
if (uflags & PCI_FILL_RESCAN)
{
uflags &= ~PCI_FILL_RESCAN;
pci_reset_properties(d);
}
if (uflags & ~d->known_fields)
d->methods->fill_info(d, uflags);
return d->known_fields;
}
fill_info
是在https://github.com/pciutils/pciutils/blob/master/lib/internal.h(第44行)
中定义的函数指针
这就是我迷路的地方。
如果你 运行 dmidecode 它将显示存储的平台信息,它会告诉你物理插槽到 PCIe 地址的映射。例如:
Handle 0x001D, DMI type 9, 17 bytes
System Slot Information
Designation: J6B1
Type: x1 PCI Express
Current Usage: In Use
Length: Short
ID: 1 <== SLOT (starting at 0)
Characteristics:
3.3 V is provided
Opening is shared
PME signal is supported
Bus Address: 0000:00:1c.3 <== PCI BUS ADDRESS
槽的编程列表:
sudo dmidecode -t 9 |awk '/ID:/ {id=} /Bus Address/ {print "Slot",id+1,"PCIe",}'
Slot 1 PCIe 0000:00:01.0
Slot 2 PCIe 0000:00:1c.3
Slot 3 PCIe 0000:00:1c.4
Slot 4 PCIe 0000:00:1c.5
Slot 5 PCIe 0000:00:1c.6
深入挖掘源代码并在调试器中成功使用 运行 lspci(感谢 Netbeans)后,我发现 lspci 使用 sysfs 来收集信息。
特别是 /sys/bus/pci/slots/slot_num/address 文件包含插槽的总线地址。这就是 lspci 在函数 sysfs_fill_slots
(在 sysfs.c)
中用来将插槽归因于总线地址的方法
不幸的是,这种方法不适合我的目的,因为无法从内核模块执行文件I/O。
lspci
可以在详细介绍中显示物理插槽号:
我想了解它是如何做到的。我将在我想修改的 driver 中应用此方法,因此它将枚举设备(具有相同的 ID)并根据物理插槽消除设备文件的歧义。喜欢 /dev/device_physslot 。 driver 将在 Ubuntu 18
上 运行我试图挖掘源代码。我在 https://github.com/pciutils/pciutils/blob/master/lspci.c:
中找到了相关的第 775 行if (p->phy_slot)
printf("\tPhysical Slot: %s\n", p->phy_slot);
p 是 struct pci_dev
。这一直很令人困惑,因为标准 linux/pci.h
没有字段 phy_slot
直到我弄清楚那是 their own (re)definition
结构is filled由函数
int
pci_fill_info_v38(struct pci_dev *d, int flags)
{
unsigned int uflags = flags;
if (uflags & PCI_FILL_RESCAN)
{
uflags &= ~PCI_FILL_RESCAN;
pci_reset_properties(d);
}
if (uflags & ~d->known_fields)
d->methods->fill_info(d, uflags);
return d->known_fields;
}
fill_info
是在https://github.com/pciutils/pciutils/blob/master/lib/internal.h(第44行)
这就是我迷路的地方。
如果你 运行 dmidecode 它将显示存储的平台信息,它会告诉你物理插槽到 PCIe 地址的映射。例如:
Handle 0x001D, DMI type 9, 17 bytes
System Slot Information
Designation: J6B1
Type: x1 PCI Express
Current Usage: In Use
Length: Short
ID: 1 <== SLOT (starting at 0)
Characteristics:
3.3 V is provided
Opening is shared
PME signal is supported
Bus Address: 0000:00:1c.3 <== PCI BUS ADDRESS
槽的编程列表:
sudo dmidecode -t 9 |awk '/ID:/ {id=} /Bus Address/ {print "Slot",id+1,"PCIe",}'
Slot 1 PCIe 0000:00:01.0
Slot 2 PCIe 0000:00:1c.3
Slot 3 PCIe 0000:00:1c.4
Slot 4 PCIe 0000:00:1c.5
Slot 5 PCIe 0000:00:1c.6
深入挖掘源代码并在调试器中成功使用 运行 lspci(感谢 Netbeans)后,我发现 lspci 使用 sysfs 来收集信息。
特别是 /sys/bus/pci/slots/slot_num/address 文件包含插槽的总线地址。这就是 lspci 在函数 sysfs_fill_slots
(在 sysfs.c)
不幸的是,这种方法不适合我的目的,因为无法从内核模块执行文件I/O。