首页 > 解决方案 > switch_root 的正确方法

问题描述

我在为我的嵌入式目标设置启动时遇到了很多(半个)问题;情况是:

我有一个嵌入式目标,它有一个相当小但可靠的闪存(16M 字节)和一个可能很大(当前为 8GB)但相当不可靠的 SD 卡。

SD卡的不可靠性主要是由于硬件设置(直接连接到电源,所以如果它“严重”唤醒,硬件重置它没有办法)我无法改变。这主要影响 u-boot(Linux 处理似乎更稳定)。

由于我需要相对较高的可靠性,即使在软件更新期间/之后,我也选择了带有“恢复”后备的拨号系统(更新休眠的,然后重新启动)。

不幸的是,我在 Flash 中没有足够的空间来安装适当的 initramfs 和完整的恢复系统,所以我试图将启动系统与恢复结合起来。

因此,我有一个完整的闪存系统,其中包含一个/init选择启动模式的小脚本。

/init脚本类似于:

#!/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

这显然是从bootargs包含开始的tryboot=A/B/R

我没有使用 Busybox switch_root,因为这不是真正的 initramfs,而是基于 Flash 的 SquashFS;我当前的 u-Boot 环境包括:

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)

当前的问题是系统因exec chroot . sbin/init ...“内核恐慌 - 不同步:试图杀死 init !”而死机。没有打印“罪魁祸首”+ exec chroot . sbin/init <dev/console >dev/console 2>&1行的错误。

注意 1:我确保sbin/init新根 fs 上存在(它是指向bin/busybox

注意 2:即使我注释掉之前umount mnt的 .

我究竟做错了什么?

标签: linuxinitramfs

解决方案


推荐阅读