在 Linux 中探索硬件设备

LinuxBeginner
立即练习

介绍

在本实验中,你将学习在 Linux 环境下探索、识别和检查硬件设备的基本技能。你将通过实践操作掌握强大的命令行工具,从而理解操作系统如何与物理组件进行交互。本实验的目标是建立对 Linux 硬件管理的初步理解,这对于系统管理、性能调优和故障排查至关重要。

你将首先使用 lsblklshw 列出块设备,以获取存储设备的概览。随后,你将使用 udevadm 来检查详细的设备属性和规则。接着,实验将引导你查看 PCI 和 SCSI 总线层级结构,以了解设备是如何连接的。最后,你将通过检查 /proc/sys 虚拟文件系统来深入了解底层的系统信息,从而从内核的角度全面查看系统的硬件情况。

使用 lsblk 和 lshw 列出块设备

在这一步中,你将学习如何识别并列出连接到系统的块设备。块设备是按固定大小的数据块传输数据的存储设备,例如硬盘、固态硬盘和 USB 闪存驱动器。我们将使用两个常用命令来实现此目的:lsblklshw

首先,让我们使用 lsblk 命令以树状视图查看所有可用的块设备。该命令通过读取 sysfs 文件系统和 udev 数据库来收集信息。

在终端中执行 lsblk 命令:

lsblk

你将看到类似以下的输出,列出了设备及其包含的任何分区。

NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
loop0    7:0    0  89.4M  1 loop /snap/lxd/31333
loop1    7:1    0     4K  1 loop /snap/bare/5
loop2    7:2    0  63.9M  1 loop /snap/core20/2318
loop3    7:3    0 242.9M  1 loop /snap/firefox/2710
loop4    7:4    0 244.5M  1 loop /snap/firefox/2800
loop5    7:5    0 349.7M  1 loop /snap/gnome-3-38-2004/140
loop6    7:6    0 349.7M  1 loop /snap/gnome-3-38-2004/143
loop7    7:7    0  91.7M  1 loop /snap/gtk-common-themes/1535
loop9    7:9    0    87M  1 loop /snap/lxd/28373
loop10   7:10   0  73.9M  1 loop /snap/core22/2010
loop11   7:11   0  38.8M  1 loop /snap/snapd/21759
loop12   7:12   0  50.9M  1 loop /snap/snapd/24718
loop13   7:13   0  63.8M  1 loop /snap/core20/2599
vda    252:0    0    40G  0 disk
├─vda1 252:1    0     1M  0 part
├─vda2 252:2    0   200M  0 part /boot/efi
└─vda3 252:3    0  39.8G  0 part /var/snap/firefox/common/host-hunspell
                                 /

根据虚拟机镜像的不同,你的主磁盘名称可能是 vdasdanvme0n1。在后续步骤中,请始终使用 lsblk 显示挂载在 / 上的设备名称。

以下是各列的简要说明:

  • NAME: 设备名称。
  • MAJ:MIN: 主设备号和次设备号,内核使用它们来识别设备。
  • RM: 是否为可移动设备(1 表示是,0 表示否)。
  • SIZE: 设备大小。
  • RO: 是否为只读设备(1 表示是,0 表示否)。
  • TYPE: 设备类型(例如 disk、part、loop)。
  • MOUNTPOINTS: 设备在文件系统中的挂载点。

虽然 lsblk 非常适合快速概览,但 lshw(列出硬件)命令可以提供更详细的信息。lshw 命令可能默认未安装,让我们先安装它。

sudo apt-get update && sudo apt-get install -y lshw

安装完成后,你可以使用 lshw 获取特定硬件类别的详细信息。例如,要查看存储控制器(如 SATA 或 NVMe 控制器)的详细信息,可以使用 -class storage 选项。

sudo lshw -class storage

输出将显示存储接口本身的信息。

  *-pnp00:03
       product: PnP device PNP0700
       physical id: 3
       capabilities: pnp
  *-ide
       description: IDE interface
       product: 82371SB PIIX3 IDE [Natoma/Triton II]
       vendor: Intel Corporation
       physical id: 1.1
       bus info: pci@0000:00:01.1
       version: 00
       width: 32 bits
       clock: 33MHz
       capabilities: ide isa_compat_mode bus_master
       configuration: driver=ata_piix latency=0
       resources: irq:0 ioport:1f0(size=8) ioport:3f6 ioport:170(size=8) ioport:376 ioport:c060(size=16)
  *-scsi
       description: SCSI storage controller
       product: Virtio block device
       vendor: Red Hat, Inc.
       physical id: 4
       bus info: pci@0000:00:04.0
       version: 00
       width: 64 bits
       clock: 33MHz
       capabilities: scsi msix bus_master cap_list
       configuration: driver=virtio-pci latency=0
       resources: irq:0 memory:fe000000-fe000fff memory:fe001000-fe001fff

