[DRAFT] Hardware discovery and driver selection

I recently proposed a wiki page tentatively titled Hardware Discovery and Driver Selection. Here's a draft of what I have in mind. Please feel free to react. :crazy_face:

After I post this thread, I will close the previous one with the link to this one.

Hardware discovery and driver selection

Most OpenWrt targets are devices with known and immutable architectures. This allows OpenWrt to be compact; it contains only software that is required for the target's components to work.

Some targets, however, have open architectures. The most notable (but by no means the only) example of this is x86, where there are multiple options for each system component. The default system image, therefore, simply cannot include everything every device might ever need. As a result, a device may be only partially functional immediately after installation. For example, only one (or even none) of several network adapters may work. This is inconvenient, but in the majority of cases fixable post-install. The fix consists of two parts:

  • Hardware discovery, when the user identifies problematic components
  • Driver selection, when the user determines what software is necessary for the problematic components to work properly

There are several ways in which components connect to the rest of the system. In this article, we well discuss two that are the most common: Peripheral Component Interconnect (PCI) and Universal Serial Bus (USB). In OpenWrt, drivers for PCI and USB devices are usually packaged as kernel modules. Kernel module packages have names that start with kmod-. A list of kernel modules for the current release can be found here:

https://openwrt.org/packages/index/kernel-modules

Additionally, there are lists of kernel modules for each release and each target. They can be accessed by browsing downloads.openwrt.org

Typical problems

There are several typical problems that can be solved with hardware discovery and driver selection. One, as mentioned before, is incomplete functionality after a new install; a component (such as an Ethernet card or a Wi-Fi card) may be unable to function because there is no driver for it. Another is component upgrades; the user replaces a component with another one that requires a driver not currently present on the system.

Catch-22

We are about to discuss solutions that require the problematic device to have Internet access. But what do you do if the device doesn't have Internet access because none of its networking components are functioning properly? We will deal with this later in this article.

Plan of work

There are two utilities on which we will rely in hardware discovery. They are lspci and lsusb. As their names suggest, they produce lists of PCI devices and USB devices on the system. Each PCI or USB device has an identifier, which consists of two groups of hexadecimal digits, four in each group. For example, Intel i211 Ethernet card has a PCI identifier 8086:1539. The first part identifies the manufacturer (so all components made by Intel would have 8086 there), the second part identifies a model or family of components.

We will use lspci and/or lsusb to find identifiers for problematic components. Then, we will use Hardware for Linux, a vast online resource, to set some search parameters to find drivers for problematic components. Finally, we will use OpenWrt's list of kernel modules to see which one(s) we may need to install.

A word on package managers

To install additional packages, we will need to use a package manager. In OpenWrt 24.10 and older, the package manager is called opkg. Some time in 2025, opkg will be replaced with apk (it is the same apk that is used in Alpine Linux). As of late 2024, snapshots have already transitioned to apk in preparation for the 25.* releases.

Getting the utilities

We immediately hit a snag: neither lspci nor lsusb is present in the default installation of OpenWrt. Normally, we would simply get them from the online repository by installing two packages, pciutils and usbutils:

opkg update && opkg install pciutils usbutils

or

apk update && apk add pciutils usbutils

But what if we don't have a working Internet connection? There are ways to work around this.

1. One working Ethernet device

At first boot, OpenWrt makes a list of Ethernet devices it can find. The first device found is designated eth0 and is assigned the LAN port function. The second, if found, gets the eth1 designation and is appointed to the WAN port position. So it is possible we do have one working Ethernet device, which is the LAN port. To see what, if any ports on the system are operational, you can run ip a. If you find that only one port is working, you can temporarily reconfigure that port to be WAN. This, of course, requires that you be able to access the device in a way other than SSH over the LAN port (for example, through the serial console or by using a monitor and a keyboard).

2. Pre-baking

You can use OpenWrt Firmware Selector to make a custom OpenWrt image that already includes pciutils and/or usbutils (or any other package you need, for that matter). Once you install that image, you will have immediate access to lspci and lsusb.

The actual hardware discovery: PCI

To obtain a list of PCI devices on your system with their PCI identifiers, run:

lspci -nn

This will produce a list with line items that look like this (formatted for readability; the actual output will have this as one long line):

06:00.0 Ethernet controller [0200]: 
        Intel Corporation I211 Gigabit Network Connection 
        [8086:1539] (rev 03)

Note the PCI identifier in square brackets near the end of the line. Write it down for future reference.

The actual hardware discovery: USB

To obtain a list of USB devices on your system with their USB identifiers, run:

lsusb

This will produce a list with line items that look like this:

Bus 001 Device 002: ID 0bda:8153 Realtek USB 10/100/1000 LAN

Note the USB identifier following the letters ID. Write it down for future reference.

Using Hardware for Linux

Hardware for Linux has information pages about an expansive array of computer components and Linux drivers for them. The problem is, this information is applicable to OpenWrt indirectly. So we will have to do some translating into OpenWrt-specific language.

When you find a page for the component you're interested in, look for two things, both in the Kernel Drivers section of the page:

  • Which Linux kernels support this component? and
  • What is the name of the device driver?

Since we already have two example devices, let's find some information about them.

PCI device search

To find information about a device with PCI ID 8086:1539, you can go to

https://linux-hardware.org/?id=pci:8086-1539

