In Linux, the initrd (initial RAM disk) and initramfs (initial RAM File System) commands are different methods we can use to load a temporary root file system to the RAM or system memory for successful booting.
We need either an initrd or initramfs file system to load the kernel into memory and mount the root file system on the hard disk from memory.
We can use initrd or initramfs to make preparations, such as starting the kernel and setting up hardware devices before mounting the real root file system (on system hard disk or storage).
2. What Is initrd?
initrd gives us the ability to load a RAM disk by the bootloader. The loaded RAM disk is mounted as the root file system, and different programs are run from it. We can also mount a new root file system from a different device, making the bootloader move the former initrd root to a different directory, and we can unmount it.
The primary design of initrd was to allow our system startup to occur in two preceding phases:
- The kernel allocates a minimum set of compiled-in drivers
- Loading of additional modules from initrd
initrd usually functions as a block device, and compiling it into the kernel requires a file system driver such as ext2, ext3, or ext4.
For the kernel to successfully detect the file system of initrd, it must have at least one built-in module available.
All of the common operations of reading and writing on an initrd image are buffered inefficiently to our system’s main memory because the initrd disk has a fixed size.
NOTE: initrd was deprecated and replaced by initramfs.
2.1. Boot Process With initrd
Let’s take a look at a more detailed explanation of the initrd boot process:
- The bootloader loads the kernel and initial RAM disk.
- The kernel converts initrd to a RAM disk. Furthermore, it clears the memory that initrd was using.
- The kernel searches for the root device in the /dev/ram0 file path, and if not found, the kernel follows the change_root procedure.
- If found in the /dev/ram0 directory, it is mounted as the root file system.
- Init loads the real file system and moves the root file system to the directory using the pivot_root system call.
- Init executes /sbin/init on the newly created root file system, performing the usual boot sequence.
- The bootloader disconnects the initrd file system.
Note: Changing our root directory does not necessarily involve unmounting it. This makes it possible for us to leave processes running on initrd throughout the procedure. Moreover, we can easily access file systems mounted under initrd.
2.2. How to Access initrd
Let’s create a new directory and copy the initrd.img file from /boot/:
$ mkdir initrd_test $ cd initrd_test $ cp /boot/initrd.img . $ ls initrd.img
Some systems like Debian require us to first extract the initrd file. Let’s rename the file to have the .gz extension so we can extract it. Furthermore, let’s use file to make sure the decompressed file is, in fact, in CPID format:
$ mv initrd.img initrd.img.gz $ gunzip initrd.img.gz $ file initrd.img initrd.img: ASCII cpio archive (SVR4 with no CRC)
Let’s use the cpio command to extract the image:
$ cpio -id < initrd.img 62 blocks $ ls initrd.img kernel
We extracted the contents of the initrd.img file on a Linux Ubuntu OS. The number of files we get after extracting may vary depending on our Linux distribution.
3. What Is initramfs?
initramfs is a cpio archive file of the initial file system that is loaded to memory. This loading happens after the kernel finishes starting the system, and before the user-space begins the init procedure.
The contents of initramfs are loaded as the initial root file system by the kernel before the main root is loaded. The initial root contains the files that are required to mount the “real” root file system and initialize our system. The files mostly contain kernel modules.
The Linux kernel is compatible and adaptive. This allows it to support the features like dynamic loading and unloading of files. Several parts of the kernel can be converted into modules, allowing Linux systems to build kernels with only the bare essentials compiled into the main kernel. Furthermore, providing functionality for every other possible feature or hardware as a module, allowing us to load or unload them as required.
initramfs also allows the kernel to access the modules from a special RAM file system. This makes it possible to access root file systems from a disk or a separate file system.
3.1. How initramfs Works
initramfs is provided as a compressed cpio archive.
Prepending the image with a decompressed cpio archive containing the microcode data loaded early in the booting process is possible.
During boot, the kernel follows this process:
- If we have a compressed cpio archive existing during the start of the initramfs, it will extract it and load the microcode data from it to the CPU.
- If we have an uncompressed cpio archive existing during the start of the initramfs, it will skip the archive and set the rest of the file as the basic initramfs. Conversely, it treats the whole initramfs as the basic initramfs.
- It will unpack the basic initramfs into a RAM-based disk by treating it as a compressed (gzip on Debian, LZ4 on Ubuntu) cpio archive file.
From there, most of the kernel initialization and bootstrap code will be moved into this disk and run in user mode. Other processes similarly moved from the kernel include:
- boot-time networking setup
- Finding the real root disk
- ACPI setup
- Handling of initrd-style RAM disks
3.2. Advantages of initramfs
Customization of the early boot processes becomes much easier. We can achieve this with user-space code, which removes the requirement of patching the kernel to change how our system boots.
Moving the initialization code into the user-space makes it easier to write code.
We require user-space code to deal with the kernel via system calls, resulting in a cleaner and safer code.
3.3. How to Access initramfs
We can also use unmkinitramfs to extract the files from initramfs.
Let’s assume that path/to/initrd already exists as an empty directory and the output file /initrd.img is an ASCII cpio archive (SVR4 with no CRC).
We’ll consider the initrd image to have the microcode prepended. Let’s extract the microcode and read the STDERR display:
$ cd path/to/initrd/ $ cpio -i < /initrd.img 62 blocks
We can extract the basic initrd by:
$ cd path/to/initrd/ $ dd if=/initrd.img of=initrd.img bs =512 skip=62 $ zcat initrd.img | cpio -i
Note: We should adjust skip values to match the cpio STDERR output.
Let’s check the microcode cpio archive size:
$ cpio -t </initrd.img >/dev/null
4. Differences Between initrd and initramfs
We can use initrd for Linux kernels 2.4 and lower. Conversely, initramfs is for kernels 2.6 and above.
Compiling initrd into the kernel requires at least one filesystem driver, which increases boot-time flexibility, simplicity, and memory efficiency.
With initramfs, we can create an archive with the files that the kernel will extract to a tmpfs, which makes file access extremely fast.
In this tutorial, we’ve taken a closer look at what initrd and initramfs mean and how to differentiate them. We also looked at the key role they both play during the booting process in different kernel versions. Moreover, we’ve also tackled how we can locate, extract, and list out their contents.