It did work out. The kernel booted fine. The error is:
Unable to mount root fs on unknown-block(0.0)
The kernel is looking for a root filesystem. You need to provide one. You can't interact with a kernel without running processes on it, and the initial process has to be loaded from somewhere: when the kernel starts, it mounts a filesystem (the root filesystem) on the directory /
, then runs the program /sbin/init
. The init program is normally in charge of running boot scripts and starting services including programs that let users log in.
You must make sure that the kernel is able to mount the root filesystem. It must have drivers for the filesystem type and for all the layers involved in the block device (disk controller (SCSI/SATA/IDE/USB/… adapter), partition type, etc.).
Linux offers an additional possibility, which is to load an initial filesystem in RAM that's used during the boot process in order to locate and mount the root filesystem. This initial filesystem can contain modules that handle the device and filesystem type of the root filesystem. There are two slightly different mechanisms: initrd and initramfs.
As it happens, it looks like a bug in debian's package of grub
.
The -kernel grub.img
approach works if I only include the grub modules I need upon grub-mkimage
.
The -bios grub.bin
works with the newer grub package from experimental
(2.00-7). However, the grub.bin
that comes with it is not very useful.
It comes with a memdisk
that comes with the grub.cfg
. It would have been better to use that memdisk to hold the modules and the grub.cfg
be specified with the -c
option of grub-mkimage
. For instance, one of the menu entry looks for /boot/grub/grub.cfg
and finds itself in the memdisk as a result. Also, the debian package doesn't include the qemu grub modules, so you can't build a different grub.bin (though you can binary edit the file to change the grub.cfg) unless you do it from the source package.
The -bios grub.bin
approach sounds like the cleanest approach to me, but I'll use the -kernel
or floppy approach until the debian package is fixed.
EDIT: well, the ata.mod
grub module to read emulated IDE drives is a lot slower than using biosdisk.mod
in combination with seabios
(the default bios when not using -bios grub.bin
). Also, it seems that grub firmware doesn't support virtio-blk nor virtio-scsi disks, so kvm -bios grub.bin
is not going to be an option for me.
In case anyone wants to goes down that path, I'm now using (zsh syntax):
grub-mkimage -O i386-pc -c =(print -l serial 'terminal_input serial' \
'terminal_output serial' 'set prefix=(hd0)/boot/grub' '. grub.cfg') -o grub.img \
at_keyboard configfile biosdisk ext2 linux test serial halt minicmd terminal cat
And -kernel grub.img -nographic
passed to kvm. That is to boot Linux VMs with no graphics (only a serial interface, so make sure that the VM's grub is configured to use serial (or at least not configured to use graphics), that the kernel console goes to ttyS0 and that you run a getty on there). It can easily be adapted to work for VGA consoles as well.
Best Answer
Instead of using an image file (or in addition to an image file) you can use a block device (LVM or loop device) and pass this to the VM (which sees it as disk drive). You can mount it from the guest and from the host. But you should make sure this is not done simultaneously.
The obvious disadvantage: This volume does not grow with the need. But you can extend the block device / loop device file later and adapt the filesystem to the new size.
libvirt configuration
This is not pure QEMU but if you use libvirt then you need entries like this: