6

On routinely updating my Debian system, I've never took the time to pick which firmware packages I do really need; basically I have them all installed, and always up-to-date.

I've been wondering how can I pick which ones I do really need. I was thinking of using every device I have in my system (even the ones I rarely use like bluetooth, ethernet, camera, touchpad, multimedia keys and so on) and look at the list of loaded firmware.

Is there an easy way to find out which firmware is currently loaded, or were loaded since last kernel boot?

rslemos
  • 163
  • 1
  • 5

2 Answers2

6

If your kernel is built with dynamic debug support (CONFIG_DYNAMIC_DEBUG), you can use a boot parameter to enable debug messages for the firmware loader. It should catch all firmware loads, unless a particular driver does something strange and does not use the kernel's firmware loading API for some reason.

Add the following to your boot parameters:

For kernels 2.6 - 4.16: dyndbg="file drivers/base/firmware_class.c +fmp"

For kernels 4.17 and later: dyndbg="file drivers/base/firmware_loader/main.c +fmp"

(For reference, file blah/foo.c +fmp means "for all debug calls in the kernel source file blah/foo.c, enable dynamic debug printing, and make the message show the filename and module name". See the kernel docs for more detail.)

After booting, run dmesg | grep firmware_class. Of particular interest are lines with firmware_class:fw_get_filesystem_firmware, which should be sandwiched between calls to __allocate_fw_priv and __free_fw_priv.

All firmware loads will be logged until you reboot or disable dynamic debugging.


Background information:

You cannot query for "currently loaded" firmware, because firmware doesn't necessarily remain in system memory. It is often uploaded to some chip in some device outside the system. Drivers usually load a firmware file into a kernel buffer, use that buffer to program the device, then discard the buffer without keeping any record of what the file was. And the standard kernel firmware API does not keep a log by default. Some drivers do log their firmware loading to the kernel log, but it's not universal.

The first thought I had was to "get between" the kernel and whatever userspace program is responsible for grabbing firmware files so that I could add some debug messages. But it turns out this is not always possible: the kernel itself it capable of getting firmware straight from the filesystem, no userspace mechanism involved. (In fact, the kernel prefers to direct load straight from /lib/firmware/ when possible.)

The next thought I had was to use kprobe or some other tracing system to trace kernel function calls that are involved in firmware loading. But it turns out I didn't have to go that far: the firmware loader conveniently includes some debug messages that — once enabled — are enough to see all what files are being loaded. The dyndbg above takes advantage of these.


Other information:

The kernel's firmware loading API is generally accessed by calls to request_firmware() or request_firmware_nowait(). A driver calls one of these functions with the name of the firmware file it wants, and the kernel attempts to load it using this process:

  • Check for firmware in the kernel image, load from there if found.
  • Check for firmware on the filesystem, load from there if found.
  • [If kernel is configured for it] use a sysfs "fallback": create /sys/firmware/<xxx>/loading, wait for some program to write firmware to it.
    • [If kernel is configured for it] create a uevent to inform udev or whoever is listening that "it would be really great if you could write to this file".
    • If too much time passes (specifically whatever length of time is in /sys/firmware/timeout), give up with an error.
James Luke
  • 76
  • 1
  • 4
0

There are multiple commands, depends what you need.

Start with lspci -vvvvv it will show you which module/driver is the device using. (look for values Kernel module and Kernel driver) To get the list of currently used modules/loaded you can use lsmod.

To obtain more details check the Wiki Lspci there are listed other commands, but you may need to install extra packages.

These will provide you info about the HW itself: dmidecode and hwinfo or lshw

EDIT:

To find out which drivers are loading during boot you usually search in (depends sys-vinit/systemd):

/var/log/bootlog
/var/log/syslog
/var/log/kern.log

or command dmesg to find out what's loading in systemd journalctl -k kernel or journalctl -b for current/last boot. Consult the man pages for each command.

Geeky Masters
  • 729
  • 2
  • 8