Slimming Down Linux Firmware Packages: Saving About 450 MB per N100 Node
This article was last updated on: November 9, 2026 pm
Introduction
One note up front: the operations described in this article were actually performed before the Ubuntu 26.04 upgrade.
I got the itch again recently and started tinkering with those four N100 mini PCs in my HomeLab.
My biggest regret with this HomeLab is that I followed upstream and gave the system only 64 GB of storage, leaving all the remaining space on the 1 TB drive to Rook Ceph. Now the system space is stretched thin — once container images, apt packages, caches, and so on pile up, disk usage easily climbs past 85%. 🤣
They run Ubuntu 24.04.5 + K3s, and I had made the system disk painfully tight. One day I ran df -h and saw the root partition approaching the red line again. Digging further with dpkg -l | grep firmware, what do you know — a whole pile of vendor firmware packages for hardware I don’t even have was sitting comfortably in /lib/firmware, gathering dust.
Starting with Ubuntu 24.04, linux-firmware is no longer a single big package. It has become a meta package that pulls in 18 vendor subpackages. 26.04.1 keeps the same layout. The problem is: these four machines only have Intel integrated graphics, Intel wireless, and Realtek NICs — the rest, NVIDIA, Mellanox, Marvell, Qualcomm… are all just along for the ride.
Clearing them out saves about 450 MB per node, and as a bonus I no longer have to download firmware updates for those vendors. Sounds great, but honestly, in my first attempt I almost killed kernel upgrades on the nodes. 😂
📝Disclaimer: The operations in this article are based on my own four-node HomeLab environment, not a general-purpose distribution guide. Check your own hardware inventory before you start.
First, a Look at What Ubuntu 24.04 Firmware Packages Look Like
The post-split structure looks roughly like this:
| Type | Package name | Description |
|---|---|---|
| Meta package | linux-firmware |
Empty shell, depends on 18 vendor subpackages |
| Subpackage | linux-firmware-<vendor>-<type> |
Actually installs the firmware files |
| Standalone package | firmware-sof-signed |
Sound card DSP firmware, not part of the meta package |
| Microcode | amd64-microcode |
Note: this one is a trap too, more on that later |
The key point: the meta package itself has no content; it’s just a dependency entry point. And linux-image-generic depends on this meta package. Every bit of trouble that follows starts here.
The Trap: Why You Can’t Just apt remove
My initial idea was very simple: remove whatever I don’t need.
1 | |
The moment I hit Enter, the solution apt proposed made my scalp tingle: it wanted to remove the linux-firmware meta package along with it, then linux-generic, then linux-image-generic.
📝Notes: This means the node would silently stop receiving kernel upgrades. Not an error, not a warning — just that
apt upgradewould never update the kernel again. By the time you remember you need to apply a kernel CVE patch, you’ll discover the machine has been left behind for months.
This is a “buried landmine” failure: everything is fine right now, and by the time it explodes you’ve already forgotten what you did. 👎
The Right Approach: Replace the Meta Package with a Stub in the Same Transaction
The idea is actually clear: since what linux-image-generic needs is “something that satisfies the linux-firmware dependency,” I just have to give it an empty shell.
Ubuntu provides linux-firmware-minimal, an empty stub package that declares Conflicts/Replaces/Provides: linux-firmware. By installing it in the same apt transaction, apt can satisfy the meta package’s dependency while clearing out all 18 subpackages at once, without touching linux-image-generic.
1 | |
The --no-install-recommends step is mandatory, not optional. That’s because linux-firmware-minimal recommends all 18 subpackages. Without this flag, apt will enthusiastically reinstall the firmware you just removed, and all your work is wasted. 🫣
Keep and Remove List
This is the actual trade-off across my four N100 nodes, for reference:
Keep (around 300 MB)
| Package | Reason to keep |
|---|---|
linux-firmware-intel-graphics |
The kernel command line sets i915.enable_guc=2, which requires i915 GuC/HuC firmware |
linux-firmware-intel-misc |
Miscellaneous Intel platform firmware |
linux-firmware-intel-wireless |
iwlwifi and Bluetooth, CNVi 8086:54f0 / the jumper node’s AX201 |
linux-firmware-misc |
Generic firmware, not large, kept as a fallback |
linux-firmware-realtek |
The jumper node’s RTL8111 / RTL8125 NICs |
linux-firmware-amd-misc |
Only 257 KB, not worth fussing over |
firmware-sof-signed |
Standalone package, sound card DSP |
Remove (about 450 MB total)
| Package | Size | Reason |
|---|---|---|
linux-firmware-nvidia-graphics |
106 MB | No NVIDIA cards in the cluster |
linux-firmware-mellanox-spectrum |
79 MB | No Mellanox NICs |
linux-firmware-marvell-prestera |
73 MB | No Marvell DPUs |
linux-firmware-qualcomm-misc |
59 MB | No Qualcomm hardware |
linux-firmware-qualcomm-wireless |
47 MB | Same as above |
linux-firmware-amd-graphics |
29 MB | No AMD discrete GPU |
linux-firmware-mediatek |
24 MB | No MediaTek hardware |
linux-firmware-qlogic |
13 MB | No QLogic HBAs |
linux-firmware-broadcom-wireless |
11 MB | No Broadcom wireless |
linux-firmware-marvell-wireless |
7 MB | Same as above |
linux-firmware-qualcomm-graphics |
7 MB | Same as above |
linux-firmware-netronome |
6 MB | Same as above |
The judgment criterion is one sentence: whatever hardware the audit report doesn’t recognize, its corresponding firmware does not stay.
Wrapped into Three Steps: audit / plan / apply
Typing it by hand once is fine, but going back and forth across four nodes is pure self-torture. I wrapped it into scripts/firmware-slim, with three steps:
1 | |
The plan step is the one I value most: it uses apt-get -s to simulate, and as soon as it finds that the transaction would remove linux-generic or linux-image-generic, it refuses to continue. This effectively hard-codes that earlier “silently losing kernel upgrades” landmine into a gate. 👍
apply then runs node by node in sequence: apt-mark manual to pin the packages to keep → re-run the simulation → abort on anything abnormal → run the install → print the remaining firmware packages, the linux-image-generic status, and disk usage.
Two Post-Change Safeguards — Don’t Cut Corners
First, don’t run apt autoremove.
Once the meta package is gone, apt considers those kept subpackages “no longer needed.” One autoremove and the i915 and Wi-Fi firmware are gone. After a reboot you’ll most likely get a black screen or no network, and you may not even connect the dots to deleted firmware right away. That’s why the script first pins the kept packages with apt-mark manual.
Second, leave amd64-microcode alone.
It looks harmless, but it is likewise a dependency of linux-image-generic. Remove it and you’ll hit exactly the same knock-on problem as with the linux-firmware meta package. Just leave it as is.
Verification and Rollback
Don’t close the terminal right after the change; verify in order:
1 | |
🐾 Note: If you add new hardware to a node later (say, you plug in an NVIDIA card), just install the corresponding subpackage back; no need to reboot the whole cluster. But don’t take the lazy route and reinstall the
linux-firmwaremeta package — it conflicts withlinux-firmware-minimaland will pull all 18 subpackages back at once, undoing everything.
Summary
Looking back, the real technical difficulty wasn’t “which package to delete” but figuring out apt’s dependency graph:
- Since Ubuntu 24.04,
linux-firmwareis a meta package, andlinux-image-genericdepends on it - Directly
apt remove-ing subpackages = removing the kernel upgrade path as well, silently planting a landmine - The correct approach is to install the
linux-firmware-minimalstub package in the same transaction, and--no-install-recommendsis mandatory - Afterward,
apt-mark manual+ not runningautoremoveis what protects the firmware you keep amd64-microcodeis equally untouchable, for exactly the same reason
Four nodes, about 450 MB saved on each, plus fewer downloads of vendor firmware updates you’ll never use. For a HomeLab where every inch of storage has to be budgeted carefully, that’s a pretty good deal.
“Prune the complex to the simple, like a tree in autumn” — the same principle applies to firmware.
That’s all.
📚️References:
- Ubuntu
linux-firmwarepackage split notes (Ubuntu Packages / Launchpad) apt-mark(8),apt-get(8)man pages- The
east4ming/homelab2repository’sscripts/firmware-slimscript source - Ubuntu 24.04 splits firmware packages for faster updates