linux-firmware is the upstream collection of binary firmware files that Linux drivers hand to devices such as Wi-Fi cards, Bluetooth radios, GPUs, network adapters and audio DSPs. The kernel finds each file under /lib/firmware (or inside the initramfs) when a driver calls request_firmware(), copies it to the device, and in most cases the device itself, not the kernel, checks the vendor signature. You update these blobs by updating your distribution's firmware package, rebuilding the initramfs and rebooting, which is a different path from fwupd and LVFS, which rewrite firmware stored in device flash.
This post goes one level deeper than our guides to firmware updates with fwupd and LVFS, CPU microcode updates and embedded controller firmware. Those posts cover flash updates, the processor and the laptop's housekeeping chip. This one covers the files that sit in /lib/firmware on almost every Linux machine and that most teams never inventory.
Key takeaways
- linux-firmware is a git repository at kernel.org and GitLab that collects redistributable firmware images and device data files for drivers in the mainline kernel. Vendors submit their own files, and every commit carries a
Signed-off-byfrom someone with authority over the licence. - The
WHENCEfile is the manifest: for each driver it lists the files, versions where known, and the licence. Nearly all entries are vendor "redistributable" licences, not open source. - The kernel loads firmware in a fixed order: built into the kernel image, then the in-memory firmware cache, then a direct filesystem lookup under
/lib/firmware, then optional fallbacks. Compressed.xzand.zstfiles are tried only after the uncompressed name fails. - Drivers built into the kernel, or loaded from the initramfs, need their firmware inside the initramfs. Updating the package without rebuilding the initramfs can leave the old blob in use.
- The kernel does not check vendor signatures on ordinary firmware files. Many modern devices verify the image in their own boot ROM or security processor. Integrity measurement policies can add a host-side check if you configure them.
- Runtime-loaded blobs live in RAM on the device and disappear at power off. Flash-resident firmware persists, and updating it is the job of fwupd, LVFS and vendor tools.
- Upstream tags are dated (
20261019,20260916). Stable distributions often freeze an older snapshot and backport fixes, so the version string alone does not tell you how current your blobs are.
A dated timeline of linux-firmware and its distribution
| Date | Event | Source |
|---|---|---|
| 18 Sep to 1 Oct 2022 | Debian holds a general resolution on non-free firmware in the installer and official media | Debian vote page |
| 10 Jun 2023 | Debian 12 "bookworm" ships with a separate non-free-firmware archive component | Debian release announcement and release notes |
| 17 Oct 2024 | linux-firmware tag 20241017; from this release the Makefile rejects the old COPYOPTS variable in favour of install-xz, install-zst and dedup targets | linux-firmware Makefile and tags |
| 2025 | Upstream publishes 14 dated tags, from 20250109 to 20251125 | GitLab tag list |
| 16 Sep 2026 | Tag 20260916; Debian testing and unstable carry 20260916-1 | GitLab tags, Debian package tracker |
| Oct 2026 | Tag 20261019, the newest at the time of writing (its last commit is dated 17 October) | GitLab tags |
| 25 Oct 2026 | Debian stable still builds from the 20250410 snapshot, with 20260916 available in backports; Arch has 20261019 in its testing repository | Debian package tracker, Arch package page |
What is the linux-firmware repository?
linux-firmware is a plain git repository of binary files and text metadata. Its README describes it as a home for firmware images "extracted from older drivers" plus new images that could never be included in a GPL work but that vendors permit to be redistributed separately. The README names the GitLab project under the kernel-firmware group as the upstream repository, and the project's mailing list is linux-firmware@kernel.org.
Who maintains it?
Two groups matter here. The kernel's MAINTAINERS file lists the maintainers of the firmware loader code itself (drivers/base/firmware_loader/), which is part of the driver core. The linux-firmware repository has its own small set of maintainers who review vendor submissions, and its README warns that they are busy and replies may be slow. Submissions arrive as a GitLab merge request, a git binary diff mailed to linux-firmware@kernel.org, or a pull request sent to the same list. The README sets three rules that matter for supply chain thinking:
- Every commit needs a
Signed-off-byline from someone with authority over the firmware's licence, usually an employee of the company that owns it. The README calls this an attestation that the contributor may submit the file and that it can be redistributed. - Firmware must come from the vendor that owns it, or with that vendor's explicit participation. Third party submissions without the vendor are refused.
- A commit that adds firmware must update
WHENCEwith the licence and a statement that the file is redistributable.
The README also asks for an Assisted-by: (or similar) trailer when an AI tool helped produce a commit, in addition to the sign-off. It also asks vendors to put a changelog of the firmware itself in the commit message, because for a binary file "the commit message is frequently the only human readable record of the change." That sentence is worth remembering when you try to work out what changed between two tags.
What does it contain?
The repository holds firmware for hundreds of drivers. On 25 October 2026 the WHENCE file on the main branch listed 269 Driver: entries. The main families are:
| Device class | Example drivers in WHENCE | What the blob does |
|---|---|---|
| Wi-Fi | iwlwifi, ath11k, ath12k, rtw89, mt7921, brcmfmac | Runs the radio's embedded processor: MAC scheduling, power save, offloads, regulatory tables |
| Bluetooth | btusb, mt7921 bluetooth | Patches the controller's ROM code and loads configuration |
| GPU | amdgpu, i915, xe, nouveau | Microcontrollers for power management, command scheduling, display and video decode |
| Wired networking | bnx2x, ice, r8169, mlxsw_spectrum | NIC and switch ASIC firmware, packet processing packages |
| Audio and DSP | snd_soc_avs, snd_soc_catpt and codec drivers | Digital signal processor code and topology files |
| Remote processors and SoCs | qcom_q6v5_pas, qcom_q6v5_mss, qcom-geni-se | Modem, sensor and peripheral subsystems on phones and Arm laptops |
| Platform helpers | amd_pmf and similar | Trusted applications and platform management data |
Not every file is executable code. The kernel's own firmware API documentation says the loader serves three kinds of request: microcode for CPU errata, device firmware that must be loaded onto device microcontrollers, and device information data such as calibration files and EEPROM overrides, some of which are optional.
WHENCE and the licences
WHENCE is a long plain text file, about half a megabyte today. Each block names a driver, lists files with File: lines (and Link: lines for symlinks), sometimes records a Version:, and ends with a Licence: or License: line. Most of those lines read "Redistributable" followed by a pointer to a vendor licence such as LICENCE.<vendor>. On 25 October 2026, 259 of the 286 licence lines contained the word "Redistributable" and 23 mentioned the GPL (a few mention both). Long licence texts live in a LICENSES/ directory.
A newer LICENSE-CRITERIA.md document spells out what the project will accept. Firmware must be a standalone image or device data file loaded by the kernel, a driver or a device, not a host application or shared library. Binary-only firmware is acceptable. The licence must allow anyone to redistribute it onward with "no signatures, registration, click-through, or payment required." The document says plainly that it is project policy, not legal advice, and that older licences predating the criteria are treated as exceptions.
Two consequences follow. First, a redistributable licence is not an open source licence: you can ship the file, but you usually cannot inspect source, rebuild it or modify it. Second, the git history gives you provenance of the file's arrival (who signed off, when, from which company), but not provenance of how the vendor built it.
How is it released?
Upstream cuts dated tags in YYYYMMDD form. The GitLab tag list shows ten tags between January and October 2026 (20260110, 20260221, 20260309, 20260410, 20260519, 20260622, 20260810, 20260910, 20260916, 20261019) and fourteen across 2025. That is roughly monthly, with occasional extra tags when a fix lands. A tag is a snapshot of the whole tree. There are no separate version numbers per driver at the repository level; any per-file version lives in WHENCE or inside the blob.
The repository ships its own install tooling. make install runs copy-firmware.sh to copy files listed in WHENCE into /lib/firmware. make install-xz and make install-zst do the same but compress each file, and make dedup replaces duplicate files with links. Since tag 20241017, the Makefile refuses the old COPYOPTS variable and tells packagers to use these targets instead. The xz path calls xz with --check=crc32, which matters because the kernel's xz decoder only accepts files with no integrity check or a CRC32 check.
How does the kernel firmware loader work?
The firmware loader is a small kernel subsystem under drivers/base/firmware_loader. Drivers call it with a file name and a device, and receive a buffer holding the bytes.
The request_firmware family
The kernel documentation lists several entry points:
| Call | Behaviour | Typical use |
|---|---|---|
request_firmware() | Synchronous; sleeps until found or failed | Most drivers at probe time |
firmware_request_nowarn() | Synchronous, without warning messages on failure | Optional files |
request_firmware_direct() | Synchronous, never falls back to the user mode helper | Optional files where a long timeout would hurt |
request_firmware_into_buf() | Loads into a caller supplied buffer | Large images, remote processors |
request_firmware_nowait() | Asynchronous with a callback | Drivers that should not stall boot |
firmware_request_platform() | Also checks firmware embedded in platform (EFI) memory | Touchscreens and similar devices whose firmware is only in the vendor's boot firmware |
firmware_request_cache() | Asks the loader to cache a file for resume | Drivers that need firmware right after suspend |
The introduction page recommends asynchronous calls where possible, because even when reading the file is quick, processing it can delay boot. The name passed in must be distinctive, because it is exposed to user space as $FIRMWARE in uevents, and it must not contain .. path components. After the driver has pushed the bytes to the device it calls release_firmware().
The lookup order
When a driver asks for a file, the loader checks sources in this order, according to the kernel's "Firmware lookup order" page:
- Built-in firmware. Files compiled into the kernel image with
CONFIG_EXTRA_FIRMWAREandCONFIG_EXTRA_FIRMWARE_DIR. - Firmware cache. Copies kept in memory across suspend and resume.
- Direct filesystem lookup. The common case: read the file from the root filesystem (or the initramfs, if root is not mounted yet).
- Platform firmware fallback. Only for
firmware_request_platform(), which can find firmware embedded in EFI boot services memory. - Sysfs fallback. If enabled, the kernel creates a sysfs interface and either sends a uevent for a user space helper or waits for a custom loader, up to a timeout.
The search paths
For the direct lookup, the kernel tries these directories in order:
<firmware_class.path, if set>
/lib/firmware/updates/<kernel release>/
/lib/firmware/updates/
/lib/firmware/<kernel release>/
/lib/firmware/
The custom path comes from the firmware_class.path= kernel parameter (up to 256 characters) or from writing to /sys/module/firmware_class/parameters/path at run time. The updates directories exist so an administrator can override a packaged file without editing the package's own files. The documentation recommends keeping /lib/firmware on the root filesystem rather than a separate partition, to avoid races during boot.
Compressed firmware
With CONFIG_FW_LOADER_COMPRESS, the loader can read .xz (on by default under that option) and .zst files. The Kconfig help text is precise: the compressed file is tried "as a fallback, only after loading the raw file failed at first." The driver still receives decompressed bytes. Compression does not apply to built-in firmware, and xz files must use no integrity check or CRC32. Distributions increasingly ship compressed trees because /lib/firmware has grown to hundreds of megabytes uncompressed.
A practical consequence: if both foo.bin and foo.bin.zst exist, the uncompressed one wins. A stale uncompressed file left behind by a manual copy will silently shadow a newer compressed file from the package.
Firmware and the initramfs
This is where most real world surprises come from. The kernel documentation says drivers built into the kernel "should have the firmware integrated also as part of the initramfs," because otherwise the driver can probe before the real root filesystem is mounted and the lookup fails. It also notes that an old style initrd does not solve the race.
The same applies to modules that are loaded from the initramfs, for example a storage or graphics driver needed early in boot. Initramfs generators (dracut, initramfs-tools, mkinitcpio and others) look at the modules they include and copy the firmware those modules declare. That copy is a snapshot. When the firmware package updates, the initramfs keeps the old blob until it is regenerated. Most distributions trigger a rebuild from a package hook, but custom images, appliances and hand-built kernels often do not.
The firmware cache across suspend
Some drivers need firmware again when the system resumes. During resume, the root filesystem may not be ready. The loader therefore requests firmware before suspend and keeps it in memory, so drivers using the standard calls get it immediately on resume. The documentation notes the fallback timeout is temporarily cut to 10 seconds while the cache is set up. The upshot for updates: after you replace a file on disk, a suspend and resume may still feed the device the cached old copy. Reboot to be sure.
Fallbacks and the sysfs loader
Older systems relied on a user space helper: the kernel created a node under /sys/class/firmware/, sent a uevent, and udev wrote the file in. Today most distributions disable the build option that forces this fallback on every request (CONFIG_FW_LOADER_USER_HELPER_FALLBACK), and drivers that truly need it opt in. The fallback still matters for unusual cases: firmware that cannot live on the root filesystem, or per-device calibration data that must be scraped from somewhere else.
There is also an EFI embedded firmware fallback. Some tablets and laptops ship touchscreen firmware only inside the vendor's UEFI boot firmware. The kernel can find a copy in EFI boot services memory early in boot, match it against a known hash, and serve it to firmware_request_platform().
The firmware upload API: the other direction
Everything above is about pushing a file into a device's RAM. The kernel also has a firmware upload API for persistent updates. A driver that registers with it exposes loading and data files under /sys/class/firmware/<name>/, plus status files. A user writes 1 to loading, writes the image to data, then writes 0, and the driver transfers the image to the device in a kernel worker. The documentation is explicit that "it is the responsibility of the device driver and/or the device itself to perform any validation on the data received." The kernel does not check a signature for you there either.
Runtime loaded or stored on device flash?
The single most useful distinction in this area is where the firmware lives when the power is off.
Runtime-loaded firmware lives in the operating system's files. The device has a small boot ROM that can do little more than accept an image over its bus, check it, and jump to it. Each boot, and often each resume or device reset, the driver sends the image again. Many Wi-Fi chips, GPU microcontrollers and audio DSPs work this way. Updating it means updating a file and reloading the driver.
Flash-resident firmware lives on the device in SPI NOR flash, EEPROM or similar storage, and runs whether or not an operating system loads anything. System UEFI firmware, embedded controllers, SSD controllers, Thunderbolt and USB4 retimers, docks, keyboards and many server NICs and storage controllers work this way. Updating it means writing to flash, usually through a vendor protocol, and usually with a reboot or device reset.
Hybrids are common. A Bluetooth controller may keep base code in ROM and accept a patch file at every boot. A GPU may boot from on-board flash for basic display output and then receive runtime microcontroller images from the driver. CPU microcode is the extreme hybrid: the processor ships with microcode in ROM, the system firmware may apply a newer patch at power on, and the kernel can apply an even newer one from the initramfs early in boot. None of it persists across power off. The kernel's x86 microcode documentation notes that late loading, applying a patch on a running system, has not been enabled by default since kernel 5.19, because it is risky while real workloads run; early loading from the initramfs is the normal path.
Why it matters for updates and risk:
| Question | Runtime loaded | Flash resident |
|---|---|---|
| How is it updated? | Distribution package, then reload or reboot | fwupd and LVFS, UEFI capsule, vendor tool |
| Does a bad update brick the device? | Rarely; boot an older file | Possible without dual banks or recovery |
| Can you roll back? | Usually yes, by restoring the old file, unless the device enforces a minimum version | Often blocked by anti-rollback counters |
| Who can see the version? | The driver logs it; files are in your package database | The device reports it; fwupd can read many |
| What does an attacker with root need to change it? | Write access to /lib/firmware or the initramfs | A flash write path and, on most modern devices, a valid vendor signature |
Who signs firmware, and what does the kernel check?
Here is the part people most often get wrong: the Linux firmware loader does not verify vendor signatures on firmware files. It reads bytes from a path and hands them to the driver. Kernel module signing, which the kernel documentation describes in detail, covers modules, not the files modules load. A root user who can write to /lib/firmware can make the kernel read a different file.
Where verification happens instead:
- On the device. Many modern devices refuse unsigned or wrongly signed images. The kernel's i915 documentation, for example, describes the HuC media firmware being loaded and then authenticated by the GuC microcontroller before use; the xe driver documentation describes the same split for newer GPUs. The xe documentation also describes the image layout: a header, the microcode itself and an RSA signature are mandatory parts of each GPU microcontroller image the driver loads. Wi-Fi, Bluetooth and SoC remote processor firmware commonly follows a similar pattern, with the check done in a boot ROM or a security processor on the device, but the details are device specific and rarely documented in public. The vendor holds the signing key; neither the kernel nor the distribution can re-sign the file.
- Through integrity measurement, if you turn it on. The kernel's IMA policy language has a
FIRMWARE_CHECKhook. A policy can measure every firmware file the loader reads into the measurement log, or appraise it against a signature stored in an extended attribute, and refuse files that fail. This is a host-side control you configure; it is off unless your distribution or your policy enables it. - Through package signatures. Your distribution signs its repository metadata, and the package manager verifies that the
linux-firmwarepackage came from the distribution. That protects the delivery path, not the content: it proves the distribution shipped this file, not what the file does. - Through the git history. Upstream sign-offs record who submitted each file. That is accountability, not cryptographic verification of the blob.
The flash update world is more explicit about this. When a vendor uploads to LVFS, the service repacks the cabinet archive and signs the firmware with a detached GPG or PKCS#7 signature so client tools can confirm it came from LVFS. LVFS metadata also carries a LVFS::DeviceIntegrity value, because, as its documentation says, generic transport protocols such as NVMe, ATA and DFU make no guarantee of signing requirements. A value of signed means the device itself verifies the payload with strong cryptography. linux-firmware has no equivalent field in WHENCE, so you learn a device's verification behaviour from vendor documentation or not at all.
Trust implications
- You trust the vendor build. The blob is opaque. A signed image that the device accepts is exactly what the vendor shipped, bugs and all. Signature checks stop tampering in transit or on disk; they do not tell you the firmware is safe.
- Device-side verification protects the device, not the host. If an attacker cannot get a malicious image accepted, they may still load an older, correctly signed image with a known flaw, unless the device enforces a minimum version. Anti-rollback support varies widely by device class.
- Devices often have broad access. GPUs, NICs and Wi-Fi chips can perform direct memory access. An IOMMU, enabled and configured, limits what a misbehaving device can touch. That is a mitigation for flawed firmware regardless of who signed it.
- NIST's platform firmware guidance sets the bar. NIST SP 800-193 (Platform Firmware Resiliency Guidelines) describes protection, detection and recovery for platform firmware, including authenticated update mechanisms. NIST SP 800-147B applies the same idea to server BIOS updates. These are written for flash-resident firmware, but the questions transfer: who can sign, what verifies, can it roll back, how do you recover.
How do distributions ship linux-firmware?
Every major distribution repackages the upstream tags, but they differ in how they split, version and update them.
Debian: the non-free-firmware component
Debian's social contract kept non-free software out of its main archive and installer for decades, which made installing on laptops with modern Wi-Fi painful. In 2022 the project held a general resolution on the question. Voting ran from 18 September to 1 October 2022. The winner was Option 5, "Change SC for non-free firmware in installer, one installer." It amended the Social Contract so that official installer and live images include non-free firmware from a dedicated archive area, and because it changed a foundation document it needed a 3:1 supermajority. It cleared that bar comfortably: 289 voters ranked it above "none of the above" against 63 the other way. Debian 12 "bookworm," released on 10 June 2023, was the first release with the separate non-free-firmware component.
Debian builds the upstream tree as the firmware-nonfree source package, split into many binary packages by vendor and device family, for example firmware-amd-graphics, firmware-atheros, firmware-brcm80211, firmware-cirrus, firmware-intel-graphics, firmware-intel-sound and firmware-misc-nonfree. On 25 October 2026 the package tracker showed stable at 20250410-2, with 20260916-1 in testing, unstable and stable backports.
The bookworm release notes explain the design: most non-free firmware packages moved from non-free to non-free-firmware, so official installation images can install a system with only main and non-free-firmware, without the rest of non-free or contrib. On a system upgraded from an older release you add non-free-firmware to your APT sources yourself. Because the resolution passed, the old split between "free" and "non-free" installer images ended.
Ubuntu: one package, dated git snapshots
Ubuntu ships a single linux-firmware source package. Its versions embed the upstream date and commit, such as 20260915.git1522c78a. Each release starts from a snapshot and then receives stable release updates and security updates on top. Launchpad shows the long-term support release from April 2024 still based on a 20240318 snapshot, with updates published as recently as September 2026. The version string therefore tells you the base snapshot, not how many fixes have been backported.
Arch Linux: split packages, near the upstream tag
Arch tracks upstream closely. Its linux-firmware package is now a meta package depending on split packages such as linux-firmware-amdgpu, linux-firmware-atheros, linux-firmware-broadcom, linux-firmware-intel, linux-firmware-mediatek, linux-firmware-nvidia, linux-firmware-realtek and linux-firmware-other, so you can install only the families your hardware needs. On 25 October 2026 the 20261019 build was in the testing repository.
What this means in practice
| Distribution model | Freshness | Who decides what you get | Risk to watch |
|---|---|---|---|
| Stable release with backports (Debian stable, Ubuntu LTS) | Base snapshot can be a year or more old | Distribution security and stable teams | New hardware unsupported; fixes depend on backporting |
| Rolling release (Arch, Debian testing) | Days to weeks behind upstream | Package maintainers | Regressions arrive quickly too |
| Enterprise distribution | Snapshot plus vendor-certified updates | Distribution vendor | Long lag for non-certified hardware |
| Custom image, appliance or embedded build | Whatever was copied at build time | You | Nobody updates it unless you rebuild |
How do linux-firmware updates relate to fwupd and LVFS?
They solve different problems and rarely overlap.
linux-firmware updates files the kernel loads into device RAM. Delivery is your package manager. The device forgets the image at power off, so the next boot uses whatever file is on disk.
fwupd is a system daemon that updates firmware stored on the device: UEFI system firmware through capsules, docks, SSDs, Thunderbolt controllers, peripherals and more. LVFS, the Linux Vendor Firmware Service, is the web service where hardware vendors upload firmware in a .cab archive with a metadata file, and which publishes signed metadata that fwupd clients download. The LVFS documentation describes it as a secure web service used by vendors to upload firmware archives and by users to download metadata and updates. Our fwupd and LVFS guide walks through that path step by step.
Some devices appear in both worlds. A GPU can have flash-resident firmware updated by fwupd and runtime microcontroller images from linux-firmware. A Wi-Fi card is almost always linux-firmware only. A dock or a keyboard is almost always fwupd only. A complete firmware hygiene routine therefore needs both: keep the package current, and run fwupdmgr get-updates on a schedule.
Comparison: four ways firmware reaches a Linux machine
| Path | Delivery | Where it persists | Who signs | Who verifies | Rollback |
|---|---|---|---|---|---|
| linux-firmware runtime blobs | Distribution package into /lib/firmware and the initramfs | Host disk only; device RAM until power off | Vendor (inside the blob, device specific) | The device, if it supports it; optionally IMA on the host | Easy on the host side; device may enforce a minimum version |
| CPU microcode | Distribution microcode package, applied early from the initramfs; also via system firmware updates | Not persistent; reapplied every boot | CPU vendor | The processor | Install an older package and reboot; late loading is off by default since kernel 5.19 |
| fwupd and LVFS updates | fwupd downloads from LVFS, applies via capsule, DFU or vendor protocol | Device flash | Vendor signs the payload; LVFS signs metadata | Device or platform firmware for the payload; fwupd for metadata | Often blocked by anti-rollback; some devices allow downgrade with a flag |
| Vendor flashing tools | Vendor download, often outside the distribution | Device flash | Vendor | Device or platform firmware | Vendor specific |
Step by step: inventory, update and verify firmware on a running system
These commands are read only unless noted. They work on most systemd based distributions; replace package manager commands with your own.
1. See which firmware files the kernel loaded
# Kernel messages about firmware loads and failures
sudo dmesg | grep -iE 'firmware|fw:|ucode|loaded' | less
# Same, from the journal for the current boot
journalctl -k -b | grep -iE 'firmware|direct firmware load|loaded firmware version'
Lines such as Direct firmware load for <name> failed with error -2 mean the file was not found (error -2 is "no such file"). Many drivers also log the version they loaded; Wi-Fi and GPU drivers usually do.
2. Map drivers to the firmware they can request
# Modules currently loaded
lsmod | awk 'NR>1 {print $1}' | sort > /tmp/mods.txt
# Firmware file names each loaded module declares
while read -r m; do
fw=$(modinfo -F firmware "$m" 2>/dev/null)
[ -n "$fw" ] && printf '%s\n%s\n\n' "== $m" "$fw"
done < /tmp/mods.txt | less
# Which driver is bound to each PCI device
lspci -k
modinfo -F firmware lists every name a module might request. A driver that supports several firmware API versions declares several, and loads the newest one it finds. The list is a superset of what was actually loaded, so combine it with the log output from step 1.
3. Check what is installed and from which package
# Debian and Ubuntu
dpkg -l 'firmware-*' linux-firmware 2>/dev/null | awk '/^ii/ {print $2, $3}'
apt policy linux-firmware firmware-misc-nonfree 2>/dev/null
# Fedora, RHEL and derivatives
rpm -qa | grep -i firmware | sort
# Arch
pacman -Qs linux-firmware
# Which package owns a specific file
dpkg -S /lib/firmware/regulatory.db 2>/dev/null || rpm -qf /lib/firmware/regulatory.db
Look for files under /lib/firmware/updates/. Anything there overrides the packaged copy, and no package manager will tell you it is stale:
sudo find /lib/firmware/updates -type f 2>/dev/null
# Files in /lib/firmware not owned by any package (Debian family)
find /lib/firmware -type f | while read -r f; do dpkg -S "$f" >/dev/null 2>&1 || echo "unowned: $f"; done
4. Check the initramfs copy
# Debian and Ubuntu
lsinitramfs /boot/initrd.img-$(uname -r) | grep -E '^(usr/)?lib/firmware' | head -50
# Fedora and other dracut systems
sudo lsinitrd /boot/initramfs-$(uname -r).img | grep firmware | head -50
# Arch (mkinitcpio)
lsinitcpio /boot/initramfs-linux.img | grep firmware | head -50
Compare a file in the initramfs with the one on disk. If the hashes differ, the early boot path is using an older blob.
5. Update the firmware package
# Debian and Ubuntu
sudo apt update && sudo apt install --only-upgrade linux-firmware 'firmware-*'
# Fedora
sudo dnf upgrade --refresh 'linux-firmware*' '*-firmware'
# Arch
sudo pacman -Syu
On Debian stable, newer firmware for new hardware is usually in backports. Enable the backports suite for your release first and install from it explicitly; do not mix in testing packages.
6. Rebuild the initramfs
Rebuilding the initramfs is not destructive, but a broken initramfs can stop the machine booting. Before you run these commands, confirm you have a second kernel entry or a rescue medium, and check the target file name with ls /boot so you rebuild the image for the kernel you mean.
ls -l /boot/
uname -r
# Debian and Ubuntu
sudo update-initramfs -u -k "$(uname -r)"
# Fedora and other dracut systems
sudo dracut --force /boot/initramfs-$(uname -r).img $(uname -r)
# Arch
sudo mkinitcpio -P
Most package managers run this automatically after a firmware package update. Check the package output; if you see no initramfs hook, run it yourself.
7. Reboot and confirm
sudo reboot
# after boot
journalctl -k -b | grep -iE 'firmware version|loaded firmware|ucode'
Reboot rather than reloading a module where you can. Reloading reloads the file from disk, but a cold boot also clears the firmware cache and any state the device kept.
8. Check flash firmware separately
fwupdmgr get-devices
fwupdmgr refresh
fwupdmgr get-updates
That covers the devices whose firmware lives in flash. It will not list linux-firmware blobs.
9. Optional: compare against an upstream tag
For a high assurance build, you can fetch the upstream tag your distribution says it is based on and compare file hashes:
git clone --depth 1 --branch 20260916 https://gitlab.com/kernel-firmware/linux-firmware.git /tmp/lf
sha256sum /tmp/lf/iwlwifi-*.ucode | sort > /tmp/upstream.sha
( cd /lib/firmware && sha256sum iwlwifi-*.ucode 2>/dev/null ) | sort > /tmp/local.sha
diff <(awk '{print $1}' /tmp/upstream.sha) <(awk '{print $1}' /tmp/local.sha)
If your distribution compresses files, decompress before hashing. Differences are not automatically a problem; distributions backport newer blobs to stable snapshots. They are a prompt to find out why.
Firmware on servers, virtual machines and container hosts
Containers share the host kernel. A container image may carry a /lib/firmware directory if its base image installed a firmware package, but the kernel never reads it: firmware requests resolve against the host's root filesystem and initramfs. Scanning a container image tells you nothing about the firmware your GPUs and NICs actually run.
On bare metal Kubernetes nodes and GPU servers, the host image is the thing that matters. NIC and accelerator firmware often comes from linux-firmware or a vendor package on the host, and some data center adapters also carry flash-resident firmware that a vendor tool updates. Treat the node image as an artifact with its own bill of materials and its own update cadence.
Virtual machines usually see emulated or paravirtual devices that need no firmware, except for passed-through devices, where the guest driver loads firmware from the guest's own /lib/firmware. Cloud images often strip firmware packages to save space, which is fine until you attach a passthrough GPU or SR-IOV NIC.
Minimal and immutable operating systems build /lib/firmware at image build time. If the build pipeline pins a firmware package version and nobody bumps it, the fleet keeps an old snapshot for as long as the image lives.
Common mistakes
- Pinning an old linux-firmware for years. Teams pin the package after a regression, then forget. Pin with an expiry date and a ticket, and test the newest tag on a canary machine every month or two.
- Forgetting the initramfs. The package updates, the initramfs keeps the old file, and the driver loads early from the initramfs. Rebuild it, check it with
lsinitramfsorlsinitrd, and reboot. - Leaving files in
/lib/firmware/updates/. A one-off fix copied there months ago now overrides every packaged update. Audit that directory. - Shadowing compressed files with uncompressed copies. The loader tries the raw name first. A manually copied
.binbeats the packaged.bin.zst. - Assuming a blob is open source. Most files in linux-firmware are redistributable binaries under vendor licences. Record the licence from
WHENCEin your compliance notes, and do not promise source for them. - Assuming the kernel checked the signature. It did not, unless you configured IMA appraisal. Device-side checks vary by hardware.
- Ignoring firmware on container hosts. Container image scans do not cover host firmware. Patch and track the node image.
- Treating suspend and resume as a reload. The firmware cache can keep the old copy in memory. Reboot after firmware updates.
- Mixing release suites to get newer firmware. Installing a testing package on a stable system can pull in unrelated dependencies. Use backports or the distribution's documented route.
- Confusing fwupd with linux-firmware. Running
fwupdmgr updatedoes not touch/lib/firmware, and updating the package does not flash anything.
FAQ
What is linux-firmware?
It is the upstream git repository, and the distribution package built from it, that collects binary firmware files Linux drivers load into devices such as Wi-Fi, Bluetooth, GPU, network and audio hardware. Vendors submit the files with a redistribution licence recorded in WHENCE.
Where are Linux firmware files stored?
Under /lib/firmware on the root filesystem (on merged-usr systems that is /usr/lib/firmware), with optional override directories at /lib/firmware/updates/ and per-kernel subdirectories. Early boot drivers read copies stored inside the initramfs.
How do I see which firmware my Linux system loaded?
Search kernel messages with dmesg or journalctl -k for "firmware" and for failed direct loads, and list the names each loaded module can request with modinfo -F firmware <module>. Most Wi-Fi and GPU drivers also log the version they loaded.
Does the Linux kernel verify firmware signatures?
Not for ordinary firmware files. The loader reads the file and passes it to the driver. Many devices verify the vendor signature themselves, and administrators can add a host-side check with an IMA policy rule for FIRMWARE_CHECK.
Is linux-firmware open source?
Mostly not. The repository is public and freely redistributable, but most files are binary-only under vendor licences that allow redistribution without granting source or modification rights. A minority are under GPL or other open source licences.
Do I need to rebuild the initramfs after updating linux-firmware?
Yes, if any driver that needs firmware loads from the initramfs. Most distributions do it automatically through package hooks; confirm by checking the initramfs contents, and rebuild manually on custom kernels or images.
What does "Direct firmware load failed with error -2" mean?
Error -2 is "no such file or directory." The driver asked for a file name that is not present in any search path. It may be an optional file, in which case the driver continues, or a missing package or an initramfs without the file.
What is the difference between linux-firmware and fwupd?
linux-firmware provides files the kernel loads into device memory at each boot. fwupd, with LVFS, writes new firmware into a device's flash storage, where it persists. Most machines need both kept current.
How often is linux-firmware released?
Upstream tags dated snapshots roughly monthly; there were ten tags from January to October 2026. Rolling distributions follow within weeks. Stable distributions start from a snapshot and backport fixes, so their version strings can look much older than the fixes they carry.
Is it safe to delete unused files from /lib/firmware?
It saves space but makes hardware changes fail silently later, and the package manager will put the files back on the next update. Split packages, where your distribution offers them, are a cleaner way to install only what your hardware needs.
Where Safeguard fits, honestly
Safeguard does not scan firmware, inspect blobs or generate hardware bills of materials, and it does not manage endpoints or flash devices. The fit is indirect and sits around the firmware: the container images, repositories and SBOM files your teams build, including the node images and tooling that install firmware packages. Safeguard scans those for vulnerable open source dependencies, shows which projects contain a given component and version, and evaluates policies and gates. Firmware freshness on the host still comes from your distribution, your initramfs rebuild and fwupd.
Firmware blobs come from hardware vendors and reach you through your distribution, so nothing below replaces a firmware package update. The node images, build pipelines and services that run on those machines still pull open source dependencies on every rebuild, and that is where the next section applies.
Fix it without waiting for upstream
Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.
3. Gold Registry: start from components that are already fixed
registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | The Gold scan GitHub Action in CI, plus Safeguard policies and gates |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch (early access) |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
See how Safeguard would help
The first demo shows the Safeguard CLI in a real repository: it reads a finding, asks before any command that changes something, edits a dependency and runs the tests. The same flow applies to the repository that builds your node or appliance image, where a pinned package or an outdated build tool is the dependency to move.
Click through it at your own pace, or open it full screen.
The second demo sets up the local runner on your own machine, approves it with a device code and scans from the terminal. That is useful when the image build happens on a machine inside your network rather than in a hosted pipeline.
Click through it at your own pace, or open it full screen.
The third demo connects Claude to the Safeguard MCP server with OAuth and lets you choose which tools Claude can use. You can then ask which of your projects contain a given component version while you work through a host image update.
Click through it at your own pace, or open it full screen.
Download the CLI at safeguard.sh/download and read the CLI docs.
Quick check
If both iwlwifi-x.ucode and iwlwifi-x.ucode.zst exist in /lib/firmware, which one does the kernel load?
The uncompressed file. The loader tries the raw file name first and only falls back to a compressed file if the raw one is missing.
You updated the firmware package, but the driver still logs the old firmware version after a suspend and resume. Why?
The firmware cache can keep the old copy in memory across suspend, and an early-loading driver may read from an initramfs that still holds the old file. Rebuild the initramfs and reboot.
Sources
- linux-firmware repository on GitLab
- linux-firmware README
- linux-firmware LICENSE-CRITERIA.md
- linux-firmware WHENCE file
- linux-firmware Makefile
- linux-firmware copy-firmware.sh
- linux-firmware tag list (GitLab API)
- Linux kernel documentation, Linux Firmware API
- Linux kernel documentation, firmware API introduction
- Linux kernel documentation, request_firmware API
- Linux kernel documentation, firmware lookup order
- Linux kernel documentation, firmware search paths
- Linux kernel documentation, direct filesystem lookup and initramfs
- Linux kernel documentation, built-in firmware
- Linux kernel documentation, firmware cache
- Linux kernel documentation, fallback mechanisms
- Linux kernel documentation, firmware upload API
- Linux kernel source, firmware_loader Kconfig
- Linux kernel MAINTAINERS file
- Linux kernel documentation, i915 driver (GuC and HuC)
- Linux kernel documentation, xe firmware
- Linux kernel documentation, x86 microcode loader
- Linux kernel documentation, kernel module signing
- Linux kernel ABI documentation, IMA policy
- Debian, General Resolution: non-free firmware (2022)
- Debian, Debian 12 bookworm released
- Debian 12 release notes, what is new
- Debian package tracker, firmware-nonfree
- Launchpad, linux-firmware package in Ubuntu
- Arch Linux, linux-firmware package
- LVFS, home page
- LVFS documentation, introduction
- LVFS documentation, uploading firmware
- LVFS documentation, metadata
- NIST SP 800-193, Platform Firmware Resiliency Guidelines
- NIST SP 800-147B, BIOS Protection Guidelines for Servers
Last reviewed: 25 October 2026.