Early Userspace Mounting

Because of bug #364235, I wanted to learn how to build a minimal initramfs to check the /usr filesystem, and pre-mount /usr. But for several reasons, I do not want to use any external tool like sys-kernel/dracut.

So I learned how to build an initramfs manually, using :
 * busybox
 * an initramfs list
 * the gen_init_cpio utility, provided by the kernel itself

The initramfs also contains the required libraries and binaries to run an ext4 fsck. Most of the code to run the fsck is coming from the /etc/init.d/fsck script.

If you are using any other filesystem other than ext4, you will need to add the required binaries/libraries into the initramfs list.

Basically, the init script is doing following actions :
 * 1) mounts readonly the root partition on /mnt/root.
 * 2) symlinks the fstab from the root partition to the initramfs environment.
 * 3) checks the filesystem of our /usr device using the embedded /sbin/fsck binary.
 * 4) mounts /usr, then move the /usr tree to /mnt/root/usr using the --move mount parameter.
 * 5) switchs to real root and executes init

My partition setup is really basic : 3 hard drives with several partitions. No lvm nor RAID. This means that if you need lvm or RAID to mount something, you will have to add some stuff into the initramfs.

Requirements
We will use busybox.

And gentoo-sources.

The kernel must already be built to have the gen_init_cpio utility.

Configuration
In /etc/fstab, we must set the sixth field for the /usr entry to 0.

This will prevent the openrc fsck init script to try to check the filesystem for the already mounted /usr. See also man fstab.

Files and scripts
The following files are installed into /usr/src/initramfs. This path is important, because it is hardcoded into the initramfs_list file.

gen_init_cpio.sh

initramfs_list

script_init.sh

Creating the initramfs
The gen_init_cpio.sh file is a simple shell script. It takes one parameter, which define the name of the initramfs list that we want to build the initramfs archive from.

When running it, the gziped initramfs archive is generated into the image child directory.

Setting up the bootloader
First we must copy the generated initramfs to /boot.

Then we can add the initrd line in grub.conf. grub.conf

Result
When booting, the output looks like this :

output of the initramfs when booting