Modifying initrd image
The very often reason why your kernel can't boot is not properly created initrd image. Here is a small description what you can do if encounter similar problem.
Contents
What is initrd image
Your boot loader ussually supports initrd instruction. For example in GRUB:
OpenVZ (2.6.8-022stab077) root (hd0,0) kernel /vmlinuz-2.6.8-022stab077 ro root=LABEL=/ console=tty0 initrd /initrd-2.6.8-022stab077.img
GRUB loads initrd-2.6.8-022stab077.img file at a certain address in memory. When kernel boots it checks for initrd image and if it exists starts init script, that resides on this image. init script usually is written on nash (something like bash, but poorer). When init scipt on initrd image is finished kernel as usually calls system V init process (/sbin/init, etc.)
Why initrd image is necessary
Suppose your root partion resides on some SCSI device and driver for this SCSI devices is compiled in some kernel module. Of course this module is required at boot time to have access to the root partion. Somebody has to load this module, and it does initrd image! Additionally after appearing udev subsystem, somebody have to start udev to create device nodes. This is initrd's duty too.
Typical problem
Consider a real problem. After booting the kernel we get the following:
... Creating root device mkrootdev: label / not found Mounting root filesystem mount: error 2 mounting ext3 mount: error 2 mounting none Switching to new root switchroot: mount failed: 22 umount /initrd/dev failed: 2 Kernel panic - not sysncing: Attempted to kill init!
This can appear if there is no module loaded for device, where root partion resides. To solve the problem extract the initrd image.
Extracting initrd image
Initrd image is just cpio-gzip archive. So to extract it:
$ mkdir cpio $ cp initrd-2.6.16-026test014.4-smp.img cpio/initrd-2.6.16-026test014.4-smp.cpio.gz $ cd cpio $ gunzip initrd-2.6.16-026test014.4-smp.cpio.gz $ cpio -i < initrd-2.6.16-026test014.4-smp.cpio $ ls -1 bin dev etc init initrd-2.6.16-026test014.4-smp.cpio lib loopfs proc sbin sys sysroot
Analyzing init script
$ cat init #!/bin/nash mount -t proc /proc /proc setquiet echo Mounted /proc filesystem echo Mounting sysfs mount -t sysfs none /sys echo Creating /dev mount -o mode=0755 -t tmpfs none /dev mknod /dev/console c 5 1 mknod /dev/null c 1 3 mknod /dev/zero c 1 5 mkdir /dev/pts mkdir /dev/shm echo Starting udev /sbin/udevstart echo -n "/sbin/hotplug" > /proc/sys/kernel/hotplug echo "Loading mptbase.ko module" insmod /lib/mptbase.ko echo "Loading mptscsih.ko module" insmod /lib/mptscsih.ko /sbin/udevstart echo Creating root device mkrootdev /dev/root umount /sys echo Mounting root filesystem mount -o defaults --ro -t ext3 /dev/root /sysroot mount -t tmpfs --bind /dev /sysroot/dev echo Switching to new root switchroot /sysroot umount /initrd/dev
We can see, that init tryies to load modules mptbase.ko and mptscsih.ko. Check for presense of these modules on initrd image:
$ ls -1 ./lib/ mptbase.ko mptscsih.ko
So they are... But on the node in question there is device, that is supported by driver in another module: mtpspi.ko! After adding it to image an in init script everything must work.
Creating initrd
We just have to cpio and gzip directory cpio:
$ ls bin etc initrd-2.6.16-026test014.4-smp.cpio loopfs sbin sysroot dev init lib proc sys $ rm initrd-2.6.16-026test014.4-smp.cpio $ find ./ | cpio -o > ../new-initrd.img 1354 blocks
Who create mkinitrd by default?
In each modern distribution there is mkdinitrd packet, that allows to create initrd image. You can use this program, it has a lot of options. OpenVZ kernel RPM-package (and "make install" too) uses this program to create initrd image.