Peios Learn
Products
PePeios pkpekit PvProvium UDUniversal Directory TrTrail Ckclackatoo PrProject WiWispist
Using Peios Security Basics Technical Documentation Source
Using Peios Security Basics Technical Documentation Source
Peios

Device firmware

Single-page view · as markdown

Device firmware

Peios / Peios technical reference / Device firmware

Many devices carry no firmware of their own: the driver has to upload a vendor-supplied blob into the device before it does anything. Almost every Wi-Fi adapter works this way, as do modern GPUs (AMD, Intel, NVIDIA), many Ethernet controllers, laptop audio codecs and amplifiers, and Bluetooth. Without the blob the driver loads, finds the device, asks the kernel for a file under /usr/lib/firmware/, and — if it is not there — gives up. The symptom is a device that is present (lspci lists it, the module is loaded) but never comes up, and a line in dmesg like firmware: failed to load iwlwifi-so-a0-gf-a0-89.ucode (-2).

The kernel loads firmware itself. There is no daemon and no udev step involved: the driver's request is answered from the filesystem, transparently decompressing the .zst files Peios ships. That makes firmware a packaging matter — the right file in the right place — and this page is about which package that is.

The org.kernel.linux-firmware-<family> packages #

Upstream collects device firmware in one tree, linux-firmware, which is over a gigabyte and mostly for hardware Peios does not run on. Peios does not ship it whole. One recipe builds it into packages by vendor or driver family, each carrying only that family's blobs and only that family's licence texts:

