The essential lines from your boot crash image:
[ 4.035680] EXT4-fs (sda): ext4_check_descriptors: Block bitmap for group 0 overlaps superblock
[ 4.036225] EXT4-fs (sda): group descriptors corrupted!
[ 4.551311] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100
[ 4.551519] CPU: 1 PID: 1 Comm: switch_root Not tainted 6.1.96 #1
So, an attempt to mount /dev/sda
did happen, but may have failed because the filesystem was corrupted.
The process #1 was trying to execute the switch_root
command when it died.
Both of these facts suggest that the system was in fact executing your initrd /init
script and was almost successful in completing it.
The crash point would be the last line of your /init
script:
exec switch_root /root /init
I don't see your script creating a symlink to busybox
with the name switch_root
anywhere.
Something like this in your creation script might help:
...
# sbin + dev
ln -s /bin/busybox /tmp/initrd/sbin/switch_root # added
cp /sbin/{modprobe,mkfs.ext4} /tmp/initrd/sbin/
cp -a /dev/{console,null,tty1,tty2,ttyS0} /tmp/initrd/dev/ # serial console port added
...
The ln -s /bin/busybox /tmp/initrd/sbin/switch_root
might seem a bit counter-intuitive.
That command will create a special symbolic link file at what is /tmp/initrd/sbin/switch_root
at the time of link creation and store the pathname /bin/busybox
within it. The resulting symbolic link will point to path /bin/busybox
at the time it'll be used. So, when this initrd is in use, there will be a link at /sbin/switch_root
, pointing to /bin/busybox
and it should work as expected.
The fact that there also happens to be a /bin/busybox
in the host OS is not relevant for this command at all: a symbolic link is just a pathname, with no "target tracking" of any kind.
I also noticed that you are creating /dev/tty1
and /dev/tty2
within the initrd. Those are useless to you as your boot options include console=ttyS0
. But you aren't creating a device node for your console device /dev/ttyS0
- that might explain why you don't see the results of the echo
commands in the /init
script.
The "run sh
and manually switch root" looks better, but... your switch_root
command is trying to run /init
after switching to the new root filesystem that comes from the kernel-hd
image file.
You are creating the essential directories:
mkdir -p /root/{bin,sbin,lib,dev,proc,sys,run}
and populating /root/bin
(which will be /bin
after the switch)
with busybox
and its links:
cp /bin/busybox /root/bin
/root/bin/busybox --install -s /root/bin
But there is nothing at /root/init
, which would be what
exec switch_root /root /init
attempts to execute after making /root
into a real root filesystem.
Either you should have your initrd place a second script there (not the same script as the initrd uses, or you'll have an infinite recursion), or perhaps you should have switch_root
start the init
of busybox
instead? You would have to supply it with an appropriate inittab
file (at /root/etc/inittab
before the switch). Then:
exec switch_root /root /bin/init
would start busybox
's init
.
Oh, and copying the contents of initrd's /dev
into /root/dev/
before switching would be a good idea too.