XK0-006 · System Management · Updated July 26, 2026
initramfs, Bootloaders, and the Linux Boot Chain (Servers and Embedded Boards)
The initramfs (initial RAM filesystem) is a compressed cpio archive of drivers, tools, and an early init script that the bootloader loads into memory alongside the Linux kernel. Its job is to solve a chicken-and-egg problem: the kernel needs storage, RAID, LVM, or encryption drivers to mount the real root filesystem, but those drivers live on the root filesystem. The initramfs supplies them from RAM, mounts the real root, and hands control to it. When you install a new driver the root filesystem depends on, you must rebuild the initramfs — on Ubuntu, with update-initramfs -u.
The boot chain on a standard server
Every Linux boot walks the same conceptual ladder, whatever the hardware:
- Firmware — UEFI (or legacy BIOS) initializes the platform, runs its power-on self-test, and locates a bootloader: on UEFI systems, an
.efibinary on the EFI System Partition; on BIOS systems, code in the MBR. - Bootloader — GRUB2 on virtually all x86 servers. It presents the menu, then loads two things into RAM: the kernel image (
vmlinuz-<version>) and the matching initramfs image (initrd.img-<version>on Debian/Ubuntu,initramfs-<version>.imgon RHEL-family), both from/boot, and passes the kernel its command line (root=,ro,quiet…). - Kernel + initramfs — the kernel decompresses itself, unpacks the initramfs into a RAM-backed filesystem, and runs its init script. That script loads the storage-stack modules (NVMe, SCSI/HBA, dm-crypt, LVM, mdraid as needed), assembles any volumes, mounts the real root filesystem, then switches root onto it.
- PID 1 — the kernel-side handoff ends by executing
/sbin/initon the real root, which on modern distributions is systemd. From there, targets and units bring up services — that half of the story is covered in systemd targets and runlevels.
If the initramfs lacks a module the root filesystem needs — say root sits on a RAID controller whose driver was never included — boot dies in early userspace, typically at a (initramfs) rescue prompt or a “cannot find root device” panic. That failure signature is the tell that the problem is the initramfs image, not GRUB and not the installed system.
Rebuilding the initramfs
The image is generated per-kernel from what’s currently installed, so any change to the early-boot stack — new filesystem driver, storage controller module, changed /etc/crypttab, new firmware blob — requires regenerating it. The tooling differs by family:
| Debian/Ubuntu | RHEL/Fedora/Rocky | |
|---|---|---|
| Generator tool | update-initramfs (initramfs-tools) | dracut |
| Rebuild for the running kernel | update-initramfs -u (or -u -k $(uname -r)) | dracut -f |
| Rebuild for every installed kernel | update-initramfs -u -k all | dracut -f --regenerate-all |
| Create for a specific new kernel | update-initramfs -c -k <version> | dracut /boot/initramfs-<v>.img <v> |
| Inspect image contents | lsinitramfs /boot/initrd.img-$(uname -r) | lsinitrd |
| Config location | /etc/initramfs-tools/ | /etc/dracut.conf, /etc/dracut.conf.d/ |
So the Ubuntu answer to “a filesystem driver package was just installed; make it available at next boot” is sudo update-initramfs -u — the -u meaning update the existing image for the current kernel (add -k $(uname -r) to name the running kernel explicitly). Package hooks often trigger this automatically, but the exam wants you to know the manual command. On RHEL-family systems the equivalent reflex is dracut -f, with --force required because the target image already exists.
Because the image is a compressed cpio archive, you can also crack one open by hand — zcat (or unmkinitramfs on Ubuntu, which handles the multi-segment early/main layout) piped into cpio -idmv. If cpio’s role there seems odd, the format comparison in cpio vs tar explains why kernel tooling standardized on cpio.
Embedded boards: U-Boot and the device tree
On an ARM (or RISC-V/MIPS) development board there’s no UEFI and no GRUB. The near-universal replacement is Das U-Boot — the bootloader that runs before the Linux kernel, initializes fundamental hardware such as DRAM controllers, clocks, and a serial console, and then loads the kernel image and the device tree blob (DTB) into RAM before jumping to the kernel. (Strictly, a mask-ROM boot ROM and a tiny U-Boot SPL — Secondary Program Loader — run first to get DRAM working, then load full U-Boot; “the bootloader that sets up basic hardware and loads kernel + DTB” is U-Boot’s defining role.)
The device tree matters because embedded SoCs (systems-on-chip) aren’t self-describing the way PCI/USB hardware is: the kernel can’t probe to discover what peripherals exist at which addresses. The DTB — compiled from device tree source with dtc — is a data structure describing the board’s hardware layout, and U-Boot must place it in memory and pass its address to the kernel. Kernel + DTB (+ optionally an initramfs) is the standard embedded boot payload.
Cross-compilation: building for a different architecture
Embedded work adds one more concept the XK0-006 objectives call out. You rarely compile on a router or dev board — it’s slow and often lacks a toolchain. Instead you build on an x86_64 workstation using a cross-compiler (a cross-compilation toolchain): a compiler, linker, and C library that run on one architecture (the host) but emit binaries for another (the target). A MIPS-targeting toolchain on a PC uses prefixed tools like mips-linux-gnu-gcc; ARM equivalents look like aarch64-linux-gnu-gcc. The prefix names the target triplet. Contrast this with native compilation, where host and target architecture are the same. Build systems such as Buildroot and Yocto exist largely to generate and drive these toolchains for whole embedded images.
How the XK0-006 exam tests this
- A “which command” question: a driver or filesystem module was installed on Ubuntu and must be present at next boot — expecting
update-initramfs -u, withdracut -fappearing either as the RHEL variant or a distractor. - A boot-sequence ordering question — arrange firmware, bootloader, kernel/initramfs, and systemd correctly, or identify which stage a described failure lives in (an
(initramfs)prompt means early userspace, not GRUB). - An embedded scenario naming a component that runs before the kernel, brings up RAM/clocks, and loads the kernel and device tree blob — the answer being U-Boot, distinguished from GRUB (x86/UEFI world) and from the kernel itself.
- A terminology question about producing MIPS or ARM binaries from an x86_64 build machine — testing that you name a cross-compiler/cross-compilation toolchain, not an emulator, hypervisor, or interpreter.
Boot-chain material spans the System Management domain — see the full XK0-006 study guide for where it sits in the exam, then drill the boot sequence until ordering questions are free points.
Quick reference
- initramfs = compressed cpio archive in RAM providing the drivers and scripts needed to mount the real root filesystem.
- Ubuntu rebuild:
update-initramfs -u(current kernel),-u -k all(all kernels),-c -k <ver>(create new). RHEL:dracut -f. - Inspect with
lsinitramfs(Debian/Ubuntu) orlsinitrd(dracut systems). - Server chain: UEFI/BIOS → GRUB2 → kernel + initramfs → switch to real root → systemd (PID 1).
- “Cannot find root device” or an
(initramfs)prompt after a storage change → regenerate the image with the missing module. - Embedded chain: boot ROM → SPL → U-Boot → kernel + DTB (+ optional initramfs).
- Device tree blob (DTB): compiled hardware description U-Boot hands the kernel, because SoC peripherals aren’t probeable.
- Cross-compiler: runs on the host arch, emits target-arch binaries — e.g.
mips-linux-gnu-gccon x86_64.