2.3. Customised initrd

In most cases a customised initrd requires running mkinitrd which will determine the kernel modules needed to support block devices and filesystems used on the root device.

2.3.1. The mkinitrd script

The following are methods used in the mkinitrd script to determine critical information about the root device and filesystem.

The root filesystem type

Using /etc/fstab the script determines which filesystem is used on the root device and theecorresponding module (for example ext3 or xfs).

Software RAID

Using /etc/raidtab the mkinitrd script deduces the names of the RAID arrays to start all the devices (even non root).

LVM root device

Once the root device $rootdev is determined in /etc/fstab the major number is obtained from the following line:

root_major=$(/bin/ls -l $rootdev | awk '{ print $5 }')

If this corresponds to a logical volume, the logical volume commands are copied onto the ram disk.

The mkinitrd script will transfer all the required tools and modules to a file mounted as a loop device on a temporary directory. Once unmounted, the file is compressed and can be used as an initrd.

2.3.1.1. mkinitrd syntaxes

The syntax for the Debian and the other distribution's mkinitrd is different.

Table 2.1. Debian mkinitrd options

-d confdirSpecify an alternative configuration directory
-kKeep temporary directory used to make the image
-m commandSet the command to make an initrd image
-o outfileWrite to outfile
-r rootOverride ROOT setting in mkinitrd.conf

Example:

mkinitrd -o /boot/initrd-test-$(uname or).img

Mandriva, RedHat, Suse/Novell mkinitrd

usage: mkinitrd [--version] [-v] [-f] [--preload <module>]
       [--omit-scsi-modules] [--omit-raid-modules] [--omit-lvm-modules]
       [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]
       [--builtin=<module>] [--nopivot] <initrd-image> <kernel-version>

Example:

mkinitrd /boot/initrd-test-2.2.5-15.img 2.2.5-15

2.3.1.2. Making an initrd

As an example we will copy the content of an existing initrd to a new initrd and change the root filesystem type from ext3 to ext2.

  1. Uncompress the current initrd

    cp /boot/initrd-kernel-version.img /tmp/initrd.img.gz
    gunzip /tmp/initrd.img.gz
    
  2. Mount the current initrd using a loop device

    mkdir /mnt/current
    mount -o loop /tmp/initrd.img /mnt/current
    
  3. Estimate the size needed for the new initrd:

    df -k /mnt/current
    Filesystem           1K-blocks      Used Available Use% Mounted on
    /tmp/initrd.img            317       191       126  61% /mnt/current
    
  4. Create a new image file called initrd-new.img of size 161K

    dd if=/dev/zero of=/tmp/initrd-new.img bs=1K count=317
    
  5. Estimate the number of inodes needed in the current initrd:

    df -i /mnt/current
    Filesystem            Inodes   IUsed   IFree IUse% Mounted on
    /tmp/initrd.img           48      33      15   69% /mnt/current
    
  6. Create a filesystem on the file /tmp/initrd-new.img with 48 inodes

    mke2fs -F -m 0 -N 48 /tmp/initrd-new.img
    
  7. Mount the file on a new directory and copy across all the files of the current initrd to the new one:

    mkdir /mnt/new
    mount -o loop /tmp/initrd-new.img /mnt/new
    (cd /mnt/current/; tar cf - .) | (cd /mnt/new; tar xf -)
    
  8. Edit the /mnt/new/linuxrc file and delete the line where the ext3 module is inserted. Also replace the ext3 option by ext2 at the mount command.

  9. Finally, unmount the /tmp/initrd-new.img then compress and rename it.

    gzip /tmp/initrd-new.img ; mv /tmp/initrd-new.img.gz /boot/initrd-test.img
    

    Or

    gzip < /tmp/initrd-new.img > /boot/initrd-test.img
    
  10. Create a new kernel entry in /etc/lilo.conf or /boot/grub/grub.conf instructing the bootloader to use the new initrd.

Sample grub.conf

title linux (2.4.22)
        root (hd0,1)
        kernel /vmlinuz-2.4.22 ro root=LABEL=/ 
        initrd /initrd-2.4.22.img

title broken?
        root (hd0,1)
        kernel /vmlinuz-2.4.22-1.2115.nptl ro root=LABEL=/ 
        initrd /initrd-new.img

Sample lilo.conf

 image=/boot/vmlinuz-2.4.22-1.2115.nptl
 	initrd=/boot/initrd-2.4.22.img
	read-only
	label=linux
     append=root=LABEL=/
image=/boot/vmlinuz-2.4.22-1.2115.nptl
 	initrd=/boot/initrd-new.img
	read-only
	label=broken?
     append=root=LABEL=/