Linux initrd and initramfs

After Linux kernel boots, it looks for root file system, which can be initrd or initramfs. They are two different ways.

linux init rootfs

initrd

  • ramdev block device is created. It is a ram-based block device, that is a simulated hard disk that uses memory instead of physical disks.
  • The initrd file is read and unzipped into the device, as if you did zcat initrd dd of=/dev/ram0 or something similar.
  • The initrd contains an image of a filesystem, so now you can mount the filesystem as usual: mount /dev/ram0 /root. Naturally, filesystems need a driver, so if you use ext2, the ext2 driver has to be compiled in-kernel.

Example to create ramdisk image:

 cat createramdisk.sh
#!/bin/bash

RDSIZE=400000
BLKSIZE=1024
# create raw disk image first
dd if=/dev/zero of=/tmp/ramdisk.img bs=$BLKSIZE count=$RDSIZE

# format it to ext2
/sbin/mke2fs -F -m 0 -b $BLKSIZE /tmp/ramdisk.img $RDSIZE

# mount it
mkdir /mnt/initrd-disk
mount /tmp/ramdisk.img /mnt/initrd-disk -t ext2 -o loop=/dev/loop0

# copy context into ramdisk image
cp -rf /mnt/marvell/* /mnt/initrd-disk/

# umount and force it write into ramdisk image
umount /mnt/initrd-disk/

# zip it
gzip -9 /tmp/ramdisk.img
mv /tmp/ramdisk.img.gz .

#since it is for u-boot to use, it has to be converted to add a header in front
mkimage -A arm64 -T ramdisk -C gzip -n "Sparrow Ramdisk Image" -d ramdisk.img.gz uRamdisk

initramfs

  • A tmpfs is mounted: mount -t tmpfs nodev /root. The tmpfs doesn’t need a driver, it is always on-kernel. No device needed, no additional drivers.
  • The initramfs is uncompressed directly into this new filesystem: zcat initramfs cpio -i, or similar.
  • Sometimes it can be very confusing because it is still called initrd in many places although it is a initramfs, particularly in boot loaders, as for them it is just a BLOB. The difference is made by the OS when it boots.

Create initramfs is a lot simpler, prepare a directory, and holding all needed files inside it, then:

find . | cpio -o -H newc | gzip | initramfs.cpio.gz

initramfs.cpip.gz, it cal also embedded into kernel directly to make just one binary.

Reference

https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt