探索 Linux 中的硬件设备

LinuxLinuxBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

引言

在本实验中,你将学习在 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
                                 /

以下是各列的简要说明:

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

虽然 lsblk 非常适合快速概览,但 lshw (list hardware) 命令可以提供更详细的信息。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 规则以自动管理设备之前,这尤其有用。

让我们检查主磁盘 /dev/vda 的属性,这是你在上一个步骤中识别出来的。

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

udevadm info -q property -n /dev/vda

输出将是描述设备的系统环境变量列表:

DEVPATH=/devices/pci0000:00/0000:00:04.0/virtio1/block/vda
DEVNAME=/dev/vda
DEVTYPE=disk
MAJOR=252
MINOR=0
SUBSYSTEM=block
USEC_INITIALIZED=xxxxxxxxx
ID_VENDOR=Virtio
ID_MODEL=Block_Device
ID_MODEL_ENC=Block\x20Device\x20\x20\x20\x20\x20\x20\x20
ID_REVISION=
ID_SERIAL=Virtio_Block_Device
ID_SERIAL_SHORT=Block_Device
ID_TYPE=disk
ID_BUS=virtio
ID_PATH=pci-0000:00:04.0-virtio-1
ID_PATH_TAG=pci-0000_00_04_0-virtio-1
DEVLINKS=/dev/disk/by-id/virtio-Block_Device /dev/disk/by-path/pci-0000:00:04.0-virtio-1
TAGS=:systemd:

此输出提供了有价值的详细信息,例如 ID_MODELID_VENDOR 和唯一的 ID_SERIAL。这些属性通常用于编写 udev 规则,这些规则可以应用于特定设备,而不管内核检测到它们的顺序如何。

为了获得更详细的分层视图,你可以使用设备的 sysfs 路径来查询它。首先,找到 /dev/vdasysfs 路径:

udevadm info -q path -n /dev/vda

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

/devices/pci0000:00/0000:00:04.0/virtio1/block/vda

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

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

此命令会产生一个更长的输出,显示块设备本身及其父 virtio 设备和 PCI 控制器的属性。这种详细程度对于高级设备管理和故障排除至关重要。由于输出内容较长,我们在此不展示完整输出,但你可以自行探索。

查看 PCI 和 SCSI 总线层级结构

在本步骤中,你将探索设备如何在系统总线上进行组织。总线是一种在计算机内部组件之间传输数据的通信系统。我们将重点关注两个重要的总线:PCI (Peripheral Component Interconnect) 和 SCSI (Small Computer System Interface)。理解它们的层级结构有助于诊断硬件问题以及了解像你的硬盘驱动器这样的设备是如何连接到系统的。

首先,让我们检查 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 (verbose) 选项。这将包含设备名称和每个设备正在使用的内核驱动程序。由于输出可能很长,我们将通过管道将其传递给 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.1  Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II]
           +-01.3  Intel Corporation 82371AB/EB/MB PIIX4 ACPI
           +-04.0  Red Hat, Inc. Virtio block device
           \-05.0  Red Hat, Inc. Virtio network device

从此输出中,你可以看到连接到 PCI 总线的特定硬件组件,例如 IDE 控制器和 Virtio 设备。

接下来,让我们看看 SCSI 总线。在我们的虚拟环境中,硬盘 /dev/vda 被呈现为 Virtio 块设备,但如果存在任何 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 通道用于链接旧式中断控制器,并且通常是现代硬件上唯一列出的通道。

接下来,让我们检查中断请求 (IRQs)。当硬件设备需要 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 文件系统中的设备信息

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

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

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

ls -l /sys/block

输出显示了块设备,包括 loop 设备和我们的主磁盘 vda。请注意,这些是符号链接,指向它们在 /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 vda -> ../devices/pci0000:00/0000:00:04.0/virtio1/block/vda

现在,让我们检查 vda 设备的目录。此目录包含各种文件,这些文件表示设备的属性。

ls /sys/block/vda

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

alignment_offset  bdi  capability  dev  device  discard_alignment  events  events_async  events_poll_msecs  ext_range  holders  inflight  integrity  power  queue  range  removable  ro  vda1  vda2  vda3  size  slaves  stat  subsystem  trace  uevent

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

cat /sys/block/vda/size

输出将是一个数字:

83886080

此数字表示设备的大小(以 512 字节扇区为单位)。你还可以看到每个分区的目录,例如 vda1vda2vda3,它们包含各自的属性集。

接下来,让我们在 /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

由于我们知道我们的磁盘 /dev/vda 是一个 Virtio 块设备,让我们看看 /sys/bus/virtio/devices 目录。这将列出所有检测到的 Virtio 设备。

ls -l /sys/bus/virtio/devices

输出显示了 Virtio 设备,通过它们的设备 ID 进行标识。这些也是指向主设备树的符号链接。

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 文件系统以探索系统设备及其属性的结构化表示。这让你对如何直接从操作系统查找和解释硬件信息有了全面的了解。