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.
The following are methods used in the mkinitrd script to determine critical information about the root device and filesystem.
Using /etc/fstab the script determines
which filesystem is used on the root device and theecorresponding module
(for example ext3 or
xfs).
Using /etc/raidtab the
mkinitrd script deduces the names of the RAID arrays
to start all the devices (even non root).
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.
The syntax for the Debian and the other distribution's mkinitrd is different.
Table 2.1. Debian mkinitrd options
-d | Specify an alternative configuration directory |
-k | Keep temporary directory used to make the image |
-m | Set the command to make an initrd
image |
-o | Write to outfile |
-r | Override 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
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.
Uncompress the current initrd
cp /boot/initrd-kernel-version.img /tmp/initrd.img.gz
gunzip /tmp/initrd.img.gz
Mount the current initrd using a
loop device
mkdir /mnt/current mount -o loop /tmp/initrd.img /mnt/current
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
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
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
Create a filesystem on the file /tmp/initrd-new.img
with 48 inodes
mke2fs -F -m 0 -N 48 /tmp/initrd-new.img
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 -)
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.
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
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=/