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-system-x86_64 -enable-kvm -kernel bzImage
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!