1. Overview

Many Linux commands return information about devices and their drivers. Most of the time, we use these commands to troubleshoot problems. Besides that, we may want to find out the installed drivers in our system.

This tutorial will examine how we can get a list of the installed devices and their corresponding drivers.

2. Hardware Configuration Commands

Some hardware configuration commands return data about any hardware resource. Yet, others deal only with devices on a certain bus like PCI or USB.

Importantly, all commands are best run with sudo, so we get the full output. In addition, most of the commands are pre-installed in popular Linux distributions. In any case, we can install them with the package manager.

2.1. The lshw Command

The lshw tool can provide information about multiple machine hardware components:

  • general system information
  • memory configuration
  • Basic Input/Output System (BIOS) data
  • firmware version
  • mainboard information
  • CPU specifications
  • cache setup
  • bus speeds

We can build lshw from source or simply install it as a package. Critically, among others, the tool also leverages the /proc and /sys pseudo-filesystems.

The -short switch of lshw shows the devices we can get data on:

H/W path          Device      Class          Description
========================================================
                              system         ThinkPad E14
/0                            bus            0666X1
/0/0                          memory         64KiB BIOS
/0/5                          processor      Intel(R) Core(TM) i3-1115G4 CPU @ 3.00GHz
/0/6                          processor      Core i3 (None)
/0/7                          processor      (None)
[...]
/0/44                         processor      (None)
/0/51                         memory         2GiB System Memory
/0/51/0                       memory         2GiB SODIMM DDR4
/0/51/1                       memory         [empty]
[...]
/0/51/7c                      memory         [empty]
/0/100                        bridge         660BX/ZX/DX - 72331BX/ZX/DX Host bridge (AGP disabled)
/0/100/7                      bridge         81161AB/EB/MB PIIX4 ISA
/0/100/7.1        scsi3       storage        81161AB/EB/MB PIIX4 IDE
/0/100/7.1/0.0.0  /dev/cdrom  disk           Virtual CD/ROM
/0/100/7.3                    bridge         81161AB/EB/MB PIIX4 ACPI
/0/100/8                      display        Haswell-ULT Integrated
/0/1                          system         PnP device PNP0b00
[...]
/0/4a             scsi0       storage
/0/4a/0.0.0       /dev/sda    disk           666GB Virtual Disk
/0/4a/0.0.0/1     /dev/sda1   volume         6333MiB EXT4 volume
/0/4a/0.0.0/2     /dev/sda2   volume         12GiB Extended partition
/0/4a/0.0.0/2/5   /dev/sda5   volume         2100MiB EXT4 volume
/0/4a/0.0.0/2/6   /dev/sda6   volume         976MiB Linux swap volume
/0/4a/0.0.0/2/7   /dev/sda7   volume         267MiB EXT4 volume
/0/4a/0.0.0/2/8   /dev/sda8   volume         665Gib EXT4 volume
/1                eth0        network        Ethernet interface

Here, we can see the Class of each device. In fact, the tool has other formats like –**html, -json, and -xml.

Running lshw without options returns all hardware resources. With the -class switch, we can pick specific resources we want to know information about:

$ sudo lshw --class network
  *-network
       description: Ethernet interface
       physical id: 1
       logical name: eth0
       serial: 52:54:00:6b:5b:e6
       size: 10Gbit/s
       capabilities: ethernet physical
       configuration: autonegotiation=off broadcast=yes driver=hv_netvsc duplex=full firmware=N/A ip=172.23.120.189 link=yes multicast=yes speed=10Gbit/s

As can be seen, the –class option shows only a defined class of hardware. Particularly, we printed information about the network card. Moreover, the configuration row contains the name of the driver that our network card uses. In our case, the driver is hv_netvsc.

2.2. The hwinfo Command

The hwinfo command is another tool that prints information about hardware devices.

Invoking hwinfo with no options will return all available hardware resources. Nevertheless, we can filter the output by entering the device type that we’re interested in:

$ sudo hwinfo --network
...
  SysFS ID: /class/net/wlp5s0
  SysFS Device Link: /devices/pci0000:00/0000:00:1c.2/0000:05:00.0
  Hardware Class: network interface
  Model: "Ethernet network interface"
  Driver: "iwl3945"
  Driver Modules: "iwl3945"
  Device File: wlp5s0
...

In the above example, we filtered the output to show network devices only. As a result, we got the device driver of the wireless network card, which is the iwl3945 driver.

2.3. The lspci Command

The lspci command prints information for devices connected to the PCI bus. Although the command doesn’t print the driver when called without options, we can use -k to print the driver:

$ sudo lspci -k
01:00.0 VGA compatible controller: NVIDIA Corporation G73M [GeForce Go 7600] (rev a1)
Subsystem: Toshiba America Info Systems G73M [GeForce Go 7600]
Kernel driver in use: nouveau
Kernel modules: nvidiafb, nouveau

