# \[DRAFT\] Hardware discovery and driver selection

**URL:** <https://forum.openwrt.org/t/draft-hardware-discovery-and-driver-selection/218417>\
**Category:** Talk about Documentation\
**Created:** [December 14, 2024, 9:04am UTC](https://forum.openwrt.org/t/draft-hardware-discovery-and-driver-selection/218417 "2024-12-14T09:04:43Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![NC1](https://forum.openwrt.org/user_avatar/forum.openwrt.org/nc1/32/62993_2.png) [@NC1](https://forum.openwrt.org/u/NC1)\
**Post date:** [December 14, 2024, 9:04am UTC](https://forum.openwrt.org/t/draft-hardware-discovery-and-driver-selection/218417/1 "2024-12-14T09:04:43Z")

</div>

I recently [proposed](https://forum.openwrt.org/t/hardware-discovery-and-driver-selection/217986/) 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. 🤪

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](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](https://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](https://linux-hardware.org/), 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`:

```plaintext
opkg update && opkg install pciutils usbutils

```

or

```plaintext
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](https://firmware-selector.openwrt.org/) 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:

```plaintext
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):

```plaintext
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:

```plaintext
lsusb

```

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

```plaintext
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](https://linux-hardware.org/) 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](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](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](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:

```plaintext
opkg install kmod-igb

```

or

```plaintext
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](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:

```plaintext
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](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](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:

```plaintext
opkg install kmod-usb-net-rtl8152

```

or

```plaintext
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](https://firmware-selector.openwrt.org/) 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.

---

<div class="post-metadata">

**Author:** ![anon63541380](https://forum.openwrt.org/letter_avatar/anon63541380/32/5_5575768a8748004e209b776fc1b2916d.png) [@anon63541380](https://forum.openwrt.org/u/anon63541380)\
**Post date:** [December 14, 2024, 10:25am UTC](https://forum.openwrt.org/t/draft-hardware-discovery-and-driver-selection/218417/2 "2024-12-14T10:25:45Z")

</div>

you miss out universal 99% working usb class drivers llike usb-storage cdc\_ether uvcvideo

---

<div class="post-metadata">

**Author:** ![kusmi](https://forum.openwrt.org/user_avatar/forum.openwrt.org/kusmi/32/104590_2.png) [@kusmi](https://forum.openwrt.org/u/kusmi)\
**Post date:** [December 14, 2024, 12:28pm UTC](https://forum.openwrt.org/t/draft-hardware-discovery-and-driver-selection/218417/3 "2024-12-14T12:28:49Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![NC1](https://forum.openwrt.org/user_avatar/forum.openwrt.org/nc1/32/62993_2.png) [@NC1](https://forum.openwrt.org/u/NC1)\
**Post date:** [December 14, 2024, 6:47pm UTC](https://forum.openwrt.org/t/draft-hardware-discovery-and-driver-selection/218417/4 "2024-12-14T18:47:31Z")

</div>

> [@anon63541380](#):
>
> you miss out universal 99% working usb class drivers llike usb-storage cdc\_ether uvcvideo

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?

---

<div class="post-metadata">

**Author:** ![anon63541380](https://forum.openwrt.org/letter_avatar/anon63541380/32/5_5575768a8748004e209b776fc1b2916d.png) [@anon63541380](https://forum.openwrt.org/u/anon63541380)\
**Post date:** [December 14, 2024, 6:48pm UTC](https://forum.openwrt.org/t/draft-hardware-discovery-and-driver-selection/218417/5 "2024-12-14T18:48:52Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![antonk](https://forum.openwrt.org/user_avatar/forum.openwrt.org/antonk/32/93698_2.png) [@antonk](https://forum.openwrt.org/u/antonk)\
**Post date:** [December 14, 2024, 8:39pm UTC](https://forum.openwrt.org/t/draft-hardware-discovery-and-driver-selection/218417/6 "2024-12-14T20:39:54Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![NC1](https://forum.openwrt.org/user_avatar/forum.openwrt.org/nc1/32/62993_2.png) [@NC1](https://forum.openwrt.org/u/NC1)\
**Post date:** [December 15, 2024, 12:25am UTC](https://forum.openwrt.org/t/draft-hardware-discovery-and-driver-selection/218417/7 "2024-12-15T00:25:37Z")

</div>

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.
