1. Overview

Sometimes, it’s important to identify the driver module associated with a specific device. It can be useful for troubleshooting, updating drivers, or understanding the underlying hardware configuration.

In this tutorial, we’ll explore several techniques to identify the drivers associated with a device. First, we’ll approach this problem manually through sysfs. Afterward, we’ll use various utilities to make this process easier.

2. sysfs

sysfs is a virtual file system in Linux that contains device and driver information. It offers a structured interface to modify information regarding devices and drivers in the kernel.

2.1. Find Major and Minor Versions of a Device

We can navigate the sysfs file system to find the drivers for a specific device. However, we’ll need to find the major and minor numbers of a device first. For that purpose, we’ll enlist the items inside the /dev directory.

As an example, we’ll find the major and minor versions of a virtual disk:

$ ls -l /dev/vda
brw-rw---- 1 root disk 252, 0 Jun 21 17:06 /dev/vda

In this output, the major and minor numbers are 252 and 0, respectively. The major and minor numbers are used to uniquely identify devices on Linux. The major number identifies the type of device driver associated with a device. On the other hand, the minor number distinguishes between individual devices of the same type.

2.2. Finding Drivers for a Device

Now, we’ve got our major and minor numbers for the device. We can now check the driver by navigating to /sys/dev/block/<major>:<minor>/device and checking the symlink of the driver file. For non-block devices, there is the /sys/dev/char directory.

Since /dev/vda is a block device, we’ll use /sys/dev/block/<major>:<minor>/device/driver using readlink:

$ readlink /sys/dev/block/252\:0/device/driver
../../../../bus/virtio/drivers/virtio_blk

As we can see, readlink leads to the actual driver in use for that device. In case we’re not sure whether the device is a block or character device, we can simply use a wildcard “*“:

$ readlink /sys/dev/*/252\:0/device/driver
../../../../bus/virtio/drivers/virtio_blk

Alternatively, we can access the block devices directly through /sys/block as well:

$ readlink /sys/block/vda/device/driver
../../../../bus/virtio/drivers/virtio_blk

2.3. Finding All In-Use Drivers

In addition to finding drivers for a single device, we can also list all the available drivers for devices using wildcards:

$ ls -l /sys/dev/*/*/device/driver
lrwxrwxrwx 1 root root 0 Jun 21 17:06 /sys/dev/block/11:0/device/driver -> ../../../../../../../bus/scsi/drivers/sr
lrwxrwxrwx 1 root root 0 Jun 21 17:06 /sys/dev/block/2:0/device/driver -> ../../../bus/platform/drivers/floppy
lrwxrwxrwx 1 root root 0 Jun 21 17:06 /sys/dev/block/252:0/device/driver -> ../../../../bus/virtio/drivers/virtio_blk
lrwxrwxrwx 1 root root 0 Jun 21 17:06 /sys/dev/char/21:0/device/driver -> ../../../../../../../bus/scsi/drivers/sr
lrwxrwxrwx 1 root root 0 Jun 21 17:06 /sys/dev/char/226:0/device/driver -> ../../../bus/pci/drivers/virtio-pci
lrwxrwxrwx 1 root root 0 Jun 21 17:06 /sys/dev/char/226:128/device/driver -> ../../../bus/pci/drivers/virtio-pci
lrwxrwxrwx 1 root root 0 Jun 21 17:06 /sys/dev/char/240:0/device/driver -> ../../../../../../../bus/hid/drivers/hid-generic
lrwxrwxrwx 1 root root 0 Jun 21 17:06 /sys/dev/char/243:0/device/driver -> ../../../../../../../bus/scsi/drivers/sr
lrwxrwxrwx 1 root root 0 Jun 21 17:06 /sys/dev/char/248:0/device/driver -> ../../../bus/pnp/drivers/rtc_cmos
lrwxrwxrwx 1 root root 0 Jun 21 17:06 /sys/dev/char/29:0/device/driver -> ../../../bus/pci/drivers/virtio-pci
...

