Difference between revisions of "Modifying initrd image"
(Initial edition of article) |
(→Analyzing init script) |
||
(6 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
− | The | + | The frequent 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. | + | Here is a small description of what you can do if you encounter a similar problem. |
==What is initrd image== | ==What is initrd image== | ||
− | Your boot loader | + | Your boot loader usually supports <code>initrd</code> instruction. |
− | For example in GRUB: | + | For example, in GRUB: |
<pre> | <pre> | ||
OpenVZ (2.6.8-022stab077) | OpenVZ (2.6.8-022stab077) | ||
Line 12: | Line 12: | ||
</pre> | </pre> | ||
GRUB loads initrd-2.6.8-022stab077.img file at a certain address in memory. | 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> | + | When kernel boots, it checks for initrd image, and if it exists starts <tt>init</tt> |
− | script | + | script that resides on this image. |
− | <tt>init</tt> script usually | + | <tt>init</tt> script is usually written in nash (a sort of bash-like shell, just smaller). |
− | When <tt>init</tt> | + | When <tt>init</tt> script on initrd image is finished, kernel usually calls standard System V <tt>init</tt> |
process (/sbin/init, etc.) | process (/sbin/init, etc.) | ||
==Why initrd image is necessary== | ==Why initrd image is necessary== | ||
− | Suppose your root partion resides on some SCSI device and driver for this SCSI devices is compiled | + | Suppose your root partion resides on some SCSI device and driver for this SCSI devices is compiled as a |
− | kernel module. Of course this module is required at boot time to have access to the root partion. | + | kernel module. Of course this module is required at boot time to have access to the root partion — but it is not in the kernel. Thus the need for an initrd image. |
− | + | ||
− | Additionally after | + | Additionally after udev subsystem become common, somebody has to start udev to create device nodes. This is initrd's duty too. |
==Typical problem== | ==Typical problem== | ||
Line 39: | Line 39: | ||
</pre> | </pre> | ||
This can appear if there is no module loaded for device, where root partion resides. | This can appear if there is no module loaded for device, where root partion resides. | ||
− | To solve the problem extract the initrd image. | + | To solve the problem, extract the initrd image. |
==Extracting initrd image== | ==Extracting initrd image== | ||
Initrd image is just cpio-gzip archive. So to extract it: | Initrd image is just cpio-gzip archive. So to extract it: | ||
<pre> | <pre> | ||
− | $ mkdir | + | $ mkdir initrd |
− | + | $ cd initrd | |
− | $ cd | + | $ gzip -dc /boot/initrd-2.6.16-026test014.4-smp.cpio | cpio -id |
− | $ | ||
− | |||
$ ls -1 | $ ls -1 | ||
bin | bin | ||
Line 99: | Line 97: | ||
</pre> | </pre> | ||
− | We can see | + | We can see that init tries to load modules <code>mptbase.ko</code> and <code>mptscsih.ko</code>. |
− | Check for | + | Check for presence of these modules on initrd image: |
<pre> | <pre> | ||
$ ls -1 ./lib/ | $ ls -1 ./lib/ | ||
Line 107: | Line 105: | ||
</pre> | </pre> | ||
− | So they are... But on the node in question there is device | + | So they are here... But on the [[Hardware Node|node]] in question there is a device supported by driver in another module: |
− | < | + | <code>mptspi.ko</code>! After adding it to the image and into init script everything should work. |
==Creating initrd== | ==Creating initrd== | ||
We just have to cpio and gzip directory cpio: | We just have to cpio and gzip directory cpio: | ||
<pre> | <pre> | ||
− | + | $ find ./ | cpio -H newc -o > /boot/new-initrd.cpio | |
− | |||
− | |||
− | |||
− | $ find ./ | cpio -o > | ||
1354 blocks | 1354 blocks | ||
+ | $ cd /boot | ||
+ | $ gzip new-initrd.cpio | ||
+ | $ mv new-initrd.cpio.gz new-initrd.img | ||
</pre> | </pre> | ||
− | ==Who create | + | Next, try to boot your kernel with newly created initrd image. |
− | + | ||
− | initrd image. You can use this program, it has a lot of options. OpenVZ kernel RPM-package (and | + | ==Who create initrd by default?== |
− | program to create initrd image. | + | Usually there is an <code>mkdinitrd</code> package installed, that allows to create |
+ | initrd image. You can use this program, it has a lot of options. OpenVZ kernel RPM-package (and “make install” target too) uses this | ||
+ | program to create an initial (default) initrd image. | ||
[[Category: HOWTO]] | [[Category: HOWTO]] | ||
[[Category: Troubleshooting]] | [[Category: Troubleshooting]] |
Latest revision as of 10:48, 28 September 2015
The frequent reason why your kernel can't boot is not properly created initrd image. Here is a small description of what you can do if you encounter a similar problem.
Contents
What is initrd image[edit]
Your boot loader usually 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 is usually written in nash (a sort of bash-like shell, just smaller). When init script on initrd image is finished, kernel usually calls standard System V init process (/sbin/init, etc.)
Why initrd image is necessary[edit]
Suppose your root partion resides on some SCSI device and driver for this SCSI devices is compiled as a kernel module. Of course this module is required at boot time to have access to the root partion — but it is not in the kernel. Thus the need for an initrd image.
Additionally after udev subsystem become common, somebody has to start udev to create device nodes. This is initrd's duty too.
Typical problem[edit]
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[edit]
Initrd image is just cpio-gzip archive. So to extract it:
$ mkdir initrd $ cd initrd $ gzip -dc /boot/initrd-2.6.16-026test014.4-smp.cpio | cpio -id $ ls -1 bin dev etc init initrd-2.6.16-026test014.4-smp.cpio lib loopfs proc sbin sys sysroot
Analyzing init script[edit]
$ 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 tries to load modules mptbase.ko
and mptscsih.ko
.
Check for presence of these modules on initrd image:
$ ls -1 ./lib/ mptbase.ko mptscsih.ko
So they are here... But on the node in question there is a device supported by driver in another module:
mptspi.ko
! After adding it to the image and into init script everything should work.
Creating initrd[edit]
We just have to cpio and gzip directory cpio:
$ find ./ | cpio -H newc -o > /boot/new-initrd.cpio 1354 blocks $ cd /boot $ gzip new-initrd.cpio $ mv new-initrd.cpio.gz new-initrd.img
Next, try to boot your kernel with newly created initrd image.
Who create initrd by default?[edit]
Usually there is an mkdinitrd
package installed, that allows to create
initrd image. You can use this program, it has a lot of options. OpenVZ kernel RPM-package (and “make install” target too) uses this
program to create an initial (default) initrd image.