Skip to content

initrd and RAM Disk Filesystems

An initrd (initial ramdisk) is a small filesystem image loaded entirely into memory before the kernel mounts its real root filesystem, solving a chicken-and-egg problem Multiboot and Physical Memory both already mention modules and a ramdisk for without explaining why one is needed at all: the driver for the real root filesystem (an AHCI driver, for instance) can itself depend on modules or firmware that only exist inside that same root filesystem, a circular dependency with no way to resolve itself from a cold start.

A kernel built with every driver statically linked in avoids this problem entirely, but at the cost of a large, inflexible binary that has to be rebuilt for any hardware change; a kernel that instead loads drivers as separate modules from its root filesystem, a common and considerably more flexible design, runs directly into the circularity: it cannot mount the root filesystem without the storage driver, and it cannot load the storage driver without first having access to the filesystem that driver’s module file lives on. The same problem shows up whenever any early-boot requirement (decrypting an encrypted root volume, assembling a software RAID array, or simply picking which of several available root devices to actually use) needs code or configuration that would otherwise have to live on the very volume that requirement is blocking access to.

An initrd breaks this cycle by never depending on the eventual root filesystem’s own driver at all: the bootloader loads a small filesystem image as a Multiboot module directly into memory alongside the kernel itself, before the kernel has run a single instruction, and the kernel mounts that image from RAM using a filesystem driver simple enough to have no external dependencies of its own (a minimal read-only format, or even an uncompressed archive format like cpio, rather than a full-featured filesystem). Because the image is already sitting in memory, reachable the same way any other boot-time data structure is, mounting it needs no storage driver, no PCI enumeration, and no I/O of any kind beyond reading memory that’s already there.

// simplified: locate the module the bootloader already loaded
struct multiboot_module *mod = &mb_info->modules[0];
void *initrd_start = (void *)mod->mod_start;
size_t initrd_size = mod->mod_end - mod->mod_start;
mount_ramdisk(initrd_start, initrd_size);

With the initrd mounted, the kernel now has a filesystem, however minimal, to load the real storage driver’s module from, along with whatever else early boot needs (firmware blobs, a RAID assembly tool, a decryption key prompt) that would otherwise have been unreachable. Once that real driver is loaded and initialized, and the actual root filesystem it manages can be mounted, the kernel performs a pivot root (or switch root): the real filesystem takes over as /, and the temporary ramdisk, its job finished, is typically discarded or unmounted entirely rather than persisting alongside the real root.

An initrd’s own filesystem format is deliberately kept simple, since its driver has to be built directly into the kernel with no dependency on anything the initrd itself might otherwise provide, an early-boot chicken-and-egg problem one level up from the one initrd solves for the real root; a compressed cpio archive (the initramfs format) or a minimal read-only image are both common choices specifically because a driver for either is small enough to justify permanently linking into the kernel binary rather than loading as a module. The pivot/switch root step itself, handled once the real filesystem is available, is exactly the kind of operation the VFS layer’s mount abstraction is built to support: from a caller’s perspective the root of the filesystem tree simply changes to point at a different mounted filesystem, without anything above the VFS needing special-case logic for the fact that an initrd preceded it at all.

  1. ^ The Linux Kernel Documentation, initrd: Initial RAM disk: describes the boot-time role and loading mechanism this article’s general problem statement applies broadly beyond the Linux-specific implementation.
  • Multiboot: the module mechanism that loads an initrd image into memory before the kernel starts running.
  • VFS: the mount abstraction the pivot/switch root step uses once the real filesystem is available.