Saturday, August 6, 2011

Initial RAM Disk in Linux

In the final boot step, the Linux kernel will execute a series of run_init_process calls:

run_init_process("/sbin/init");
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");
panic("no init found.  try passing init= option  tp kernel.")

The run_init call execite program in a filesystem already mounted, else the kernel will panic.  Linux kernel contains 2 mechanisms to mount an early root file system to perform certain start up functions.
(1) initial RAM disk (initrd) is the legacy method. Support for this must be compiled into the kernel. It is a small, self-contained root file system that usually contains directives to load specific device driveers before the end of boot cycle. For example, Red Hat and Ubbuntu uses initrd to load the EXT3 file system driver before mounting the real root file system.
The bootloader pass the initrd image to the kernel. A common scenario is that the bootloader loads the kernel image into memory and loads the initrd image to another address ranges. Bootloader than passes the load address of initrd to kernel. In other scenario (ARM architecture), the initrd and kernel image are simply concatenated into a single composite image. The address and size of the intird is passed to kernel using the kernel command line. One note is that the initrd image is universally compressed.
When Linux boots, it detects the presence of initrd image. It copies the compressed binary file from the physical location in RAM to proper kernel ramdisk and mounts it as the root file system. It then looks for a special file in the initial ramdisk called linuxrc. This file contains directives (commands)required before mounting the real root file system. After the kernel copies the ramdisk from physcial address into the kernel ramdisk, it releases the physical memory. This is similar to transfer the initrd image from real memory to virtual memory of the kernel.

As part of the Linux boot process, the kernel must locate andmount a root file system. The kernel decides what and where to mount in a funciton called prepare_namespace() in /init/do_mount.c.

If initrd support is enabled in the kernel and the kernel command line is so configured, kernel decompresses the initrd image and copy the content to ramdisk under /dev/ram. At this point, we have a proper file system on a kernel ramdisk. The kernel effectively mounted the ramdisk device as its root file system. Finally, kernel spawn a kernel thread ti execute the linuxrc file. When linuxrc is done, kernel unmounts the initrd and proceed to the final stage of system boot. If the real, root device has a directory called /initrd, Linux will mount initrd file system on this path. Otherwise, the initrd will be discarded.

If the kernel command line contains a root= paramter specifying a ramdisk (e.g. root=/dev/ram0), the previous described behaviour will change. First, the processing of the linuexrc file is skipped. Second, no attempt is made to mount another file system as root. It means the initrd is the only root file system. This is useful if minimal system configuration is intended.

(2) initiramfs is the preferred mechanism for executing early user space programs. It is coneptually simliar to initrd and its purpose is also similar: to load drivers that might be required to mount the real file system.
Initramfs is much easier to use by developer as it is a cpio archive whereas initrd is a gzipped file system image.

No comments: