Changes

Jump to: navigation, search

Modifying initrd image

3,980 bytes added, 14:34, 27 June 2006
Initial edition of article
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.

==What is initrd image==
Your boot loader ussually supports <tt>initrd</tt> instruction.
For example in GRUB:
<pre>
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
</pre>
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 <tt>init</tt>
script, that resides on this image.
<tt>init</tt> script usually is written on nash (something like bash, but poorer).
When <tt>init</tt> scipt on initrd image is finished kernel as usually calls system V <tt>init</tt>
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:
<pre>
...
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!
</pre>
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:
<pre>
$ 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
</pre>

==Analyzing init script==
<pre>
$ 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
</pre>

We can see, that init tryies to load modules mptbase.ko and mptscsih.ko.
Check for presense of these modules on initrd image:
<pre>
$ ls -1 ./lib/
mptbase.ko
mptscsih.ko
</pre>

So they are... But on the node in question there is device, that is supported by driver in another module:
<tt>mtpspi.ko</tt>! After adding it to image an in init script everything must work.

==Creating initrd==
We just have to cpio and gzip directory cpio:
<pre>
$ 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
</pre>

==Who create mkinitrd by default?==
In each modern distribution there is <tt>mkdinitrd</tt> 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.

[[Category: HOWTO]]
[[Category: Troubleshooting]]
172
edits

Navigation menu