
How Linux Maps Hardware to Kernel Drivers
There's no single command that lists every driver on a Linux box, and any answer that hands you one is skipping the part that matters. To list drivers on Linux, you work from the device side: lspci -k and lsusb -t show which kernel driver is bound to each piece of hardware, lsmod shows which modules are loaded right now, and modinfo tells you what a module claims to support. Those three views disagree more often than people expect, and the disagreement is usually the bug you were chasing.
How do you list drivers on Linux?
Run these in order, and read the output rather than skimming it.
lspci -k # PCI devices with their bound driver and candidate modules
lsusb -t # USB tree with the driver on each interface
lsmod # modules loaded into the running kernel
modinfo e1000e # what one module is, where it lives, what it takes
ls -l /sys/class/net/*/device/driver # the binding, straight from the kernel
Each one answers a different question. lspci and lsusb tell you what hardware exists and what claimed it. lsmod tells you what's resident in memory. modinfo tells you what a module on disk would do if it loaded.
The /sys symlink is the one I trust when the others look ambiguous. It's the kernel's own bookkeeping, not a formatted report. If a driver directory is on the other end of that link, the binding is real.
PCI devices name both their driver and their modules

lspci -k prints two lines that people constantly conflate. Kernel driver in use: is the driver actually bound to that device. Kernel modules: is a list of modules that could claim it based on their alias tables. A device with the second line and no first line is unclaimed, and that's your failure.
Add the numeric IDs when you need to search for anything:
lspci -nnk -s 00:1f.6
Now you have vendor and device IDs in hex, which is what driver alias tables actually match on. The tool doing this work is pciutils, and its device ID database is why you see friendly names at all.
Names lie about lineage, too. e1000e is the Linux kernel driver for Intel PRO/1000 PCI-Express Ethernet adapters, and it supports all PCI Express Intel Gigabit Network Connections except those that are 82575-, 82576-, and 82580-based. Meanwhile the Intel PRO/1000 P Dual Port Server Adapter uses the e1000 driver instead, because the 82546 part sits behind a PCI Express bridge. So a card in a PCIe slot can still want the older driver.
Walking the USB tree without guessing

lsusb -t is the view worth learning, because USB binds drivers per interface, not per device. A webcam can hand its video interfaces to one driver and its audio interface to another. The tree shows you Driver= on each branch, so you can see exactly which piece went unclaimed.
lsusb -t
sudo lsusb -v -d 1d6b:0002
The verbose form needs root to read full descriptors. Without it you get a truncated dump and a confusing gap where the interesting fields should be.
For the ground truth, go to sysfs again:
ls -l /sys/bus/usb/devices/1-2:1.0/driver
That path is bus-port-config:interface. If the driver symlink is missing, nothing bound to that interface, and no amount of rerunning lsusb will change it. Also worth knowing: if you've handed a device to a userspace program through libusb, the kernel driver may have been detached on purpose. That looks identical to a failure and isn't one.
Loaded modules are only part of the picture
lsmod is a formatted view of /proc/modules, nothing more. If you want the raw form, read the file. The last column lists the modules that depend on each entry, and anything named there has to go before the module underneath it will unload.
What lsmod will never show you is anything compiled into the kernel image. Built-in drivers work fine and appear nowhere in that list. To check, look at the build config:
grep -E 'CONFIG_E1000E|CONFIG_IWLWIFI' /boot/config-$(uname -r)
A =y means built in, =m means a loadable module, and no result means it wasn't built at all. That distinction ends most "why isn't my driver loaded" confusion on the spot. For the difference between what's resident and what's merely available, my walkthrough on listing loaded kernel modules covers the mechanics.
Modules present on disk but unloaded live under /lib/modules/$(uname -r)/kernel/. They're candidates, not drivers, until something binds them.
Reading a module with modinfo
modinfo answers where a module came from and what it will accept. I use it before changing any driver parameter, because guessing at option names produces silent no-ops.
modinfo iwlwifi
modinfo -F parm iwlwifi
modinfo -n e1000e
The filename field tells you whether you're looking at a distro module or something a vendor installer dropped in. vermagic has to match your running kernel or it won't load, full stop. depends shows what else gets pulled in. alias lines are the pattern-matched hardware IDs, which is how the kernel picks a module for a device it just saw.
Provenance matters because names are reused and forks exist. iwlwifi is the Linux kernel driver for Intel's current wireless chips, and its source lives at drivers/net/wireless/intel/iwlwifi in the kernel tree. The e1000e source sits at drivers/net/ethernet/intel/e1000e. When the in-tree behavior and your box disagree, reading the probe function in those directories settles the argument faster than another forum thread.
If a parameter needs to survive reboots, set it properly rather than by hand each time. My guide to loading kernel modules with modprobe has the config file layout.
Which driver is this device actually using?
Follow the device, not the name. A module can be loaded and bound to nothing, which looks like success in lsmod and is a failure everywhere else.
udevadm info --query=all --name=/dev/sda
udevadm info -a -p /sys/class/net/enp0s31f6
sudo udevadm monitor --udev
The first gives you properties including ID_... fields and the driver. The second walks the device up through its parents, which is where you find the attributes a rule would need to match. The third watches events live while you unplug and replug something, and it's the only honest way to see whether the device is even being detected. Full flag reference is in the udevadm documentation.
For a stubborn case, look at the driver's own directory:
ls /sys/bus/pci/drivers/e1000e/
Bound devices appear there as symlinks named by PCI address. Empty means the driver holds nothing.
When a driver is missing or the probe fails
Read the kernel log first, scoped to this boot.
journalctl -k -b
journalctl -k -b --since "5 min ago" | grep -iE 'firmware|probe|failed|denied'
dmesg -T | tail -40
Probe failures print a negative error code. Don't guess what it means. Look it up in errno.h or run errno from the moreutils package, because acting on the wrong assumption sends you off rewriting a config that was fine.
Missing firmware is the most common outcome that isn't a driver problem at all. The module loads, the hardware is detected, and the probe dies because a blob isn't in /lib/firmware. Wireless chips hit this constantly, and the log says so plainly.
Other frequent causes, in the order I check them:
- Secure Boot rejecting an unsigned or out-of-tree module, which shows up as a lockdown message rather than a driver error.
- A blacklist entry someone added and forgot, which you can confirm with
modprobe -v --dry-run <module>. My notes on blacklisting modules safely explain how these files interact. - A
vfio-pcior similar override grabbing the device before the real driver gets a chance. - Permissions on the resulting device node, which is a userspace problem wearing a driver costume.
strace -f -e trace=openat,ioctl ./yourprogramshows the exact call and the exact path that got refused.
Why one command will never be enough
Because five different things are all called "drivers" in casual conversation, and each tool sees only one of them.
| What you want to know | Where to look | What it won't tell you |
|---|---|---|
| Hardware present on the bus | lspci -nnk, lsusb -t | Whether anything bound |
| Driver bound right now | /sys/.../device/driver, Kernel driver in use: | Why binding failed |
| Modules resident in memory | lsmod, /proc/modules | Anything built into the kernel |
| Drivers built into the image | /boot/config-$(uname -r), /sys/module/ | Runtime state |
| Modules on disk, unloaded | /lib/modules/$(uname -r)/, modinfo | Whether they'd match your hardware |
Reading only one row is how people conclude a driver is "missing" when it's built in, or "working" when it's loaded and idle.
The useful habit is to state your question precisely before picking a command. "Is the hardware detected" and "is the driver bound" and "is the module loaded" are separate failures with separate fixes, and answering them in that order costs a minute. Skipping straight to a fix you found online costs the evening.
FAQ
Does a loaded module mean my hardware works?
No. Loading puts code in memory; binding attaches it to a device. Check the driver directory under /sys/bus/pci/drivers/ or /sys/bus/usb/drivers/ and confirm your device appears there as a symlink.
How do I list drivers for hardware that Linux hasn't detected at all?
You can't, and that's the answer. If lspci and lsusb don't show the device, no driver question applies yet. Check whether it's disabled in firmware settings, on a bus that needs a controller driver first, or physically dead.
Can I force a device onto a specific driver?
Yes, through sysfs. Unbind it by writing the device address into the current driver's unbind file, then write the same address into the target driver's bind file. It doesn't survive a reboot, which makes it a good test and a poor solution.
Why does modinfo work on a module that lsmod doesn't list?
modinfo reads the file on disk and doesn't care about runtime state. So a module can be installed, documented, and completely inert. That's normal for hardware you don't have.
What's the fastest way to see driver activity while I plug something in?
Open two terminals. Run sudo udevadm monitor --udev in one and journalctl -kf in the other, then connect the device. You get the event stream and the kernel's reaction side by side, timestamped together.