(Note that the colon in the identifier is replaced by the dash in the URL.)

On that page, you can see that:

  • this card is supported by kernel versions 3.16 and newer, and
  • in mainline Linux sources, the driver for this card is found at drivers/net/ethernet/intel/igb/igb_main.c

In terms of kernel, OpenWrt 23.* releases run on kernel version 5.15; OpenWrt 24.* and recent snapshots, on kernel version 6.6. So you can conclude that this card is probably supported on OpenWrt 23 and 24.

If you don't know what your kernel version is, run uname -r on your device.

In terms of driver name, look for the part that's unique to a particular model or family. In drivers/net/ethernet/intel/igb/igb_main.c, that part might be igb (occasionally, you may identify several possibilities; be sure to try all of them). On that assumption, go to the OpenWrt list of kernel modules:

https://openwrt.org/packages/index/kernel-modules

and see if you can find something with igb in it (use Ctrl-F in your browser). Sure enough, you quickly find kmod-igb:

https://openwrt.org/packages/pkgdata/kmod-igb

The package description says, "Kernel modules for Intel(R) 82575/82576 PCI-Express Gigabit Ethernet adapters", so you can be reasonably certain that this is the package you need. To install it, you would run:

opkg install kmod-igb

or

apk add kmod-igb

USB device search

To find information about a device with USB ID 0bda:8153, you can go to

https://linux-hardware.org/?id=usb:0bda-8153

(Note that the colon in the identifier is replaced by the dash in the URL.)

On that page, you can see that:

  • this device is supported by kernel versions 3.11 and newer, and
  • in mainline Linux sources, the driver for this device can be found at several possible locations:
drivers/net/usb/r815x.c
drivers/net/usb/cdc_ether.c
drivers/net/usb/r8152.c
drivers/usb/core/quirks.c
drivers/net/usb/r8153_ecm.c

In terms of kernel, OpenWrt 23.* releases run on kernel version 5.15; OpenWrt 24.* and recent snapshots, on kernel version 6.6. So you can conclude that this device is probably supported on OpenWrt 23 and 24.

If you don't know what your kernel version is, run uname -r on your device.

In terms of driver name, look for the part that's unique to a particular model or family. In this instance, we have some work to do. If we go to the OpenWrt list of kernel modules:

https://openwrt.org/packages/index/kernel-modules

and search for r815, nothing is found. But if we search for just 815, kmod-usb-net-rtl8152 pops up:

https://openwrt.org/packages/pkgdata/kmod-usb-net-rtl8152

The package description says, "Kernel module for USB-to-Ethernet Realtek 8152 USB 2.0/3.0 convertors", so this looks like the package you need. To install it, you would run:

opkg install kmod-usb-net-rtl8152

or

apk add kmod-usb-net-rtl8152

Catch-22 redux

But, again, what if none of the networking works and we don't have Internet access? In the worst-case scenario, we now know exactly what packages we're missing, so we can use OpenWrt Firmware Selector to pre-bake a custom firmware with those packages included.

Conclusion

This article should help you in resolving many of your missing driver problems. However, occasionally, the workflow described here will produce negative results. This can happen for several reasons:

  • The problematic component is neither PCI nor USB. Specifically, there are SDIO components, but luckily, they are not very common.
  • An OpenWrt driver for the problematic component simply doesn't exist. This is very likely to happen in case of obscure components or components manufactured by companies that do not contribute source code for their drivers to Linux. One such company is Broadcom.
  • A driver may exist, but be too old or too new for your device. For example, some recent Realtek drivers require kernel version 6.2 or newer, so they are not available for OpenWrt 23, which runs on kernel version 5.15, but are available for OpenWrt 24, which runs on kernel version 6.6.
5 Likes

you miss out universal 99% working usb class drivers llike usb-storage cdc_ether uvcvideo

Very informative - I guess it would be one of the top Wiki pages :blush:

Good point. One way to incorporate this would be to make a bullet point in the conclusion saying that non-networking hardware may require non-kmod packages, so if you didn't find your driver in the kernel module list, try the broader package list next... For debugging purposes, can you share a specific case? Name a device (if you have its USB ID handy, that would be great) and the package(s) it requires, so I can see whether the process can be tweaked to include those?

There should be a way to slurp hardware id's from built modules, like you see on desktop linuces.

First of all, this looks like a useful article, so props to you.

Now a few suggestions:

  • Change the article name. "Hardware discovery and driver selection" is not specific enough IMO. How about "Adding drivers after installation"?
  • I am not a native English speaker but I think that the word "immutable" will be hard to decipher for most non-coders. How about "rigid" or "predefined"?
  • Since this is a technical article which people will use to solve problems, IMO the style could be made more fitting by removing things which are not strictly necessary and generally condensing the information a bit more. For example, I would remove (but by no means the only) and rephrase this sentence:
    The default system image, therefore, simply cannot include everything every device might ever need.
    To this:
    The default system image cannot include everything every device might ever need.
    I won't scrutinize every sentence but there are more similar style-related suggestions which can be made.
    This is somewhat of a nitpick but IMO will make it easier for people to get what they want when reading a technical article, which is essential info in minimum time.

Those are valid criticisms, and this is precisely why I want this thing on the wiki. The collective wisdom will clean it up much better than I can working alone.