3. udevadm

udevadm is a utility that allows us to manage and inspect the udev subsystem. It provides information about devices, rules, and events. It’s part of the systemd package, so it should be installed on most Linux distributions.

Here’s the general syntax for finding information about a device:

$ udevadm info -a -n <device>

Let’s break this down:

  • info is used to print information about a device
  • -a walks along the chain of parent devices and prints all matching keys
  • -n specifies node or symlink name for attribute walk

As an example, let’s print out the attributes of /dev/vda:

$ udevadm info -a -n /dev/vda
  looking at device '/devices/pci0000:00/0000:00:04.0/virtio2/block/vda':
    KERNEL==vda
    SUBSYSTEM==block
    DRIVER==
    ATTR{alignment_offset}==0
    ATTR{cache_type}==write back
    ATTR{capability}==0
    ATTR{discard_alignment}==0
    ATTR{diskseq}==20
    ATTR{events}==
    ATTR{events_async}==
...

However, we’re interested in the drivers for the device. So, we’ll grep that info instead:

$ udevadm info -a -n /dev/vda | grep -oP 'DRIVERS?=="\K[^"]+'
virtio_blk
virtio-pci

4. lspci

lspci displays information about the PCI buses and devices connected to them. It provides detailed information about the hardware devices present in the system.

Let’s list the devices that are currently in use along with their drivers:

$ lspci -k
00:00.0 Host bridge: Intel Corporation 440FX - 82441FX PMC [Natoma] (rev 02)
	Subsystem: Red Hat, Inc. Qemu virtual machine
00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II]
	Subsystem: Red Hat, Inc. Qemu virtual machine
00:01.1 IDE interface: Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II]
	Subsystem: Red Hat, Inc. Qemu virtual machine
	Kernel driver in use: ata_piix
	Kernel modules: pata_acpi
00:01.2 USB controller: Intel Corporation 82371SB PIIX3 USB [Natoma/Triton II] (rev 01)
	Subsystem: Red Hat, Inc. QEMU Virtual Machine
	Kernel driver in use: uhci_hcd
00:01.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 03)
	Subsystem: Red Hat, Inc. Qemu virtual machine
	Kernel driver in use: piix4_smbus
	Kernel modules: i2c_piix4
00:02.0 VGA compatible controller: Red Hat, Inc. Virtio GPU (rev 01)
	Subsystem: Red Hat, Inc. Virtio GPU
	Kernel driver in use: virtio-pci
00:03.0 Ethernet controller: Red Hat, Inc. Virtio network device
	Subsystem: Red Hat, Inc. Virtio network device
	Kernel driver in use: virtio-pci
00:04.0 SCSI storage controller: Red Hat, Inc. Virtio block device
	Subsystem: Red Hat, Inc. Virtio block device
	Kernel driver in use: virtio-pci

Notably, not only does it print the kernel driver in use but also the kernel modules if they’re available for the devices.

Alternatively, for more verbose output, we can use the -vv switch:

$ lspci -vv > lspci-output.txt

5. Alternative: lshw

lshw provides detailed information about the hardware components of a Linux system.

We can use lshw to print out information about a specific class of devices. For instance, let’s print out detailed information about our virtual disk:

$ sudo lshw -class storage | sed -n '/*-scsi/,$p'
  *-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:11 ioport:c000(size=128) memory:febd2000-febd2fff memory:fe808000-fe80bfff

Let’s break this down:

  • -class specifies the class of devices that we want to print details about
  • storage is a class associated with storage components of the system
  • sed matches the *-scsi pattern to print out text after the matched line

In the output, we can see the driver associated with the device in the configuration field.

6. Conclusion

In this article, we learned how to check for drivers associated with a device in Linux. For this purpose, we explored different approaches, such as using the sysfs virtual file system.

Moreover, we also used a few utilities, including udevadm, lspci, and lshw, to make this process a bit easier.