PackageCovers
org.kernel.linux-firmware-iwlwifiIntel Wi-Fi
org.kernel.linux-firmware-atherosQualcomm Atheros Wi-Fi and Bluetooth (ath9k, ath10k/11k/12k, btqca)
org.kernel.linux-firmware-mediatekMediaTek Wi-Fi and Bluetooth (mt76, mt79xx)
org.kernel.linux-firmware-realtekRealtek Wi-Fi, Bluetooth, USB/PCIe Ethernet
org.kernel.linux-firmware-broadcomBroadcom and Cypress Wi-Fi, Bluetooth, tg3/bnx2 Ethernet
org.kernel.linux-firmware-marvellMarvell and NXP Wi-Fi and Bluetooth (mwifiex, libertas)
org.kernel.linux-firmware-ralinkRalink rt2x00 Wi-Fi
org.kernel.linux-firmware-amd-graphicsAMD Radeon GPUs (amdgpu, radeon)
org.kernel.linux-firmware-amd-platformAMD PSP/SEV, Platform Management Framework, XDNA NPU
org.kernel.linux-firmware-intel-graphicsIntel GPUs (i915, xe: GuC, HuC, DMC)
org.kernel.linux-firmware-intel-platformIntel Bluetooth, sensor hub, IPU cameras, NPU, QAT, E800 NICs
org.kernel.linux-firmware-intel-soundIntel audio DSP firmware for pre-2019 parts (AVS, catpt, Skylake SST)
org.sofproject.sof-firmwareIntel Sound Open Firmware — the audio DSP firmware, loadable modules and topologies for Ice Lake and newer (from SOF's own release, not linux-firmware)
org.kernel.linux-firmware-nvidia-graphicsNVIDIA GPUs for nouveau/nova (GSP)
org.kernel.linux-firmware-audio-codecsCirrus, TI and Creative laptop codecs and amplifiers
org.kernel.linux-firmware-nicWired NICs: Chelsio, QLogic qed, Myricom, Tehuti, 3Com, legacy USB Ethernet
org.kernel.linux-firmware-storageFC/SCSI HBAs (qla2xxx, QLogic BR, AdvanSys) and the ENE card reader
org.kernel.linux-firmware-miscUSB serial adapters, DVB/V4L tuners, legacy Wi-Fi, PCMCIA, sound cards

The names are the canonical reverse-DNS ones. Each package also provides the shorter firmware-<family> name it shipped under first, so an image manifest or an install command written against firmware-iwlwifi still resolves; that is a migration capability, not a second package.

Which ones a machine needs is a question about its hardware, and the answer is usually two or three: an Intel laptop wants org.kernel.linux-firmware-iwlwifi, org.kernel.linux-firmware-intel-graphics, org.kernel.linux-firmware-intel-platform (Bluetooth), org.sofproject.sof-firmware (audio DSP) and org.kernel.linux-firmware-audio-codecs; an AMD one swaps the graphics and platform packages. dmesg | grep firmware after boot names every file a driver asked for and did not get, and the file's directory (intel/, amdgpu/, rtw89/) maps onto the table.

Every package installs under /usr/lib/firmware/, which is where the kernel looks (it reads /lib/firmware, and /lib is a view of /usr/lib). The blobs are zstd-compressed on disk; the kernel decompresses them on load and no tool needs to know.

Licensing, and license_class = "firmware" #

Firmware blobs are almost never free software. Vendors permit redistribution of the unmodified binary and nothing more, each under their own terms, and there is no source. Peios does not pretend otherwise: each org.kernel.linux-firmware-<family> package declares its vendor licences as LicenseRef- SPDX identifiers and carries license_class = "firmware" in its manifest.

The licences come from upstream's WHENCE manifest, file by file. Each package's SPDX expression is derived from exactly the licences its own files cite, vendor terms and the GPL, MIT or Apache texts a few blobs are under alike. Those texts are shipped under /usr/share/licenses/org.kernel.linux-firmware-<family>/, together with a WHENCE excerpt: upstream's own licence statements and copyright notices for every entry the package draws on, verbatim. Where upstream hedges ("Allegedly GPL, but no source visible"), the excerpt keeps that wording rather than stating more than upstream does.

That class is the machine-readable fact. peipkg info org.kernel.linux-firmware-iwlwifi shows it, a composed image's /usr/share/licenses.json lists it for every package, and it is what lets a tool answer "what non-free is on this machine" without parsing licence expressions. firmware is a class of its own — distinct from proprietary — because it is a different bargain: it does not run on the CPU, it is needed to use hardware you already own, and you cannot get it any other way. Peios ships firmware and does not ship proprietary userspace; the class is how an image policy can say exactly that.

Trust #

Firmware runs on a device that can DMA into host memory, so a tampered blob is a compromise of the whole system — at least as bad as an unsigned binary running with kernel privilege, and it happens without an exec for the kernel to intercept. Peios treats firmware as part of the trusted computing base and signs it the same way it signs TCB binaries.

Every blob in every org.kernel.linux-firmware-<family> package carries an ML-DSA-65 signature made with the TCB key when the package is built. Blobs are not ELF, so the signature travels as a <blob>.peios.sig entry beside the blob in the package, and peipkg turns it into the file's security.peios.sig extended attribute as it installs the blob (see Signature format). The kernel verifies that attribute every time a driver asks for firmware, on the exact bytes it is about to hand to the device, and refuses a file that is unsigned, altered, or signed with a key below the TCB tier. The signature covers the compressed .zst bytes as they sit on disk, so verification happens before decompression.

In 2026.8 the check runs in log mode: a file that would be refused is reported to the kernel log and still loaded, so a system can be brought up on a mixed firmware set and the gaps found. Refusal becomes the default in the release after the whole farm has shipped signed; until then kacs_fwsig=enforce on the kernel command line turns it on for a boot, and kacs_fwsig=log turns it back off. Either way, /usr/lib/firmware is not a place to put files by hand: an unsigned blob dropped there, or one placed on a path added to the loader's search list, is exactly what the check exists to catch.

What is not shipped #

The upstream tree also carries firmware for ARM SoCs (Qualcomm, MediaTek video processors, Rockchip, Amlogic, NXP i.MX), datacentre switches and SmartNICs (Mellanox, Netronome), InfiniBand and crypto accelerators. None of it is packaged: Peios is x86-64, and a family is only added when there is hardware to use it. CPU microcode is a separate mechanism entirely — intel-ucode and com.amd.amd-ucode are early-loaded from the initramfs before the firmware loader exists.

Nothing under /usr/lib/firmware is needed to reach a root filesystem (NVMe, AHCI, USB and virtio storage need no blobs), so the initramfs carries no firmware. A driver that probes in the initramfs and cannot find its blob is re-probed once the real root is mounted and the device manager replays device events.

Intel Sound Open Firmware is not in linux-firmware at all; it is a separate upstream (thesofproject's sof-bin), which is why it is its own package, org.sofproject.sof-firmware, rather than a family of the linux-firmware recipe. The old firmware-intel-sof name remains a migration capability, not the package's canonical identity. Only the Intel-signed images ship — the community builds signed with the public development key run only on Chromebooks and development boards whose DSPs accept that key. Install org.sofproject.sof-firmware-debug separately when DSP debugging tools need the much less commonly used .ldc data.

Peios Learn — documentation for the Peios project.

Built with Trail.