Here, we can see that the command printed the driver used by the display adapter, which is nouveau. Furthermore, the command printed all installed drivers that could be used for this device. In our case, these are the nvidiafb and the nouveau drivers.

We can also use the -v option:

$ sudo lspci -v
...
01:00.0 VGA compatible controller: NVIDIA Corporation G73M [GeForce Go 7600] (rev a1) (prog-if 00 [VGA controller])
Subsystem: Toshiba America Info Systems G73M [GeForce Go 7600]
Flags: bus master, fast devsel, latency 0, IRQ 28
...
Kernel driver in use: nouveau
Kernel modules: nvidiafb, nouveau

Notably, the -v option produces similar output to the -k option concerning kernel drivers.

2.4. The lsusb Command

The lsusb command prints data about USB buses and the devices connected to them. We can run the command with the -t option to get the driver:

$ sudo lsusb -t
...
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M
    |__ Port 2: Dev 2, If 0, Class=Vendor Specific Class, Driver=, 12M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/8p, 480M

Here, the command printed the driver for the second USB device. We see the ehci-pci driver, which is the Linux USB 2.0 driver.

3. The sysfs Pseudo-Filesystem

Linux has a /sys sysfs pseudo-filesystem as an interface to internal kernel data structures, but mainly those that describe hardware. Still, /sys also provides access to information about filesystems, Security-Enhanced Linux (SELinux), modules, and others.

While the similar /proc pseudo-filesystem is a raw UNIX remnant, a first attempt at bringing order to the chaotic reading and interpretation of /dev/mem, /sys takes that a step further.

Despite their overlap, there are perhaps a couple of big differences between /proc and /sys:

  • /sys enforces Linux-specific standards and philosophy while supposedly bringing structure to the concept of /proc
  • /sys and /proc overlap, but /sys usually provides more organized hardware information and drivers instead of exposing direct memory regions

When it comes to hardware, the desktop management interface (DMI) provides a standard source of information about components in a machine. Since its main focus is hardware, sysfs exposes DMI at /sys/class/dmi/id:

$ tree /sys/class/dmi/id
/sys/class/dmi/id
├── bios_date
├── bios_vendor
├── bios_version
├── board_name
├── board_serial
├── board_vendor
├── board_version
├── chassis_asset_tag
├── chassis_serial
├── chassis_type
├── chassis_vendor
├── chassis_version
├── modalias
├── power
│   ├── async
│   ├── autosuspend_delay_ms
│   ├── control
│   ├── runtime_active_kids
│   ├── runtime_active_time
│   ├── runtime_enabled
│   ├── runtime_status
│   ├── runtime_suspended_time
│   └── runtime_usage
├── product_name
├── product_serial
├── product_uuid
├── product_version
├── subsystem -> ../../../../class/dmi
├── sys_vendor
└── uevent

Here, we use the tree command to output the sysfs subtree related to DMI.

Let’s read a value:

$ cat /sys/class/dmi/id/sys_vendor
LENOVO

Of course, for writeable values, we can simply overwrite the appropriate file.

In addition to the above, the sysfs filesystem provides data about drivers.

One way to find the driver of a device is to browse the /class sub-directory where devices are grouped by their type. Let’s find the installed network adapters:

$ ls /sys/class/net
enp7s8  lo  wlp5s0

Here, we list the subdirectory /net to get all network adapters. To find the driver of the wireless adapter, we can search for a driver folder in wlp5s0:

$ sudo readlink  /sys/class/net/wlp5s0/device/driver
../../../../bus/pci/drivers/iwl3945

As we can see, we managed to print the driver used by the wireless card, which is the iwl3945 driver.

4. Kernel Modules

Another critical point is that most Linux drivers are kernel modules. Kernel modules extend kernel functionality, and we can load and unload them as needed.

So, we can use the modinfo command to find driver details:

$ modinfo iwl3945
filename:       /lib/modules/4.4.0-210-generic/kernel/drivers/net/wireless/iwlegacy/iwl3945.ko
firmware:       iwlwifi-3945-2.ucode
license:        GPL
author:         Copyright(c) 2003-2011 Intel Corporation <[email protected]>
version:        in-tree:s
description:    Intel(R) PRO/Wireless 3945ABG/BG Network Connection driver for Linux
srcversion:     59CEE3A5C9D9B5F86295C7E
depends: iwlegacy,mac80211,cfg80211
...

In the above example, we can see some useful properties of the driver like the author, filename, and dependencies.

5. Conclusion

In this tutorial, we learned several commands that we can use to find the driver name of a device. Then, we showed how we can browse the sysfs filesystem to find the drivers. Finally, we used the modinfo command to print the details of a driver.