I'm building a very minimal Linux system that just consists of the kernel (v4.1-rc5) and an initramfs populated with busybox (v1.23.2). It works fine for the most part, but I observe a difference in behavior of command execution in /init whether I'm using an embedded initramfs vs. an external one.
The /init script is:
#!/bin/sh
dmesg -n 1
mount -t devtmpfs none /dev
mount -t sysfs none /sys
mount -t proc none /proc
echo "Welcome"
while true
do
setsid cttyhack /bin/sh
done
Then I either set the CONFIG_INITRAMFS_SOURCE option in the kernel .config to the directory containing all the folders for the initramfs, or I run
find . | cpio -H newc -o | gzip > ../rootfs.cpio.gz
to build it.
When I then compile the kernel, either with or without CONFIG_INITRAMFS_SOURCE set, I end up with two variants of my system:
bzImage with initramfs embedded
bzImage + rootfs.cpio.gz (external initramfs)
when I now start those using qemu
qemu-system-x86_64 -enable-kvm -kernel bzImage
or
qemu-system-x86_64 -enable-kvm -kernel bzImage -initrd rootfs.cpio.gz
I get the following difference in behavior:
with version 2 (external initramfs) everything works fine, "Welcome" is displayed and I get a prompt. With version 1 however (embedded initramfs) I get the warning
unable to open an initial console
"Welcome" is not displayed, and I get my prompt.
As far as I understand the process, those two versions of initramfs should contain the same files, since I build it (or have the kernel build it) from an identical folder.
I wonder if anyone can help me with an explanation for this behavior?
* UPDATE *
as mikeserv said in the comments, The kernel includes a minimal embedded initramfs per default. This is still present when using an external one, but gets overwritten if you embed your own. I found that contrary to the specification, this is indeed not empty, but contains a dev folder, a root folder and the /dev/console device. This device then gets used when using an external initramfs, but overwritten if you embed your own. So you have to include the /dev/console device in your initramfs source mknod -m 622 initramfs_src/dev/console c 5 1
when embedding your own.
Thanks a lot to mikeserv, frostschutz and JdeBP for helping me get my head around that!
/dev/console
on your builtin one? I think the difference might be about who does the packing in the two cases. – mikeserv Jun 09 '15 at 17:41mknod -m 622 console c 5 1
actually works in getting rid of the problem in the embedded version. That leaves me still puzzled why the behavior is different for the two cases, in that the external initramfs has its console device ready already when its supposed to execute the "echo" – clw Jun 09 '15 at 18:49mount -t devtmpfs none /dev
in init, which for some reason shows different results when using an embedded initramfs vs. external – clw Jun 09 '15 at 19:08cmp
ing anddiff
ing until you figure it out. It's only a few kb in either case - you just need to dig, dude. – mikeserv Jun 09 '15 at 19:14