Home / Alt manpages / mkinitramfs(8)

  • mkinitramfs(8)
  • Admin command
  • linux

Build and Check a Custom initramfs with mkinitramfs

You will finish with an initramfs image written to a scratch path, a clear view of what it contains, and a safe way to choose its kernel version and compression. The examples use mkinitramfs from initramfs-tools-core 0.142ubuntu25.8, installed on Ubuntu at the time of writing.

Allow 15 to 30 minutes. You need a shell, enough space for a temporary image, and the matching kernel files under /lib/modules. This guide creates a separate file. It does not install an image, alter the bootloader or replace anything under /boot. Most inspection commands can run as an ordinary user; use elevated privileges only when your chosen output directory requires them.

Safety boundary

Do not point the output at a filename already used by a boot entry until you have checked the path, kernel version and contents. A bad initramfs can prevent a machine from reaching its normal root filesystem.

1. Check the installed tool and its required option

The low-level command requires -o and an output filename. With no version argument it builds for the running kernel. Check the local help before copying a command into a script:

$ mkinitramfs --help
Usage: mkinitramfs [option]... -o outfile [version]

Options:
  -c compress    Override COMPRESS setting in initramfs.conf.
  -d confdir     Specify an alternative configuration directory.
  -l level       Override COMPRESSLEVEL setting in initramfs.conf.
  -k             Keep temporary directory used to make the image.
  -o outfile     Write to outfile.
  -r root        Override ROOT setting in initramfs.conf.

The installed script accepts --help, but it does not expose a useful version-reporting option. Record the package version instead:

$ dpkg-query -W -f='${Package} ${Version}\n' initramfs-tools-core
initramfs-tools-core 0.142ubuntu25.8

Checkpoint: the command should print usage with -o outfile. If mkinitramfs is missing, install or repair initramfs-tools-core using your normal package-management process before continuing.

2. Choose a scratch output path

Use a new file in a temporary directory while learning or testing. mktemp reserves the name, and the command then writes the image there:

out=$(mktemp /tmp/initramfs-test.XXXXXX.img)
mkinitramfs -o "$out" "$(uname -r)"
status=$?
printf 'exit status: %s\nimage: %s\n' "$status" "$out"
test "$status" -eq 0

The explicit kernel version makes the target visible in the command and avoids relying on a reader remembering which kernel is running. The version must have usable module data under /lib/modules/<version>. The resulting file is a compressed cpio archive, not a filesystem image that you mount directly.

On a successful run, the final line is exit status: 0 and the path names a non-empty file. If the build fails, keep the error output and do not use the file as a boot image. Check the requested version without changing anything:

$ printf 'running: '; uname -r
running: 6.8.0-XX-generic
$ test -d "/lib/modules/$(uname -r)" && echo 'module directory exists'
module directory exists

Replace XX only in explanatory output. In a real command, use the value printed by uname -r; do not type a guessed kernel version.

3. Understand the configuration that shapes the image

The main configuration file is /etc/initramfs-tools/initramfs.conf. Snippets in /etc/initramfs-tools/conf.d are read afterwards, so a snippet can override the main file. Read the effective inputs before diagnosing an unexpected result:

$ sed -n '1,220p' /etc/initramfs-tools/initramfs.conf
$ find /etc/initramfs-tools/conf.d -maxdepth 1 -type f -print -exec sed -n '1,80p' {} \;
$ sed -n '1,120p' /etc/initramfs-tools/modules

MODULES=most is the documented default. It adds common filesystem and storage drivers. dep tries to include modules needed by the running machine, netboot adds base and network support while skipping block devices, and list limits extra modules to the explicitly listed set. The modules file and files in /usr/share/initramfs-tools/modules.d are always included.

Other settings have practical boot consequences. BUSYBOX=n removes BusyBox even though many boot scripts need its utilities. RESUME=none disables hibernation resume; an unset or auto value selects the largest available swap partition. FSTYPE=auto detects the current root and /usr filesystem types. For an NFS root, BOOT=nfs and the NFS variables select the network setup.

Do not edit the system configuration just to test one image. Use -c, -l, -r or, for a complete alternate configuration tree, -d. Those command-line overrides are easier to review and undo.

4. Test compression without changing configuration

The installed configuration on this machine uses COMPRESS=zstd, but the command can override that for one build. For example:

out_lz4=$(mktemp /tmp/initramfs-lz4.XXXXXX.img)
mkinitramfs -c lz4 -l 1 -o "$out_lz4" "$(uname -r)"
printf 'exit status: %s\n' "$?"
file "$out_lz4"

-c selects the compression method and -l selects its level. The valid level range depends on the compressor. If the kernel lacks support for the configured format, or the corresponding userspace utility is unavailable, the tool falls back to gzip according to initramfs.conf(5). Do not infer the format from the filename extension: inspect the file.

The configuration also supports UMASK, which controls permissions on the generated image and can prevent embedded keys from being disclosed. Treat an initramfs as sensitive: it may contain credentials, keys or hardware-specific configuration.

5. Inspect the archive before using it

Use lsinitramfs to list the archive without unpacking it:

$ lsinitramfs "$out"
.
bin
bin/sh
conf
conf/arch.conf
conf/initramfs.conf
scripts
scripts/init-bottom
scripts/init-top

The exact list varies with the host, package version, kernel version and configuration. Look for the expected kernel modules, hooks and configuration rather than comparing the whole listing to a fixed transcript:

lsinitramfs "$out" | sed -n '1,80p'
lsinitramfs "$out" | grep -E '(^|/)(init|scripts|lib/modules/)' | sed -n '1,80p'
test -s "$out" && echo 'image is non-empty'

If the image is empty, missing, or does not contain the drivers needed to reach the root filesystem, stop here. Recheck the kernel version, MODULES, the modules file and any configuration snippets. Do not compensate by copying random drivers into the archive.

6. Clean up or promote the result carefully

Once you have finished checking a scratch image, remove only the exact temporary paths you created:

$ rm -- "$out" "$out_lz4"

This is irreversible for those files, so verify the variables first with printf '%s\n' "$out" "$out_lz4". If you need a boot image, the normal administration command is update-initramfs, which handles naming, hashes and backups for installed kernels. Do not copy a hand-built test image over an existing file unless you have a recovery path and have separately verified the target.

Checkpoint

A finished test has an exit status of zero, a non-empty archive, the intended kernel version, and a listing that contains the expected early-boot files. The original files under /boot remain unchanged.

Common failure traps

  • A missing output argument is a command-shape error, not a reason to edit configuration. Recheck -o and quote paths containing spaces.
  • A successful build does not prove that the machine can boot from it. Archive inspection checks contents; boot testing is a separate operational decision.
  • TMPDIR controls temporary build directories and defaults to /var/tmp. The directory must allow execution, so a noexec mount can make an otherwise valid build fail.
  • -k keeps the temporary build directory for debugging. It can contain sensitive material and consumes space, so use it deliberately and remove the exact retained directory after inspection.
  • SOURCE_DATE_EPOCH makes the tool attempt a reproducible image. Reproducibility does not make a mismatched kernel or incomplete driver set safe.

Done means

  • You built to a new scratch path for an explicit kernel version.
  • The command returned zero and produced a non-empty compressed cpio archive.
  • You checked effective configuration, including later conf.d overrides and requested modules.
  • You inspected the archive with lsinitramfs and confirmed the expected early-boot content.
  • You left installed boot images untouched, or used the normal update-initramfs workflow with a recovery plan.