Explore Hardware Devices in Linux

CompTIABeginner
Practice Now

Introduction

In this lab, you will learn the essential skills to explore, identify, and inspect hardware devices within a Linux environment. You will gain hands-on experience with powerful command-line utilities to understand how the operating system interacts with physical components. The objective is to build a foundational understanding of hardware management in Linux, which is crucial for system administration, performance tuning, and troubleshooting.

You will start by listing block devices using lsblk and lshw to get an overview of storage. Following that, you will use udevadm to inspect detailed device properties and rules. The lab will then guide you through viewing the PCI and SCSI bus hierarchies to see how devices are connected. Finally, you will delve into low-level system information by examining the /proc and /sys virtual filesystems, giving you a comprehensive view of your system's hardware from the kernel's perspective.

List Block Devices with lsblk and lshw

In this step, you will learn how to identify and list the block devices connected to your system. Block devices are storage devices that transfer data in fixed-size blocks, such as hard drives, solid-state drives, and USB flash drives. We will use two common commands for this purpose: lsblk and lshw.

First, let's use the lsblk command to get a tree-like view of all available block devices. This command reads the sysfs filesystem and udev database to gather information.

Execute the lsblk command in your terminal:

lsblk

You will see an output similar to this, listing the devices and any partitions they contain.

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
                                 /

Here's a brief explanation of the columns:

  • NAME: The device name.
  • MAJ:MIN: The major and minor device numbers, used by the kernel to identify the device.
  • RM: Removable device (1 if yes, 0 if no).
  • SIZE: The size of the device.
  • RO: Read-only device (1 if yes, 0 if no).
  • TYPE: The type of device (e.g., disk, part, loop).
  • MOUNTPOINTS: Where the device is mounted in the filesystem.

While lsblk is great for a quick overview, the lshw (list hardware) command can provide much more detailed information. The lshw command may not be installed by default. Let's install it first.

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

Once the installation is complete, you can use lshw to get detailed information about specific classes of hardware. For example, to see details about storage controllers (like your SATA or NVMe controller), you can use the -class storage option.

sudo lshw -class storage

The output will show information about the storage interface itself.

  *-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

To get more detailed information about the partitions and logical volumes, which is comparable but more detailed than lsblk, use the -class volume option.

sudo lshw -class volume

This command provides a wealth of information, including logical names, serial numbers, and capabilities of each partition.

  *-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

By using lsblk and lshw, you can get both a high-level and a detailed, low-level view of the storage devices on your Linux system.

Inspect Device Properties with udevadm

In the previous step, you learned how to list block devices. Now, you'll dive deeper and inspect the specific properties of these devices using the udevadm command. udev is the device manager for the Linux kernel, which dynamically manages device nodes in the /dev directory. The udevadm command is the control tool for udev, allowing you to query the udev database for detailed device information. This is particularly useful before creating custom udev rules to manage devices automatically.

Let's inspect the properties of the main disk, /dev/vda, which you identified in the previous step.

To display the properties of /dev/vda in a simple key-value format, execute the following command. The -q property flag tells udevadm to query the database for all known properties of the device, and -n /dev/vda specifies the device node name.

udevadm info -q property -n /dev/vda

The output will be a list of environment variables that describe the device:

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:

This output provides valuable details such as the ID_MODEL, ID_VENDOR, and a unique ID_SERIAL. These properties are often used to write udev rules that apply to a specific device, regardless of the order it was detected by the kernel.

For an even more detailed, hierarchical view, you can query the device using its sysfs path. First, find the sysfs path for /dev/vda:

udevadm info -q path -n /dev/vda

The output will be the device's path within the /sys filesystem:

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

Now, use this path with the -a (attribute walk) and -p (path) flags to see all device attributes from the parent devices up to the specified device. This gives a complete picture of the device and its parent controllers.

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

This command produces a much longer output, showing attributes for the block device itself, as well as its parent virtio device and PCI controller. This level of detail is essential for advanced device management and troubleshooting. We won't show the full output here due to its length, but feel free to explore it.

View the PCI and SCSI Bus Hierarchy

In this step, you'll explore how devices are organized on system buses. A bus is a communication system that transfers data between components inside a computer. We will focus on two important buses: PCI (Peripheral Component Interconnect) and SCSI (Small Computer System Interface). Understanding their hierarchy helps in diagnosing hardware issues and understanding how devices like your hard drive are connected to the system.

First, let's examine the PCI bus, which connects most of the high-speed components on the motherboard. The lspci command is the standard tool for this. The pciutils package which provides this command is usually pre-installed, but we'll ensure it is.

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

Now, to display the PCI bus hierarchy in a tree-like structure, use the lspci command with the -t option.

lspci -t

The output will look something like this, showing the connections between buses and devices:

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

This tree shows the connections, but not what the devices are. To make it more useful, add the -v (verbose) option. This will include device names and the kernel driver in use for each device. Since the output can be long, we'll pipe it to more so you can scroll through it. Press the spacebar to scroll down and q to quit.

