tech_log: Problems with booting vanilla image in qemu

Thursday, November 20, 2008

Problems with booting vanilla image in qemu

I built vanilla bzImage with intention to run it in qemu, using command:

qemu -hda rootfs.img -kernel bzImage -append "root=/dev/hda"

instead of previous:

qemu -hda rootfs.img -kernel vmlinuz-2.6.18-4-k7 -initrd initrd.img-2.6.18-4-k7 -append "root=/dev/hda"

where
I used prebuild Debian kernel (ths already patched), provided as a
binary with the distro. Note here that initrd image is provided also
and had to be used with the Debian kernel which I wanted to avoid (by
building my own vanilla).

rootfs.img I used was created using Busybox:

  1. make menuconfig
  2. make
  3. make install
Find the files under busybox/_install:

drasko@Lenin:~/lddTutorial$ ls busybox-1.12.1
applets debianutils LICENSE runit
arch docs loginutils scripts
archival e2fsprogs Makefile selinux
AUTHORS editors Makefile.custom shell
busybox examples Makefile.flags sysklogd
busybox.links findutils Makefile.help testsuite
busybox_unstripped include miscutils TODO
busybox_unstripped.map init modutils TODO_config_nommu
busybox_unstripped.out _install networking util-linux
Config.in INSTALL printutils
console-tools libbb procps
coreutils libpwdgrp README


drasko@Lenin:~/lddTutorial$ ls busybox-1.12.1/_install/
bin linuxrc sbin usr



After that, rsync _install from busybox with rootfs.img file, formated to ext2:


  1. dd if=/dev/zero of=rootfs.img bs=10000k count=1
  2. mkfs.ext2 -F rootfs.img
  3. mkdir /mnt/rootfs
  4. mount -o loop rootfs.img /mnt/rootfs
  5. rsync -a busybox/_install/ /mnt/rootfs/
  6. chown -R root:root /mnt/rootfs/
  7. sync

Cool, now we have root FS on our file. We can now boot with:



qemu -hda rootfs.img -kernel bzImage -append "root=/dev/hda"



So, I built vanilla kernel bzImage, but wanted minimal size - i started with:

make allnoconfig

and turn on one by one.



First error - I missed support for IDE drive - device drivers not
selected in make menuconfig prevented the kernel to recognize /dev/hda
given to qemu as a hard disk partition. It gave kernel panic something
like:

Undefined block(0,0).



Back to the make menuconfig, turn on block devices, and under Device Drivers find IDE sections. Make.



That worked, but here comes new kernel panic:
Kernel panic - not syncing: No init found. Try passing init= option to kernel.

Obviously, there is init missing, and that is most because there is no console on the newly created rootfs.img.

The
thing is that /dev directory is dynamically created by kernel, but
kernel has no means in creating console. It has to be created manually.

Well,
why did not previous run complained, the one with Debian kernel?
Because of initrd. This image has udev, which can dynamically make
console using hotplug, when enabled in kernel (which probably is the
case of Debian pre-build kernel).

---
As a digression:

Following the Debian Kernel Handbook, initrd.img can be unpacked:


$ zcat /boot/initrd.img-2.6.18-4-k7 | cpio -i


After unpacking we can inspect contents of initrd directory:

drasko@Lenin:~/dmel/initrd$ pwd
/home/drasko/dmel/initrd

drasko@Lenin:~/dmel/initrd$ ls
bin conf etc init initrd.img-2.6.18-4-k7 lib sbin scripts

drasko@Lenin:~/dmel/initrd$ ls sbin/
depmod modprobe rmmod udevd udevsettle udevtrigger


---

In our vanilla kernel we do not have initrd, we tried to skip this step
by simplifying kernal and static build of all needed stuff.

That's why we have to create /dev/console manually in our filesystem (rootfs.img).

Creating device files when programs complain:
  1. mkdir /mnt/rootfs/dev
  2. mknod /mnt/rootfs/dev/console c 5 1
  3. mknod /mnt/rootfs/dev/null c 1 3
Taking the GNU/Linux host as an example to find correct
major and minor numbers:
ls -l /dev/console
ls -l /dev/null


-----------------------

Final note: Trying with kernel 2.6.27, I saw that init is working correctly, even for the minimal configuration. So - avoid 2.6.23 - it is buggy. Not only that it can not be build with gcc-4.3, but also loop.o gives compilation error whenn loop block device support is selected in kernel. And, yes, init is dead...

-----------------------

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home