How initramfs-tools Generates Debian Boot Images
In the Debian operating system, initramfs-tools is the
standard utility suite responsible for generating the initial RAM
filesystem (initrd.img) required during the system boot
sequence. This article explains how initramfs-tools reads
system configurations, aggregates necessary kernel modules and system
binaries, executes modular build hooks, and compiles the final
compressed CPIO archive that the bootloader hands over to the Linux
kernel.
The Invocation Trigger
The generation process begins either automatically via package
manager hooks during kernel updates or manually when a system
administrator runs update-initramfs -u. The
update-initramfs wrapper manages existing images,
determines the target kernel version, and delegates the low-level build
work to the core script: mkinitramfs.
Configuration Parsing
Before compiling files, mkinitramfs reads system-wide
settings from /etc/initramfs-tools/initramfs.conf and
modular drop-in files inside /etc/initramfs-tools/conf.d/.
These files define crucial build parameters:
- MODULES setting: Determines the scope of kernel
drivers to include. Options include
most(maximum hardware compatibility),dep(only modules matching currently detected hardware),netboot(network boot modules), orlist(only specifically listed drivers). - COMPRESS option: Defines the compression algorithm
(such as
zstd,gzip, orxz) used for the final archive. - BUSYBOX: Specifies whether to embed the static
busyboxbinary to provide core shell utilities inside the early userspace.
Explicitly required drivers are also loaded from
/etc/initramfs-tools/modules.
Staging the Filesystem Hierarchy
mkinitramfs creates a temporary directory that acts as
the root (/) of the upcoming initramfs. It constructs the
standard Linux directory layout (/bin, /sbin,
/usr/bin, /etc, /dev,
/sys, /proc, /run) and deploys
the master /init script located at
/usr/share/initramfs-tools/init. This /init
script is the first process the kernel executes upon mounting the RAM
disk.
Executing Hook Scripts
To populate the staging environment with system tools, storage
drivers, and cryptography utilities, mkinitramfs executes
hook scripts found in two primary locations:
/usr/share/initramfs-tools/hooks/(system and package hooks)/etc/initramfs-tools/hooks/(local administrator hooks)
Packages such as cryptsetup, lvm2,
mdadm, and systemd install their own hooks.
These scripts rely on helper functions provided by
/usr/share/initramfs-tools/hook-functions, most notably
copy_exec. The copy_exec function
automatically resolves shared library dependencies (ldd)
for any binary, copying both the executable and its required shared
objects (.so files) into the staging tree.
Resolving and Adding Kernel Modules
Based on the configured MODULES mode,
mkinitramfs inspects
/lib/modules/<kernel-version>/. It resolves internal
dependencies among drivers using modprobe and
modules.dep. Essential storage controllers, filesystem
drivers (e.g., ext4, btrfs), input drivers, and cryptographic helpers
are copied into the staging directory alongside their corresponding
modules.builtin and map files.
Deploying Boot Scripts
The initramfs requires a framework to order actions at boot time.
mkinitramfs copies modular boot scripts into directories
within the image:
scripts/init-top: Early device discovery and preparation.scripts/init-premount: Runs before any filesystem checks or partition assembly.scripts/local-top/scripts/nfs-top: Unlocks encrypted partitions, activates LVM volume groups, or configures the network interface.scripts/local-premount/scripts/nfs-premount: Runs filesystem integrity checks (fsck).scripts/local-bottom/scripts/nfs-bottom: Cleans up tasks right before root handover.
Packaging and Compression
Once all binaries, configurations, modules, and scripts reside in the
temporary directory, mkinitramfs pipes the directory tree
into cpio to create an uncompressed archive. This stream is
immediately routed through the configured compression utility (commonly
zstd on modern Debian installations).
The compressed stream is written directly to
/boot/initrd.img-<kernel-version>. If configured, an
early microcode archive (containing CPU updates for AMD or Intel
processors) is prepended to the final image, completing the build
process and leaving the system ready for the bootloader.