lspci -tv | more

The output will be much more detailed:

-[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

From this output, you can see the specific hardware components connected to the PCI bus, such as the IDE controller and Virtio devices.

Next, let's look at the SCSI bus. In our virtual environment, the hard disk /dev/vda is presented as a Virtio block device, but we can still explore SCSI devices if any are present. A user-friendly way to view this information is with the systool command. Let's install the sysfsutils package that provides it.

sudo apt-get install -y sysfsutils

Now, use systool with the -b scsi option to list devices on the SCSI bus.

systool -b scsi

This command will show the devices attached to the SCSI bus:

Bus = "scsi"

  Device = "host0"
  Device = "host1"

Examine Low-Level System Resources in /proc

In this step, you will delve into the /proc virtual filesystem to inspect low-level system resources. The /proc filesystem doesn't contain real files on disk; instead, it's a direct interface to the kernel's data structures. By reading files in /proc, you can get a real-time look at how the system is managing hardware resources like DMA channels, interrupts, and I/O ports.

First, let's look at Direct Memory Access (DMA) channels. DMA allows certain hardware devices to access system memory directly, without involving the CPU, which improves performance. To see which DMA channels are currently in use, you can view the contents of the /proc/dma file.

cat /proc/dma

The output is typically very simple, especially on modern or virtualized systems.

 4: cascade

This output shows the registered DMA channels. The cascade channel is used to chain older-style interrupt controllers and is often the only one listed on modern hardware.

Next, let's examine interrupt requests (IRQs). When a hardware device needs the CPU's attention, it sends an interrupt signal. The /proc/interrupts file provides statistics on how many interrupts have been received for each IRQ number.

cat /proc/interrupts

The output shows a detailed breakdown of interrupt activity per CPU core.

           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
...

Here's what the columns mean:

  • The first column is the IRQ number.
  • The CPU0 column (and other CPU columns if present) shows the number of interrupts handled by that CPU core.
  • The last column shows the name of the device driver associated with that interrupt. This is very useful for debugging hardware conflicts.

Finally, let's look at I/O ports. These are special memory addresses that the CPU uses to communicate directly with hardware devices. The /proc/ioports file lists the I/O port regions that are currently reserved for devices. Since the list can be long, it's best to view it with less. You can scroll with the arrow keys and press q to exit.

less /proc/ioports

You will see a list of memory ranges and the devices using them.

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
...

This output shows the memory address range and the device that has claimed it. For example, you can see ranges for the keyboard, timers, and the ata_piix disk controller we saw in the previous step.

Explore Device Information in the /sys Filesystem

In this final step, you will explore the sysfs filesystem, mounted at /sys. While /proc provides information about processes and some hardware resources, /sys offers a more structured view of the system's device model. It exports a hierarchical representation of kernel objects, devices, and drivers. Many of the tools you've used in previous steps, like lsblk and udevadm, get their information by reading from /sys.

First, let's look at how block devices are represented. The /sys/block directory contains a subdirectory for each block device known to the system.

List the contents of /sys/block to see the devices:

ls -l /sys/block

The output shows the block devices, including the loop devices and our main disk vda. Notice that these are symbolic links pointing to their actual locations within the /sys/devices hierarchy.

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

Now, let's inspect the directory for the vda device. This directory contains various files that represent the attributes of the device.

ls /sys/block/vda

You will see a list of files and directories:

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

Each file holds a specific piece of information. For example, to find the size of the disk, you can read the size file.

cat /sys/block/vda/size

The output will be a number:

83886080

This number represents the size of the device in 512-byte sectors. You can also see directories for each partition, such as vda1, vda2, and vda3, which contain their own sets of attributes.

Next, let's explore how devices are organized by bus type in the /sys/bus directory. This provides an alternative way to navigate the device hierarchy.

ls /sys/bus

You'll see a list of different bus types supported by the kernel:

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

Since we know our disk /dev/vda is a Virtio block device, let's look inside the /sys/bus/virtio/devices directory. This will list all detected Virtio devices.

ls -l /sys/bus/virtio/devices

The output shows the Virtio devices, identified by their device IDs. These are also symbolic links pointing back to the main device tree.

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

By exploring /sys, you can directly access the raw data that higher-level tools use to report on system hardware. It's a powerful way to understand how the Linux kernel sees and organizes devices.

Summary

In this lab, you learned to identify and inspect hardware devices in a Linux environment. You practiced using the lsblk command to list block devices and their partitions in a tree-like format, and the lshw command to obtain more detailed hardware specifications. The lab also covered using udevadm to inspect device properties managed by the udev subsystem, and how to view the system's bus hierarchies for PCI and SCSI devices.

Furthermore, you explored the low-level information presented by the kernel through pseudo-filesystems. You examined the /proc filesystem to view raw system resource data and navigated the /sys filesystem to explore a structured representation of the system's devices and their attributes. This provided a comprehensive understanding of how to find and interpret hardware information directly from the operating system.