Preface
The boot sequence of Linux starts with the BIOS determining the primary boot device (Usually the first disk). Next the grub is displayed and we choose the desired Operating System. Loading of the OS starts next and the kernel is loaded into memory. Following the Kernel, the linux initrd is mounted. After this, control is passed to the kernel. The kernel mounts the partitions and starts the init process. Init takes over and runs the scripts triggering the services needed to bring the system to a full swing. Phew, that was long. In this sequence there is one element which is less noticed, initrd. Why is it is needed at all and why is it loaded just after the mighty kernel? Lets peek into this little known utility.
Initrd in a nutshell
Initrd is the initial ram disk image. As the name suggests it an image file. The Linux kernel consists of selected drivers. However, all the drivers needed for the system to become fully functional cannot be placed within the kernel. This will make the kernel consume more space and complex and the loading of the kernel will be slow.
The initrd comes into play here. It is a temporary root file system that is mounted during system boot to support the two-state boot process. It is composed of the necessary executables and specific drivers to access the devices. After the kernel is loaded into memory. The kernel decompresses this image file and mounts it. The init executable present within it (an init different from the one in your /sbin/init ) is run next and the drivers and executables available in the initrd are utilised to mount the root partition. The task of initrd is finished here and the kernel can safely mount the / (root) partition.
Precious initrd
initrd is used primarily to install the disk drivers of RAID, SCSI etc that hold the root partition. Yet another usage is at the time of hibernation when the system will dump the image of memory to the swap. This has to be loaded from the disk back to the memory before the root filesystem is mounted. Some times the partitions are encrypted as in the case of high secure data drives and a specific utility will have to be preloaded to interpret the data in the disk partition, for this, the initrd is preconfigured with the utility to read the data from the device. In the embedded platform, as the memory finger print is quite small, the default file system used in the system will be the initrd, no disk/data is further mounted. In this case the initrd will possess all the binaries and libraries the embedded system will require.
initrd and initramfs
Now, initrd comes in two flavours, the classic initrd and the newer initramfs. initrd is a raw ext2 filesystem containing the necessary utilities whereas initramfs is cpio archieve. Both are additionally compressed with gzip. initrd is no more supported and current distributions (using the 2.6 kernel and onward) come with initramfs as default.
To determine if you are having an initrd or initramfs for your distribution, perform the below command on your inirtd file:
gunzip -c /boot/initrd-2.4.17.img.gz | file -
/dev/stdin: Linux rev 1.0 ext2 filesystem data
(This is an initrd file, notice the ext2 filesystem)
gunzip -c /boot/initrd.img-2.6.24-19-generic | file -
/dev/stdin: ASCII cpio archive
(This is an initramfs file, notice the cpio archive)
Anatomy
I will be discussing about initramfs file here on as initrd. The initrd file is present in the /boot/ directory (usually in a different partition). This file is present with the filename format initrd-kernelversion.img like initrd-2.6.18-128.el5.img. It is usually a cpio or cpio-gzip compressed archive (determinable with the file command). To observe the content in it, follow the commands below:
mkdir /tmp/initrd_unpack/
(to determine if this is a gzip or just a cpio archive)
cp /boot/initrd-2.6.18-128.el5.img /tmp/initrd_unpack/
cd /tmp/initrd_unpack/
file initrd-2.6.18-128.el5.img
mv initrd-2.6.18-128.el5.img initrd-2.6.18-128.el5.img.gz
gunzip initrd-2.6.18-128.el5.img.gz
cpio -idv < initrd-2.6.18-128.el5.img
Most of the directories present will be empty except for the lib and the dev. The lib hold the kernel object files (.ko). Each file is a loadable kernel module, this is an added feature of linux 2.6. The dev directory will hold device files.
custom tailored images
There are two commands which can be used to make the initrd images. On debian/ubuntu systems, mkinitramfs can be used. The command to be used is:
mkinitramfs -v -o /tmp/initramfs-$(uname -r)
In redhat based systems, mkinitrd may be used. The command in this case is:
mkinitrd /tmp/initrd-$(uname -r).img $(uname -r)
eg: mkinitrd /tmp/initrd-2.2.16-3ext3.img 2.2.16-3ext3
The second argument is the directory in /lib/modules/ from which the necessary driver modules are retrieved. recollect that uname -r only provides the kernel version of the currenly loaded kernel, so if the kernel for which the image to be made is different, it has to be specified explicitly.
In either of the two commands the image file is created in the tmp directory. The image thus created will have to be moved to /boot and grub will have to be configured to use the new one. For this, edit the line beginning with initrd corresponding to the required kernel (eg: for the kernel /boot/vmlinuz-2.4.20-24.9, the line is initrd /boot/initrd-2.4.20-24.9.img) to the newer one and you are done.