Linux 硬體資訊獲取
在linux
上可以通過dmidecode
或是lshw
來獲取硬體資訊,能夠方便的檢視系統配置。
但它們的輸出資訊過多,解析起來有些麻煩,另外lshw
對usb
介面的網絡卡支援不好,顯示的資訊不夠,
所以在此整理下通過讀檔案或是一些簡單命令來獲取硬體資訊的方法。
DMI
一般情況下核心預設載入了dmi sysfs
,路徑是/sys/class/dmi
。裡面包含了bios
,board
,product
等資訊。
-
Bios
通過命令
ls -l /sys/class/dmi/id/bios_*
可以看到支援的bios
欄位,如下:$ ls -l /sys/class/dmi/id/bios_* -r--r--r-- 1 root root 4.0K 5月8 17:18 /sys/class/dmi/id/bios_date -r--r--r-- 1 root root 4.0K 5月8 17:18 /sys/class/dmi/id/bios_vendor -r--r--r-- 1 root root 4.0K 5月8 17:18 /sys/class/dmi/id/bios_version
直接讀檔案即可獲取對應值。
-
Board
通過命令
ls -l /sys/class/dmi/id/board_*
可以看到支援的board
欄位,如下:$ ls -l /sys/class/dmi/id/board_* -r--r--r-- 1 root root 4.0K 5月8 08:45 /sys/class/dmi/id/board_asset_tag -r--r--r-- 1 root root 4.0K 5月8 08:45 /sys/class/dmi/id/board_name -r-------- 1 root root 4.0K 5月8 08:45 /sys/class/dmi/id/board_serial -r--r--r-- 1 root root 4.0K 5月8 08:43 /sys/class/dmi/id/board_vendor -r--r--r-- 1 root root 4.0K 5月8 08:45 /sys/class/dmi/id/board_version
直接讀檔案即可獲取對應值,但有些檔案需要
root
許可權。 -
Product
通過命令
ls -l /sys/class/dmi/id/product_*
可以看到支援的product
欄位,如下:$ ls -l /sys/class/dmi/id/product_* -r--r--r-- 1 root root 4.0K 5月8 08:45 /sys/class/dmi/id/product_family -r--r--r-- 1 root root 4.0K 5月8 08:43 /sys/class/dmi/id/product_name -r-------- 1 root root 4.0K 5月8 08:45 /sys/class/dmi/id/product_serial -r--r--r-- 1 root root 4.0K 5月8 17:12 /sys/class/dmi/id/product_sku -r-------- 1 root root 4.0K 5月8 08:45 /sys/class/dmi/id/product_uuid -r--r--r-- 1 root root 4.0K 5月8 08:45 /sys/class/dmi/id/product_version
直接讀檔案即可獲取對應值,但有些檔案需要
root
許可權。其中
product_uuid
可作為機器的唯一ID
。
CPU
通過讀取檔案/proc/cpuinfo
可獲取cpu
的資訊,一般model name
欄位為cpu
名稱,如:
$ cat /proc/cpuinfo|grep 'model name' model name: Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz model name: Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz model name: Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz model name: Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz
但在龍芯,申威上可能不是這個欄位,需要根據檔案內容確定。
Memory
通過讀取檔案/proc/meminfo
可獲取記憶體總大小,欄位是MemTotal
,如:
$ cat /proc/meminfo |grep MemTotal MemTotal:7860064 kB
對於記憶體廠商等資訊咱還未找到獲取方法,待以後補全。
Disk
硬碟資訊這裡使用lsblk
來獲取,通過指定它的引數來獲取,如:
$ lsblk -J -bno NAME,SERIAL,TYPE,SIZE,VENDOR,MODEL,MOUNTPOINT { "blockdevices": [ {"name": "sda", "serial": "TF0500WE0GAV0V", "type": "disk", "size": "500107862016", "vendor": "ATA", "model": "HGST HTS725050A7", "mountpoint": null, "children": [ {"name": "sda1", "serial": null, "type": "part", "size": "4294967296", "vendor": null, "model": null, "mountpoint": "/boot"}, {"name": "sda2", "serial": null, "type": "part", "size": "4294967296", "vendor": null, "model": null, "mountpoint": "[SWAP]"}, {"name": "sda3", "serial": null, "type": "part", "size": "1024", "vendor": null, "model": null, "mountpoint": null}, {"name": "sda5", "serial": null, "type": "part", "size": "107374182400", "vendor": null, "model": null, "mountpoint": "/Data"}, {"name": "sda6", "serial": null, "type": "part", "size": "64424509440", "vendor": null, "model": null, "mountpoint": "/"} ] } ] }
引數的含義通過lsblk -h
命令檢視。
只有type
為disk
時才表示為一塊硬碟,其它如loop
則應該過濾掉。每塊硬碟中的children
表示它下面的分割槽,通過mountpoint
可確定硬碟在此係統上的使用情況。
Network
這裡是先獲取系統上的網路介面,這包括了物理網絡卡和虛擬網絡卡(如docker
建立的)。
lo
dummy, veth, vboxnet, vmnet, vmxnet, vmxnet2, vmxnet3
的網絡卡, 虛擬機器中的bridge
型別的網絡卡
如果網絡卡介面同時存在於/sys/class/net/
和/sys/devices/virtual/net/
中,則需要過濾掉。
接下來分別給出網絡卡資訊獲取的方法:
-
Interface Name
即是上面的目錄下的子目錄名
-
Mac Address
讀取檔案
/sys/class/net/<iface name>/address
可得到 -
IP
通過呼叫
ioctl
來獲取指定iface name
的ip
,程式碼大致如下:char* get_ip_for_iface(char *iface) { int fd; struct ifreq ifr; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd == -1) { fprintf(stderr, "open socket failed: %s", strerror(errno)); return; } // must init ifr memset(&ifr, 0, sizeof(ifr)); ifr.ifr_addr.sa_family = AF_INET; strncpy(ifr.ifr_name, name.c_str(), IFNAMSIZ - 1); ioctl(fd, SIOCGIFADDR, &ifr); close(fd); char *c_addr = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr); char *ip = calloc(strlen(c_addr)+1, sizeof(char)); memcpy(ip, c_addr, strlen(c_addr)); return ip; }
ipv6
的暫未測試。 -
Model
網絡卡一般在
pci
介面上,但也有些實在usb
介面上,要分別獲取。不過都要先讀取檔案
/sys/class/net/enp0s25/device/uevent
,然後分別處理。-
pci
uevent
內容如:DRIVER=e1000e PCI_CLASS=20000 PCI_ID=8086:1502 PCI_SUBSYS_ID=17AA:21F3 PCI_SLOT_NAME=0000:00:19.0 MODALIAS=pci:v00008086d00001502sv000017AAsd000021F3bc02sc00i00
取到其中的
PCI_SLOT_NAME
,然後執行lspci -k -s <PCI_SLOT_NAME>
來獲取model
資訊,如:$ lspci -k -s 0000:00:19.0 00:19.0 Ethernet controller: Intel Corporation 82579LM Gigabit Network Connection (Lewisville) (rev 04) Subsystem: Lenovo 82579LM Gigabit Network Connection Kernel driver in use: e1000e Kernel modules: e1000e
其中
Subsystem
之後的即是model
資訊。 -
usb
uevent
內容如:DEVTYPE=usb_interface DRIVER=ath9k_htc PRODUCT=cf3/9271/108 TYPE=255/255/255 INTERFACE=255/0/0 MODALIAS=usb:v0CF3p9271d0108dcFFdscFFdpFFicFFisc00ip00in00
取到其中的
PRODUCT
,然後將/
替換為:
,然後執行
lsusb -d <product>
來獲取model
資訊,如:# 可以不要最後的 '108' $ lsusb -d cf3:9271:108 Bus 001 Device 007: ID 0cf3:9271 Atheros Communications, Inc. AR9271 802.11n
其中
Subsystem
之後的即是model
資訊。
-
Bluetooth
在/sys/class/bluetooth/
下是藍芽裝置,與網絡卡
一樣,根據/sys/class/bluetooth/<hciX>/device/uevent
的內容使用lspci
或lsusb
來獲取model
資訊。
如:
$ cat /sys/class/bluetooth/hci0/device/uevent DEVTYPE=usb_interface DRIVER=btusb PRODUCT=a5c/21e6/112 TYPE=255/1/1 INTERFACE=255/1/1 MODALIAS=usb:v0A5Cp21E6d0112dcFFdsc01dp01icFFisc01ip01in00
這就是一個usb
介面的裝置,所以使用lsusb
來獲取model
資訊,如:
$ lsusb -d a5c:21e6:112 Bus 001 Device 003: ID 0a5c:21e6 Broadcom Corp. BCM20702 Bluetooth 4.0 [ThinkPad]
Graphic
顯示卡資訊在/sys/class/drm/
下,裡面還包含了顯示卡支援輸出介面,但只有card+integer
組成的目錄才是顯示卡的,如本機的資訊:
$ ls /sys/class/drm/ card0@card0-DP-1@card0-DP-2@card0-DP-3@card0-HDMI-A-1@card0-HDMI-A-2@card0-HDMI-A-3@card0-LVDS-1@card0-VGA-1@renderD128@version
根據輸出可知只有一塊顯示卡card0
,通過讀取檔案card0/device/uevent
獲取裝置型別,然後同網絡卡
一樣查詢model
資訊,如:
$ cat /sys/class/drm/card0/device/uevent DRIVER=i915 PCI_CLASS=30000 PCI_ID=8086:0166 PCI_SUBSYS_ID=17AA:21FA PCI_SLOT_NAME=0000:00:02.0 MODALIAS=pci:v00008086d00000166sv000017AAsd000021FAbc03sc00i00 $ lspci -k -s 0000:00:02.0 00:02.0 VGA compatible controller: Intel Corporation 3rd Gen Core processor Graphics Controller (rev 09) Subsystem: Lenovo 3rd Gen Core processor Graphics Controller Kernel driver in use: i915 Kernel modules: i915
另外/sys/class/hwmon/
和/sys/class/graphics/
下有當前使用中的顯示卡裝置,也是對應子目錄下的device/uevent
來獲取資訊。
若無device
目錄或是device/uevent
中的內容既沒有pci
資訊也沒有usb
資訊,則過濾掉,有就如下所示獲取:
-
hwmon
$ cat /sys/class/hwmon/hwmon2/device/uevent DRIVER=nouveau PCI_CLASS=30000 PCI_ID=10DE:0A75 PCI_SUBSYS_ID=17AA:3957 PCI_SLOT_NAME=0000:02:00.0 MODALIAS=pci:v000010DEd00000A75sv000017AAsd00003957bc03sc00i00 $ lspci -k -s 0000:02:00.0 02:00.0 VGA compatible controller: NVIDIA Corporation GT218M [GeForce 310M] (rev a2) Subsystem: Lenovo GT218M [GeForce 310M] Kernel driver in use: nouveau Kernel modules: nouveau
-
graphics
$ cat /sys/class/graphics/fb0/device/uevent DRIVER=i915 PCI_CLASS=30000 PCI_ID=8086:0166 PCI_SUBSYS_ID=17AA:21FA PCI_SLOT_NAME=0000:00:02.0 MODALIAS=pci:v00008086d00000166sv000017AAsd000021FAbc03sc00i00 $ lspci -k -s 0000:00:02.0 00:02.0 VGA compatible controller: Intel Corporation 3rd Gen Core processor Graphics Controller (rev 09) Subsystem: Lenovo 3rd Gen Core processor Graphics Controller Kernel driver in use: i915 Kernel modules: i915
Display Monitor
顯示器的資訊目前是從edid
中獲取,先確定顯示器連線的顯示卡埠,然後使用edid-decode
(需要安裝)解析其的edid
檔案,就可得到詳細資訊。
如本機是card0-LVDS-1
:
$ cat /sys/class/drm/card0-LVDS-1/edid|edid-decode Extracted contents: header:00 ff ff ff ff ff ff 00 serial number:06 af 6c 10 00 00 00 00 00 14 version:01 04 basic params:90 1c 10 78 02 chroma info:20 e5 92 55 54 92 28 25 50 54 established:00 00 00 standard:01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 descriptor 1:12 1b 56 58 50 00 19 30 30 20 36 00 15 9c 10 00 00 18 descriptor 2:00 00 00 0f 00 00 00 00 00 00 00 00 00 00 00 00 00 20 descriptor 3:00 00 00 fe 00 41 55 4f 0a 20 20 20 20 20 20 20 20 20 descriptor 4:00 00 00 fe 00 42 31 32 35 58 57 30 31 20 56 30 20 0a extensions:00 checksum:ec Manufacturer: AUO Model 106c Serial Number 0 Made week 0 of 2010 EDID version: 1.4 Digital display 6 bits per primary color channel Digital interface is not defined Maximum image size: 28 cm x 16 cm Gamma: 2.20 Supported color formats: RGB 4:4:4 First detailed timing is preferred timing Established timings supported: Standard timings supported: Detailed mode: Clock 69.300 MHz, 277 mm x 156 mm 1366 1414 1446 1454 hborder 0 768771777793 vborder 0 -hsync -vsync Manufacturer-specified data, tag 15 ASCII string: AUO ASCII string: B125XW01 Checksum: 0xec (valid) EDID block does NOT conform to EDID 1.3! Missing name descriptor Missing monitor ranges Detailed block string not properly terminated
Sound
音效卡裝置在/sys/class/sound
目錄下,目錄名一般是card+integer
組成,如本機的資訊:
$ ls /sys/class/sound/ card0@controlC0@hwC0D0@hwC0D3@pcmC0D0c@pcmC0D0p@pcmC0D3p@pcmC0D7p@pcmC0D8p@timer@
就只有一塊音效卡card0
,通過讀取檔案card0/device/uevent
獲取裝置型別,然後同網絡卡
一樣查詢model
資訊,如:
$ cat /sys/class/sound/card0/device/uevent DRIVER=snd_hda_intel PCI_CLASS=40300 PCI_ID=8086:1E20 PCI_SUBSYS_ID=17AA:21FA PCI_SLOT_NAME=0000:00:1b.0 MODALIAS=pci:v00008086d00001E20sv000017AAsd000021FAbc04sc03i00 $ lspci -k -s 0000:00:1b.0 00:1b.0 Audio device: Intel Corporation 7 Series/C216 Chipset Family High Definition Audio Controller (rev 04) Subsystem: Lenovo 7 Series/C216 Chipset Family High Definition Audio Controller Kernel driver in use: snd_hda_intel Kernel modules: snd_hda_intel
Input/Output Device
輸入裝置的資訊可以從/proc/bus/input/devices
檔案中獲取,如:
I: Bus=0019 Vendor=0000 Product=0005 Version=0000 N: Name="Lid Switch" P: Phys=PNP0C0D/button/input0 S: Sysfs=/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0D:00/input/input0 U: Uniq= H: Handlers=event0 B: PROP=0 B: EV=21 B: SW=1 I: Bus=0011 Vendor=0001 Product=0001 Version=ab54 N: Name="AT Translated Set 2 keyboard" P: Phys=isa0060/serio0/input0 S: Sysfs=/devices/platform/i8042/serio0/input/input3 U: Uniq= H: Handlers=sysrq kbd event3 leds B: PROP=0 B: EV=120013 B: KEY=10000 0 0 0 1000402000000 3803078f800d001 feffffdfffefffff fffffffffffffffe B: MSC=10 B: LED=7 I: Bus=0011 Vendor=0002 Product=0007 Version=01b1 N: Name="SynPS/2 Synaptics TouchPad" P: Phys=isa0060/serio1/input0 S: Sysfs=/devices/platform/i8042/serio1/input/input5 U: Uniq= H: Handlers=mouse0 event5 B: PROP=5 B: EV=b B: KEY=e520 10000 0 0 0 0 B: ABS=660800011000003 ...
由於內容太多,這裡就只顯示部分內容。
另外也可通過xinput
命令獲取,如:
$ xinput ⎡ Virtual core pointerid=2[master pointer(3)] ⎜↳ Virtual core XTEST pointerid=4[slavepointer(2)] ⎜↳ SynPS/2 Synaptics TouchPadid=11[slavepointer(2)] ⎜↳ TPPS/2 IBM TrackPointid=12[slavepointer(2)] ⎣ Virtual core keyboardid=3[master keyboard (2)] ↳ Virtual core XTEST keyboardid=5[slavekeyboard (3)] ↳ Power Buttonid=6[slavekeyboard (3)] ↳ Video Busid=7[slavekeyboard (3)] ↳ Sleep Buttonid=8[slavekeyboard (3)] ↳ Integrated Camera: Integrated Cid=9[slavekeyboard (3)] ↳ AT Translated Set 2 keyboardid=10[slavekeyboard (3)] ↳ ThinkPad Extra Buttonsid=13[slavekeyboard (3)]
使用xinput list-prop <device id>
可以檢視裝置的屬性。
Battery
電池資訊可以從/sys/class/power_supply/<name>/uevent
檔案中獲取,電池的名稱一般以BAT
開頭。如本機的資訊:
$ cat /sys/class/power_supply/BAT0/uevent POWER_SUPPLY_NAME=BAT0 POWER_SUPPLY_STATUS=Full POWER_SUPPLY_PRESENT=1 POWER_SUPPLY_TECHNOLOGY=Li-ion POWER_SUPPLY_CYCLE_COUNT=0 POWER_SUPPLY_VOLTAGE_MIN_DESIGN=11100000 POWER_SUPPLY_VOLTAGE_NOW=12226000 POWER_SUPPLY_POWER_NOW=0 POWER_SUPPLY_ENERGY_FULL_DESIGN=57720000 POWER_SUPPLY_ENERGY_FULL=48000000 POWER_SUPPLY_ENERGY_NOW=48000000 POWER_SUPPLY_CAPACITY=100 POWER_SUPPLY_CAPACITY_LEVEL=Full POWER_SUPPLY_MODEL_NAME=45N1023 POWER_SUPPLY_MANUFACTURER=SANYO POWER_SUPPLY_SERIAL_NUMBER=15921
Backlight
/sys/class/backlight/
目錄下的是背光裝置,如顯示屏,背光鍵盤等,可以更改檔案內容來調節這些裝置的亮度。
如:
$ ls /sys/class/backlight/intel_backlight/ actual_brightnessbl_powerbrightnessdevice@max_brightnesspower/subsystem@typeuevent
-
brightness
更改這個檔案可以修改此裝置的當前亮度
-
max_brightness
這個檔案顯示的是此裝置支援的最大亮度
另外背光裝置device
可能只想真實的顯示卡裝置,一般是子目錄中包含video
的。
Camera
/sys/class/video4linux/
下是攝像頭裝置,不同子目錄中的裝置可能是同一個,也是讀取device/uevent
檔案來選擇lspci
或lsusb
獲取裝置資訊,
如:
$ cat /sys/class/video4linux/video0/device/uevent DEVTYPE=usb_interface DRIVER=uvcvideo PRODUCT=5986/2d2/11 TYPE=239/2/1 INTERFACE=14/1/0 MODALIAS=usb:v5986p02D2d0011dcEFdsc02dp01ic0Eisc01ip00in00 $ lsusb -d 5986:2d2:11 Bus 001 Device 004: ID 5986:02d2 Acer, Inc
Printer
印表機應該是在/sys/class/printer
下,資訊獲取方法應該與上文一致,本人手中沒有印表機就不給出示例了。
Fingerprint
指紋的功能目前是由libfprint
專案提供,呼叫其提供的介面來獲取。
如使用qdbus
來獲取:
$ qdbus --system --literal net.reactivated.Fprint /net/reactivated/Fprint/Manager net.reactivated.Fprint.Manager.GetDevices [Argument: ao {}]
輸出可知本機沒有指紋裝置。