Creating a Custom Initramfs

Updated

October 30, 2026

Creating a Custom Initramfs

The initramfs (Initial RAM Filesystem) is a compressed CPIO archive containing a complete, tiny userspace environment that the bootloader loads into physical RAM alongside the kernel image.

+-----------------------------------------------------------+
|               Inside the initramfs Archive                |
|                                                           |
|  /init                 (Executable shell script or binary)|
|  /bin/busybox          (Single static binary: sh, mount)  |
|  /lib/modules/.../*.ko (Storage & filesystem drivers)     |
|  /dev/console, /dev/null                                  |
|  /newroot              (Mount point for real root disk)   |
+-----------------------------------------------------------+

Why an Initramfs is Necessary

In a simple development setup, the kernel could mount /dev/sda1 directly if its driver was compiled statically (=y). But in real-world systems, mounting the root filesystem requires complex userspace logic: - The disk might be an encrypted LUKS volume requiring a password prompt or TPM2 key unsealing. - The root might be an LVM logical volume or mdadm software RAID requiring scanning and activation. - The root might be on an NFS share or iSCSI SAN requiring DHCP lease acquisition. - Hardware device nodes are dynamic and require udev or mdev to settle.

The kernel delegates all this complexity to an early userspace script: /init.

Building a Minimal Initramfs by Hand

To truly understand how early boot works, we will construct a custom initramfs using BusyBox:

Step 1: Create the Directory Tree

$ mkdir -p initramfs-root/{bin,sbin,etc,proc,sys,dev,newroot}

Step 2: Install BusyBox

Copy a statically linked busybox binary and create symlinks:

$ cp /bin/busybox initramfs-root/bin/
$ cd initramfs-root/bin
$ ln -s busybox sh
$ ln -s busybox mount
$ ln -s busybox umount
$ ln -s busybox switch_root
$ ln -s busybox sleep
$ cd ../..

Step 3: Write the /init Script

Create an executable script at initramfs-root/init:

#!/bin/sh
# /init — BYOL Early Userspace Boot Script
echo "========================================="
echo "   Welcome to BYOL Linux (Early Boot)    "
echo "========================================="

# 1. Mount virtual kernel filesystems
mount -t proc none /proc
mount -t sysfs none /sys
mount -t devtmpfs none /dev

# 2. Parse kernel command line for root= parameter
ROOT_DEV=""
for param in $(cat /proc/cmdline); do
    case "$param" in
        root=*) ROOT_DEV="${param#root=}" ;;
    esac
done

echo "[initramfs] Mounting real root: $ROOT_DEV to /newroot..."
# Wait for storage devices to settle
sleep 1

# 3. Mount real root disk
mount -o ro "$ROOT_DEV" /newroot
if [ $? -ne 0 ]; then
    echo "[initramfs] FATAL: Failed to mount root filesystem!"
    echo "[initramfs] Dropping into rescue emergency shell..."
    exec /bin/sh
fi

# 4. Clean up mounts before switch_root
umount /proc
umount /sys
umount /dev

# 5. Pivot into permanent rootfs and invoke real PID 1
echo "[initramfs] Handing execution over to /sbin/init..."
exec switch_root /newroot /sbin/init

Ensure the script has executable permissions:

$ chmod +x initramfs-root/init

Step 4: Pack into a Compressed CPIO Archive

The kernel expects the archive in standard newc CPIO format:

$ cd initramfs-root
$ find . -print0 | cpio --null --create --format=newc | gzip -9 > ../initramfs.img

In under 2 megabytes, you have engineered a fully functional early boot environment!