What's happening is that you're trying to boot Linux in the "Obsolete" way. That is where the initrd
is a ramdisk as opposed to a compressed cpio archive unpacked by the kernel in a ramfs, and with the old way to switch to the end device.
In that mode, the kernel mounts the disk.img as a ramdisk as the root file system and then executes /linuxrc
in there. Most likely in your case, there's no such file. When /linuxrc
(which is supposed to do whatever's necessary to bring up the block device for the real root filesystem) exits, then the kernel mounts the real root file system.
The messages above show that it mounts the ram disk successfully (1,0: 1 is for ram
, so /dev/ram0
) but not the real root file system /dev/sda1 (8,1: 8 is sd
, 1 is a1
). Presumably since you didn't specify a kernel command line (-append
), that /dev/sda1
comes from a CONFIG_CMDLINE passed at kernel compile time or using rdev
.
If your disk.img is meant to contain a root file system of say a small Linux distribution with /sbin/init
..., then you probably want to write it instead:
kvm -kernel kernel.img -initrd disk.img -append 'root=/dev/ram0`
Then, the kernel would treat the ram disk as the real root file system (though you could still pivot_root
to another one).
To be able to see the kernel messages more easily, I'd recommend using serial output:
kvm -kernel kernel.img -initrd disk.img -nographic -append "root=/dev/ram0 console=ttyS0"
As an alternative you could use an init ramfs instead of an init ramdisk:
mkdir -p RAMFS/{bin,dev}
cd RAMFS/bin
cp /bin/busybox .
"$PWD/busybox" --install .
cd ..
cp -a /dev/{null,tty,zero,console} dev
printf '%s\n' "#! /bin/sh -" "exec /bin/sh" > init
chmod +x init
find . | cpio -oHnewc | gzip > ../initramfs.gz
cd ..
kvm -kernel kernel.img -initrd initramfs.gz
(provided busybox
is the statically linked version) and you'll get a shell and other busybox utilities in that kernel).
Note that the kernel now runs /init
as opposed to /linuxrc
or /sbin/init
in that mode.