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?
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 fileblah/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 withfirmware_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:
/sys/firmware/<xxx>/loading
, wait for some program to write firmware to it.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 valuesKernel module
andKernel driver
) To get the list of currently used modules/loaded you can uselsmod
.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
andhwinfo
orlshw
EDIT:
To find out which drivers are loading during boot you usually search in (depends sys-vinit/systemd):
or command
dmesg
to find out what's loading in systemdjournalctl -k kernel
orjournalctl -b
for current/last boot. Consult the man pages for each command.