要获取有关分区和逻辑卷的更详细信息(比 lsblk 更详尽),请使用 -class volume 选项。

sudo lshw -class volume

该命令提供了丰富的信息,包括每个分区的逻辑名称、序列号和功能。

  *-volume:0
       description: BIOS Boot partition
       vendor: EFI
       physical id: 1
       bus info: scsi@0:0.0.0,1
       logical name: /dev/vda1
       serial: xxxx-xxxx
       size: 1MiB
       capacity: 1MiB
       capabilities: primary
  *-volume:1
       description: EFI partition
       vendor: EFI
       physical id: 2
       bus info: scsi@0:0.0.0,2
       logical name: /dev/vda2
       serial: XXXX-XXXX
       size: 200MiB
       capacity: 200MiB
       capabilities: boot fat initialized
       configuration: FATs=32 filesystem=fat mount.fstype=vfat mount.options=rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro state=mounted
  *-volume:2
       description: Linux filesystem
       physical id: 3
       bus info: scsi@0:0.0.0,3
       logical name: /dev/vda3
       size: 39GiB
       capacity: 39GiB
       capabilities: primary ext4 initialized
       configuration: filesystem=ext4 lastmountpoint=/ modified=2024-xx-xx mounted=2024-xx-xx state=mounted

通过使用 lsblklshw,你可以获得 Linux 系统存储设备的高层概览以及详细的底层视图。

使用 udevadm 检查设备属性

在上一步中,你学习了如何列出块设备。现在,你将深入了解并使用 udevadm 命令检查这些设备的特定属性。udev 是 Linux 内核的设备管理器,它动态管理 /dev 目录中的设备节点。udevadm 命令是 udev 的控制工具,允许你查询 udev 数据库以获取详细的设备信息。这在创建自定义 udev 规则以自动管理设备之前特别有用。

让我们检查包含根文件系统的主磁盘的属性。首先,识别根分区及其父磁盘:

ROOT_PARTITION=$(findmnt -n -o SOURCE /)
DISK_NAME=$(lsblk -no PKNAME "$ROOT_PARTITION")
echo "$ROOT_PARTITION -> /dev/$DISK_NAME"

要以简单的键值格式显示该磁盘的属性,请执行以下命令。-q property 标志告诉 udevadm 查询数据库以获取设备的所有已知属性,-n "/dev/$DISK_NAME" 指定了设备节点名称。

udevadm info -q property -n "/dev/$DISK_NAME"

输出将是一系列描述该设备的环境变量。你的具体值会有所不同,但输出应如下所示:

DEVPATH=/devices/pci0000:00/0000:00:04.0/nvme/nvme0/nvme0n1
DEVNAME=/dev/nvme0n1
DEVTYPE=disk
MAJOR=259
MINOR=0
SUBSYSTEM=block
USEC_INITIALIZED=xxxxxxxxx
ID_MODEL=Alibaba Cloud Elastic Block Storage
ID_REVISION=1.0
ID_SERIAL=Alibaba_Cloud_Elastic_Block_Storage_xxxxxxxxxxxx
ID_SERIAL_SHORT=xxxxxxxxxxxx
ID_TYPE=disk
ID_PATH=pci-0000:00:04.0-nvme-1
ID_PATH_TAG=pci-0000_00_04_0-nvme-1
DEVLINKS=/dev/disk/by-id/nvme-... /dev/disk/by-path/pci-0000:00:04.0-nvme-1
TAGS=:systemd:

此输出提供了有价值的详细信息,例如 ID_MODELID_PATH 和唯一的 ID_SERIAL。这些属性通常用于编写适用于特定设备的 udev 规则,而无需考虑内核检测到它们的顺序。

为了获得更详细的层级视图,你可以使用设备的 sysfs 路径来查询设备。首先,找到你所选磁盘的 sysfs 路径:

udevadm info -q path -n "/dev/$DISK_NAME"

输出将是设备在 /sys 文件系统中的路径:

/devices/pci0000:00/0000:00:04.0/nvme/nvme0/nvme0n1

现在,将此路径与 -a(属性遍历)和 -p(路径)标志一起使用,以查看从父设备到指定设备的所有设备属性。这提供了设备及其父控制器的完整视图。

udevadm info -a -p "$(udevadm info -q path -n "/dev/$DISK_NAME")"

该命令会产生很长的输出,显示块设备本身及其父存储控制器和 PCI 设备的属性。这种详细程度对于高级设备管理和故障排查至关重要。由于篇幅原因,我们不在此展示完整输出,但你可以自行探索。

查看 PCI 和 SCSI 总线层级结构

在这一步中,你将探索设备是如何在系统总线上组织的。总线是一种在计算机内部组件之间传输数据的通信系统。我们将重点关注两个重要的总线:PCI(外设组件互连标准)和 SCSI(小型计算机系统接口)。了解它们的层级结构有助于诊断硬件问题,并理解硬盘等设备是如何连接到系统的。

