I'm having a ton (and a half) of problems setting up booting for my embedded target; situation is:
I have an embedded target with a rather small, but reliable, Flash (16M bytes) and a possibly large (currently 8GB), but rather unreliable, SD card.
Unreliability of SD card is mainly due to hardware setup (direct connection to power supply, so NO WAY to hardware reset it if it wakes up "badly") I cannot change. This is mainly affecting u-boot (Linux handling seems much more stable).
Since I need a relatively high reliability, even during/after software update, I opted for a dial system (update the dormant one, then reboot) with a "recovery" fallback.
Unfortunately I do not have enough space in Flash for a proper initramfs plus a full recovery system, so I'm trying to couple startup system with recovery.
I thus have a full flash system with a small /init
script choosing startup mode.
/init
script is something like:
#!/bin/ash
set -x
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
boot_prod() {
mount -t proc none /proc
mount -t sysfs none /sys
mount $1 /mnt && [ -x /mnt/sbin/init ] || return 1
echo "switching to $1"
cd /mnt
mount --move /sys sys
umount /proc # /proc is remounted by BusyBox /dev/inittab
mount --move /dev dev
config_set sys $2
pivot_root . mnt
umount mnt
exec chroot . sbin/init <dev/console >dev/console 2>&1
}
case $tryboot; in
A)
boot_prod /dev/mmcblk0p6 A
;;
B)
boot_prod /dev/mmcblk0p7 B
;;
R)
[ -x /mnt/sbin/init ] && exec /mnt/sbin/init
;;
*)
;;
esac
echo "Could not boot cleanly; running a shell"
mount -t proc none /proc
mount -t sysfs none /sys
exec setsid cttyhack sh
This is clearly started with bootargs
containing tryboot=A/B/R
.
I am not using Busybox switch_root
because this is not a true initramfs, but a SquashFS living on Flash; my current u-Boot environment includes:
BOOT_A_GOOD=y
BOOT_CURRENT=B
SYSTEM_R=/dev/mtdblock5
boot_a=echo "Loading System A";part=A;run boot_x
boot_b=echo "Loading System B";part=B;run boot_x
boot_now=if test "${BOOT_CURRENT}" = A; then run boot_a; elif test "${BOOT_CURRENT}" = B; then run boot_b; fi; if env exists BOOT_A_GOOD; then run boot_a; fi; if env exists BOOT_B_GOOD; then run boot_b; fi; run boot_r
boot_r=echo "Loading Recovery";part=R;run boot_x
boot_x=setenv bootargs "${default_bootargs} mtdparts=${mtdparts} root=${part}" && bootm bc050000
bootcmd=rub boot_now
bootdelay=2
default_bootargs=earlyprintk rootwait console=ttyS2,115200
mtdids=nor0=spi0.0
mtdparts=spi0.0:312k(u-boot),4k(env),4k(factory),2368k(kernel),-(filesystem)
Current problem is system dies at exec chroot . sbin/init ...
with a "Kernel panic - not syncing: Attempted to kill init !" error without printing the "culprit" + exec chroot . sbin/init <dev/console >dev/console 2>&1
line.
Note1: I made sure sbin/init
exists on new root fs (it is a symlink to bin/busybox
Note2: Error persists even if I comment out previous umount mnt
.
What am I doing wrong?
I have more experience with switch_root than pivot_root.
This means that the process with PID 1 exited or was killed. (PID 1 is called "init" because it is typically /init in an initial RAM disk.)
Does /mnt/sbin/init ever end or exit?