System-Information

在linux中獲取硬體型號名稱

  • March 26, 2020

當一個選項被傳遞時,我正在編寫一個像Neofetch一樣工作的應用程序。它顯示了一些系統資訊,如記憶體、交換、cpu、電池使用情況、主機名、本地 ip、核心版本等。-w

我想知道如何在 Neofetch 中獲得“主機”。例如:

                  -`                    sourav@archlinux-arm 
                 .o+`                   -------------------- 
                `ooo/                   OS: Arch Linux armv7l 
               `+oooo:                  Host: Raspberry Pi 3 Model B Rev 1.2 
              `+oooooo:                 Kernel: 4.19.108-1-ARCH 
              -+oooooo+:                Uptime: 10 mins 
            `/:-:++oooo+:               Packages: 804 (pacman) 
           `/++++/+++++++:              Shell: bash 5.0.16 
          `/++++++++++++++:             Resolution: 1366x768 
         `/+++ooooooooooooo/`           DE: Xfce 
        ./ooosssso++osssssso+`          WM: Xfwm4 
       .oossssso-````/ossssss+`         WM Theme: XFCE_Colour_Lite_Pink 
      -osssssso.      :ssssssso.        Theme: XFCE_Colour_Lite_Pink [GTK2], X 
     :osssssss/        osssso+++.       Icons: Papirus [GTK2], Tela-orange [GT 
    /ossssssss/        +ssssooo/-       Terminal: tilix 
  `/ossssso+/:-        -:/+osssso+-     CPU: BCM2835 (4) @ 1.350GHz 
 `+sso+:-`                 `.-/+oso:    Memory: 333MiB / 901MiB 
`++:.                           `-/+/
.`                                 `/                           

我得到這樣的資訊。在我的筆記型電腦上:

                  -`                    sourav@archlinux 
                 .o+`                   ---------------- 
                `ooo/                   OS: Arch Linux x86_64 
               `+oooo:                  Host: Inspiron 5567 
              `+oooooo:                 Kernel: 5.5.10-arch1-1 
              -+oooooo+:                Uptime: 3 hours 
            `/:-:++oooo+:               Packages: 1163 (pacman) 
           `/++++/+++++++:              Shell: bash 5.0.16 
          `/++++++++++++++:             Resolution: 1920x1080 
         `/+++ooooooooooooo/`           DE: Xfce 
        ./ooosssso++osssssso+`          WM: Xfwm4 
       .oossssso-````/ossssss+`         WM Theme: XFCE_Colour_Lite_Ruby 
      -osssssso.      :ssssssso.        Theme: XFCE_Colour_Lite_Purple [GTK2 
     :osssssss/        osssso+++.       Icons: Papirus [GTK2/3] 
    /ossssssss/        +ssssooo/-       Terminal: tilix 
  `/ossssso+/:-        -:/+osssso+-     CPU: Intel i3-6006U (4) @ 2.000GHz 
 `+sso+:-`                 `.-/+oso:    GPU: Intel Skylake GT2 [HD Graphics  
`++:.                           `-/+/   Memory: 2814MiB / 3755MiB 
.`                                 `/

我的問題與這個問題有關,但它沒有回答我的問題,因為我的樹莓派無法執行dmidecode,(也沒有/sys/devices/virtual/dmi/),沒有lshw安裝。此外,/etc/hostname它們不是電腦的型號名稱,而只是archlinux-armarchlinuxuname -aor在樹莓派上cat /proc/version沒有“ Rapsberry Pi ”字元串。

有沒有辦法在不使用任何也應該在大多數硬體上執行的依賴項的情況下獲得像 neofetch 這樣的硬體名稱?

在 Linux 中沒有可移植的、可靠的、通用的方法來檢索硬體型號名稱。讓我描述兩種不同的情況:安裝了 Raspbian 的基於 ARM 的 Raspberry Pi 和安裝了 OpenWRT 的基於 MIPS 的 TP-LINK 路由器。

Raspberry Pi 有一個 ARM CPU 和 ARM 設備通常使用 設備樹來描述硬體, 維基百科的文章甚至提到它自 2012 年以來是強制性的。設備樹結構暴露給使用者空間,可用於通過cating 檢索模型名稱,/proc/device-tree/model其中/proc/device-tree本身是一個符號連結/sys/firmware/devicetree/base(請注意,設備樹文件末尾沒有換行符,因此我們創建了一個名為catn對文件進行分類並添加換行符)

pi@raspberrypi:~$ catn () { cat $1 && echo; }
pi@raspberrypi:~$ catn /proc/device-tree/model
Raspberry Pi 3 Model B Rev 1.2
pi@raspberrypi:~$ catn /sys/firmware/devicetree/base/model
Raspberry Pi 3 Model B Rev 1.2

或者通過使用 dtc 手動轉儲/sys/firmware/fdt扁平的設備樹 blob:

pi@raspberrypi:~$ sudo dtc /sys/firmware/fdt 2>/dev/null | grep model
   compatible = "raspberrypi,3-model-b\0brcm,bcm2837";
   model = "Raspberry Pi 3 Model B Rev 1.2";

如果一個官方的 Raspberry Pi Linux fork 正在使用中,模型也被 寫入 /proc/cpuinfo

pi@raspberrypi:~$ grep "^Model" /proc/cpuinfo
Model           : Raspberry Pi 3 Model B Rev 1.2

另請注意,板的全名 -Raspberry Pi 3 Model B Rev 1.2由低級韌體建構,您不會在 Linux 核心程式碼的任何地方找到這樣的完整字元串:

pi@raspberrypi:~$ strings /boot/start.elf  | grep 'Raspberry Pi '
Raspberry Pi %s Rev %s
Raspberry Pi Bootcode

modelDTSpec中描述的標准設備樹屬性。

RISC-V 等其他架構也使用設備樹來描述硬體,但我沒有任何 RISC-V 板要檢查。

我的 TP-LINK 路由器上沒有 /proc/device-tree、/sys/firmware/devicetree/base 和 /sys/firmware/fdt - 這意味著它要麼根本沒有設備樹,要麼一些適當的 Linux 核心配置選項已被禁用,並且設備樹沒有暴露給使用者空間。然而,前者更有可能,因為有 /tmp/sysinfo 代替:

~ $ cat /tmp/sysinfo/board_name
tl-wdr4300
~ $ cat /tmp/sysinfo/model
TP-Link TL-WDR3600 v1

這些值由ar71xx.sh 腳本生成,該腳本 相當長,但您可以看到它name是在第 1313 行分配的:

*"TL-WDR3600/4300/4310")
       name="tl-wdr4300"
   ;;

基於TL-WDR4900 v2哪個又取自machine/proc/cpuinfo的欄位:

machine=$(awk 'BEGIN{FS="[ \t]+:[ \t]"} /machine/ {print $2}' /proc/cpuinfo)

然後在腳本末尾分配AR71XX_BOARD_NAME和寫入 /tmp/sysinfo/board_name

machine此路由器上 /proc/cpuinfo中欄位的完整值為:

~ $ grep "^machine" /proc/cpuinfo
machine                 : TP-LINK TL-WDR3600/4300/4310

但是 Neofetch 不是在尋找 /tmp/sysinfo/board_name,而是在尋找 /tmp/sysinfo/model。它不是取自 /proc/cpuinfo 而是從firmwareflash 分區中讀取的:

~ $ cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00020000 00010000 "u-boot"
mtd1: 0010c5a4 00010000 "kernel"
mtd2: 006c3a5c 00010000 "rootfs"
mtd3: 00490000 00010000 "rootfs_data"
mtd4: 00010000 00010000 "art"
mtd5: 007d0000 00010000 "firmware"
~ $ dd if=/dev/mtdblock5 bs=4 count=1 skip=16 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"'  && echo
36000001

模型在第 321 行分配:

"360000"*)
   model="TP-Link TL-WDR3600"
   ;;

當然,很難想像像 Neofetch 這樣的通用程序會對每個韌體、它的快閃記憶體佈局等有如此多的了解。但是我可以想像一個基於 MIPS 的實現,它不支持設備樹並且不提供任何/tmp/sysinfo 和其他任何地方有用的硬體模型資訊,在這種情況下,/proc/cpuinfo 可以作為最後的手段來獲取有關硬體的任何資訊。

閱讀Neofetch的原始碼可以清楚地了解混淆。Neofetch 版本 7.0.0 的第 1174 行有條件檢查:

if [[ -d /system/app/ && -d /system/priv-app ]]; then
   model="$(getprop ro.product.brand) $(getprop ro.product.model)"

elif [[ -f /sys/devices/virtual/dmi/id/product_name ||
   -f /sys/devices/virtual/dmi/id/product_version ]]; then
   model=$(< /sys/devices/virtual/dmi/id/product_name)
   model+=" $(< /sys/devices/virtual/dmi/id/product_version)"

elif [[ -f /sys/firmware/devicetree/base/model ]]; then
   model=$(< /sys/firmware/devicetree/base/model)

elif [[ -f /tmp/sysinfo/model ]]; then
   model=$(< /tmp/sysinfo/model)
fi

它實際上檢查各種路徑,而不是獲取詳細資訊的單一路徑。所以這不是一個適用於每個 GNU/Linux 發行版的硬核檢查。例如,第一個 if 條件檢查可以在 Android 上找到的特定路徑。

我已經在各種發行版和硬體上測試了這些文件:

個人電腦和筆記型電腦

對於我所有的系統,/sys/devices/virtual/dmi/id/product_name都有模型資訊。

Raspberry Pi 3 Model B 和 Android(7.0 測試)

在我的 Raspberry Pi 3 Model B 和 Android 智能手機中,該文件/sys/firmware/devicetree/base/model包含型號資訊。

虛擬盒子

Debian 在 Virtualbox 中執行,Neofetch 顯示Virtualbox 1.2為主機,可以通過cat /sys/devices/virtual/dmi/id/product_name /sys/devices/virtual/dmi/id/product_version.

請注意,product_version可以只是一個換行符,因此最好在讀取文件並連接字元串後去掉 (strip, strip! in Ruby) 尾隨的換行符。

因此,放置所有條件並檢查現有文件並讀取文件以獲取模型資訊可能是有意義的。

引用自:https://unix.stackexchange.com/questions/574808