首先,让我们检查 PCI 总线,它连接了主板上的大多数高速组件。lspci 命令是此任务的标准工具。提供此命令的 pciutils 软件包通常是预装的,但我们将确保它已安装。

sudo apt-get update && sudo apt-get install -y pciutils

现在,要以树状结构显示 PCI 总线层级,请使用带有 -t 选项的 lspci 命令。

lspci -t

输出将如下所示,显示总线和设备之间的连接:

-[0000:00]-+-00.0
           +-01.0
           +-01.1
           +-01.3
           +-04.0
           \-05.0

这棵树显示了连接关系,但没有显示设备具体是什么。为了使其更有用,请添加 -v(详细)选项。这将包含设备名称以及每个设备正在使用的内核驱动程序。由于输出可能很长,我们将通过管道将其传递给 more,以便你可以滚动查看。按空格键向下滚动,按 q 退出。

lspci -tv | more

输出将更加详细:

-[0000:00]-+-00.0  Intel Corporation 440FX - 82441FX PMC [Natoma]
           +-01.0  Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II]
           +-01.3  Intel Corporation 82371AB/EB/MB PIIX4 ACPI
           +-02.0  Cirrus Logic GD 5446
           +-03.0  Red Hat, Inc. Virtio console
           +-04.0  Intel Corporation QEMU NVM Express Controller
           +-05.0  Red Hat, Inc. Virtio network device
           \-06.0  Red Hat, Inc. Virtio memory balloon

从该输出中,你可以看到连接到 PCI 总线的特定硬件组件,例如 NVMe 存储控制器和其他虚拟设备。

接下来,让我们看看 SCSI 总线。在此虚拟机中,主磁盘可能是通过 NVMe 而不是 Virtio 或 SCSI 暴露的,但你仍然可以探索存在的任何 SCSI 设备。查看此信息的一种用户友好方式是使用 systool 命令。让我们安装提供该命令的 sysfsutils 软件包。

sudo apt-get install -y sysfsutils

现在,使用带有 -b scsi 选项的 systool 来列出 SCSI 总线上的设备。

systool -b scsi

该命令将显示连接到 SCSI 总线的设备:

Bus = "scsi"

  Device = "host0"
  Device = "host1"

在 /proc 中检查底层系统资源

在这一步中,你将深入研究 /proc 虚拟文件系统以检查底层系统资源。/proc 文件系统不包含磁盘上的真实文件;相反,它是内核数据结构的直接接口。通过读取 /proc 中的文件,你可以实时查看系统如何管理 DMA 通道、中断和 I/O 端口等硬件资源。

首先,让我们看看直接内存访问(DMA)通道。DMA 允许某些硬件设备直接访问系统内存,而无需 CPU 参与,从而提高了性能。要查看当前正在使用的 DMA 通道,你可以查看 /proc/dma 文件的内容。

cat /proc/dma

输出通常非常简单,特别是在现代或虚拟化系统上。

 4: cascade

此输出显示了已注册的 DMA 通道。cascade 通道用于链接旧式中断控制器,在现代硬件上通常是唯一列出的通道。

接下来,让我们检查中断请求(IRQ)。当硬件设备需要 CPU 注意时,它会发送中断信号。/proc/interrupts 文件提供了每个 IRQ 号接收到的中断次数的统计信息。

cat /proc/interrupts

输出显示了每个 CPU 核心的中断活动详细分解。

           CPU0
  0:         10   IO-APIC   2-edge      timer
  1:          2   IO-APIC   1-edge      i8042
  8:          1   IO-APIC   8-edge      rtc0
  9:          0   IO-APIC   9-fasteoi   acpi
 11:        ...   IO-APIC  11-fasteoi   ata_piix, uhci_hcd
 12:          4   IO-APIC  12-edge      i8042
NMI:          0   Non-maskable interrupts
LOC:      ...   Local timer interrupts
...

各列的含义如下:

  • 第一列是 IRQ 号。
  • CPU0 列(如果存在其他 CPU 列,则包括它们)显示了该 CPU 核心处理的中断次数。
  • 最后一列显示与该中断关联的设备驱动程序名称。这对于调试硬件冲突非常有用。

最后,让我们看看 I/O 端口。这些是 CPU 用来直接与硬件设备通信的特殊内存地址。/proc/ioports 文件列出了当前为设备保留的 I/O 端口区域。由于列表可能很长,最好使用 less 查看。你可以使用箭头键滚动,按 q 退出。

less /proc/ioports

你将看到内存范围列表以及使用它们的设备。

