理解 lspci

在 linux 中,可以利用 lspci 指令來列出所有連接的 PCI 裝置,本文簡單說明 lspci 的顯示結果。




lspci 的顯示結果

Interpreting the output of lspci 的例子來說:

00:00.0 Host bridge: Intel Corporation Haswell-ULT DRAM Controller (rev 0b)
00:02.0 VGA compatible controller: Intel Corporation Haswell-ULT Integrated Graphics Controller (rev 0b)
00:03.0 Audio device: Intel Corporation Haswell-ULT HD Audio Controller (rev 0b)
00:14.0 USB controller: Intel Corporation Lynx Point-LP USB xHCI HC (rev 04)
00:16.0 Communication controller: Intel Corporation Lynx Point-LP HECI #0 (rev 04)
00:1b.0 Audio device: Intel Corporation Lynx Point-LP HD Audio Controller (rev 04)
00:1d.0 USB controller: Intel Corporation Lynx Point-LP USB EHCI #1 (rev 04)
00:1f.0 ISA bridge: Intel Corporation Lynx Point-LP LPC Controller (rev 04)
00:1f.2 SATA controller: Intel Corporation Lynx Point-LP SATA Controller 1 [AHCI mode] (rev 04)
00:1f.3 SMBus: Intel Corporation Lynx Point-LP SMBus Controller (rev 04)


每一行都表示一個 PCI 裝置,在 linux 系統中,會對每個裝置給予 domain number, bus number, device number, function number,PCI Specification 允許系統中最多擁有 256 個 bus,每個 bus 最多可以有 32 個 devices,每個 devices 最多可以有 8 個 functions,而非零 domain number 只有在大型系統中才會用到,也因為這個原因,所以 lspci 並沒有顯示 domain number。
bus number, device number, function number 常被稱為 PCI 裝置的 BDF 或 B/D/F。

以第一行來說:

00:00.0 Host bridge: Intel Corporation Haswell-ULT DRAM Controller (rev 0b)


以亮色表示的字眼就是這個裝置的 BDF,其 bus number 為 00, device number 為 00, function number 為 0。
其 class 為 "Host bridge",vendor 為 "Intel Corporation", device 為 "Haswell-ULT DRAM Controller",版本號("rev") 為 11 (0x0b)。
版本號("rev") 定義了此裝置的 chipset 版本及 firmware 版本。

以倒數第二行來說:

00:1f.2 SATA controller: Intel Corporation Lynx Point-LP SATA Controller 1 [AHCI mode] (rev 04)


這個裝置的 bus number 為 00, device number 為 1f, function number 為 2。
其 class 為 "SATA controller",vendor 為 "Intel Corporation", device 為 "Lynx Point-LP SATA Controller 1 [AHCI mode]"。

這樣的話,很自然的會產生一個疑問,lspci 是如何知道 PCI 裝置的 class, vendor 及 device?

答案就是每個 PCI 裝置都會有一組暫存器來存放 device class、vendor ID 及 device ID 的值,這組暫存器稱為這個裝置的 configuration space

雖然儲存在 configuration space 的 device class、vendor ID 及 device ID 都是數字,但是 lspci 會透過事先定義好的 PCI ID table 把這些值轉換成文字模式。
利用 "lspci -nn",就可以看到原始的 device class、vendor ID 及 device ID。

00:00.0 Host bridge [0600]: Intel Corporation Haswell-ULT DRAM Controller [8086:0a04] (rev 0b)
00:02.0 VGA compatible controller [0300]: Intel Corporation Haswell-ULT Integrated Graphics Controller [8086:0a16] (rev 0b)
00:03.0 Audio device [0403]: Intel Corporation Haswell-ULT HD Audio Controller [8086:0a0c] (rev 0b)
00:14.0 USB controller [0c03]: Intel Corporation Lynx Point-LP USB xHCI HC [8086:9c31] (rev 04)
00:16.0 Communication controller [0780]: Intel Corporation Lynx Point-LP HECI #0 [8086:9c3a] (rev 04)
00:1b.0 Audio device [0403]: Intel Corporation Lynx Point-LP HD Audio Controller [8086:9c20] (rev 04)
00:1d.0 USB controller [0c03]: Intel Corporation Lynx Point-LP USB EHCI #1 [8086:9c26] (rev 04)
00:1f.0 ISA bridge [0601]: Intel Corporation Lynx Point-LP LPC Controller [8086:9c43] (rev 04)
00:1f.2 SATA controller [0106]: Intel Corporation Lynx Point-LP SATA Controller 1 [AHCI mode] [8086:9c03] (rev 04)
00:1f.3 SMBus [0c05]: Intel Corporation Lynx Point-LP SMBus Controller [8086:9c22] (rev 04)


第一組以亮色表示的字眼就是 device class,第二組以亮色表示的字眼就是 vendor ID 及 device ID,格式為 [vendor-id:device-id]。



如何得到 PCI 裝置的 class、vendor、model 名稱

那 lspci 究端是如何將數字型式的 device class,vendor ID 及 device ID 轉換成文字型式呢?
利用 "lspci -h" 的說明,可以看到一些端倪:
-i <file> Use specified ID database instead of /usr/share/misc/pci.ids.gz
也就是說加上 -i <file> 參數,就可以讓 lspci 根據這個檔案來將數字型式的 device class,vendor ID 及 device ID 轉換成文字型式。
檔案通常是 pci.ids,可以在這個網站 The PCI ID Repository 下載。
經過測試,的確可以用加上 -i <file> 參數的方式來實作。

可是問題又來了,那如果不加上 -i <file> 參數呢?
從上述訊息是說,預設會讀取 /usr/share/misc/pci.ids.gz,但是系統中,卻沒有這個檔案,這是怎麼一回事?

經過 grep 整個系統資料夾,總算在下列兩個檔案中,找到關鍵字:
/usr/lib/udev/hwdb.d/20-pci-classes.hwdb
/usr/lib/udev/hwdb.d/20-pci-vendor-model.hwdb
從檔名來看,可以知道一個是 class 的對映,另一個就是 vendor 及 model 的對映,這邊所指的 model 跟 device ID 是同一個東西。

但是這兩個檔案並不是直接被 lspci 所參考,lspci 直接參考的檔案是:
/etc/udev/hwdb.bin
這個結論是這樣來的:
因為透過 grep 整個系統資料夾,得知 hwdb.bin 也包含關鍵字,但是直接修改 hwdb.bin,會導致 lspci 執行有問題,所以就 google 了如何更新 hwdb.bin,於是找到了這篇文章:Linux通用键位修改(中)-实际操作

那該如何更新 /etc/udev/hwdb.bin 呢?
Linux通用键位修改(中)-实际操作 來推敲,機制是這樣子的,先修改 20-pci-classes.hwdb 及 20-pci-vendor-model.hwdb,再執行以下指令,把定義的內容編譯到 hwdb.bin:
# udevadm hwdb --update // 重新編譯 hwdb.bin
# udevadm trigger // 讓重新編譯的 hwdb.bin 生效

 

 

Reference

Interpreting the output of lspci

Linux通用键位修改(中)-实际操作

文字內容 或 影像內容 部份參考、引用自網路,如有侵權,請告知,謝謝。

 

 

 

arrow
arrow
    全站熱搜

    silverwind1982 發表在 痞客邦 留言(1) 人氣()