0000-0cf7 : PCI Bus 0000:00
  0020-0021 : PIC1
  0040-0043 : timer0
  0050-0053 : timer1
  0060-0060 : keyboard
  0064-0064 : keyboard
  0070-0077 : rtc0
  0080-008f : dma page reg
  00a0-00a1 : PIC2
  00c0-00df : dma2
  00f0-00ff : fpu
0170-0177 : 0000:00:01.1
  0170-0177 : ata_piix
01f0-01f7 : 0000:00:01.1
  01f0-01f7 : ata_piix
...

此输出显示了内存地址范围以及声明该范围的设备。例如,你可以看到键盘、定时器以及我们在上一步中看到的 ata_piix 磁盘控制器的范围。

在 /sys 文件系统中探索设备信息

在最后一步中,你将探索挂载在 /sys 上的 sysfs 文件系统。虽然 /proc 提供了有关进程和某些硬件资源的信息,但 /sys 提供了系统设备模型的更结构化视图。它导出了内核对象、设备和驱动程序的层级表示。你在之前步骤中使用过的许多工具(如 lsblkudevadm)都是通过读取 /sys 来获取信息的。

首先,让我们看看块设备是如何表示的。/sys/block 目录包含系统已知的每个块设备的子目录。

列出 /sys/block 的内容以查看设备:

ls -l /sys/block

输出显示了块设备,包括循环设备(loop devices)和你的主磁盘。请注意,这些是指向它们在 /sys/devices 层级中实际位置的符号链接。

total 0
lrwxrwxrwx 1 root root 0 Jan  1 00:00 loop0 -> ../devices/virtual/block/loop0
lrwxrwxrwx 1 root root 0 Jan  1 00:00 loop1 -> ../devices/virtual/block/loop1
...
lrwxrwxrwx 1 root root 0 Jan  1 00:00 nvme0n1 -> ../devices/pci0000:00/0000:00:04.0/nvme/nvme0/nvme0n1

再次找到根文件系统的父磁盘,然后检查该目录。该目录包含表示设备属性的各种文件。

ROOT_PARTITION=$(findmnt -n -o SOURCE /)
DISK_NAME=$(lsblk -no PKNAME "$ROOT_PARTITION")
ls /sys/block/"$DISK_NAME"

你将看到文件和目录列表:

alignment_offset  diskseq  holders  nvme0n1p2  ro       uevent
bdi               events   inflight nvme0n1p3  size     wwid
capability        events_async integrity power  slaves
dev               events_poll_msecs mq    queue  stat
device            ext_range nsid    range  subsystem
discard_alignment hidden    nvme0n1p1 removable trace

每个文件都保存着特定的信息。例如,要查找磁盘大小,你可以读取 size 文件。

cat /sys/block/"$DISK_NAME"/size

输出将是一个数字:

83886080

此数字表示以 512 字节扇区为单位的设备大小。你还可以看到每个分区的目录,例如 nvme0n1p1nvme0n1p2nvme0n1p3,它们包含各自的属性集。在其他镜像上,分区名称可能使用不同的设备前缀。

接下来,让我们探索设备是如何在 /sys/bus 目录中按总线类型组织的。这提供了一种导航设备层级的替代方法。

ls /sys/bus

你将看到内核支持的不同总线类型列表:

acpi  amba  clocksource  container  cpu  event_source  hid  i2c  i8042  ide  mdio_bus  memory  pci  pci_express  platform  scsi  serial  serio  soc  system  usb  virtio  workqueue

即使你的存储磁盘不是 Virtio 块设备,虚拟机可能仍然会暴露其他 Virtio 设备。让我们查看 /sys/bus/virtio/devices 目录以列出它们。

ls -l /sys/bus/virtio/devices

输出显示了由设备 ID 标识的 Virtio 设备。这些也是指向主设备树的符号链接。

total 0
lrwxrwxrwx 1 root root 0 Jan  1 00:00 virtio0 -> ../../../devices/pci0000:00/0000:00:05.0/virtio0
lrwxrwxrwx 1 root root 0 Jan  1 00:00 virtio1 -> ../../../devices/pci0000:00/0000:00:04.0/virtio1

通过探索 /sys,你可以直接访问更高级工具用于报告系统硬件的原始数据。这是理解 Linux 内核如何查看和组织设备的一种强大方式。

总结

在本实验中,你学习了如何在 Linux 环境下识别和检查硬件设备。你练习了使用 lsblk 命令以树状格式列出块设备及其分区,并使用 lshw 命令获取更详细的硬件规格。实验还涵盖了使用 udevadm 检查由 udev 子系统管理的设备属性,以及如何查看系统的 PCI 和 SCSI 总线层级结构。

此外,你还探索了内核通过伪文件系统呈现的底层信息。你检查了 /proc 文件系统以查看原始系统资源数据,并导航了 /sys 文件系统以探索系统设备及其属性的结构化表示。这为你提供了关于如何直接从操作系统中查找和解释硬件信息的全面理解。