mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-08-09 19:07:50 +00:00
busybox-initramfs: reorganize init script in preparation for boot type handlers
Changes to kernel commandline parameters: Remove legacy parameters, to be added back later if desired. Add a new parameter: break=<all|step,step,...> which will cause a debugging shell to be started after each or the specified boot steps. Functions: mount_part, mount_disk, mount_nbd: reorganize to use mount type handlers, which will support specifying kernel parameters like boot=TYPE=target and disk=TYPE=target. This initial commit only has mount_default, which supports LABEL=label and UUID=uuid, as well as block devices /dev/* and image files. error: show more meaningful error messages, containing the boot step and action which caused the error. If not debugging, halt the system. This prevents the error from causing more damage further on in the boot sequence. If debugging, start a debugging shell. update: make sure the file to update already exists at the destination, to prevent clobbering a rootfs mounted on /flash, which can be the case when mounting a mtd or NBD device. load_modules: enable loading of kernel modules in early boot, e.g. xhci-hcd to enable mount of USB3 devices on boot. Add a simple boot step sequencer, which allows for starting a debugging shell after each step. Signed-off-by: Alain Kalker <a.c.kalker@gmail.com>
This commit is contained in:
parent
2e66a869ad
commit
a3f3a62767
@ -21,17 +21,13 @@
|
||||
# http://www.gnu.org/copyleft/gpl.html
|
||||
################################################################################
|
||||
|
||||
MODULE_DIR=/lib/modules
|
||||
UPDATE_DIR=/storage/.update
|
||||
|
||||
IMAGE_SYSTEM="SYSTEM"
|
||||
IMAGE_KERNEL="KERNEL"
|
||||
REBOOT="0"
|
||||
|
||||
# defaults for booting from an nbd root
|
||||
NBD_ROOT_SERVER="192.168.1.1"
|
||||
NBD_ROOT_PORT="2000"
|
||||
NFS_OVERLAY="192.168.1.1:/var/lib/overlay"
|
||||
|
||||
# mount all needed special filesystems
|
||||
/bin/busybox mount -t devtmpfs none /dev
|
||||
/bin/busybox mount -t proc none /proc
|
||||
@ -62,22 +58,8 @@ NFS_OVERLAY="192.168.1.1:/var/lib/overlay"
|
||||
fastboot)
|
||||
FASTBOOT=yes
|
||||
;;
|
||||
netboot)
|
||||
NETBOOT=yes
|
||||
;;
|
||||
nbdroot=*)
|
||||
nbdroot="${arg#nbdroot=}"
|
||||
NBD_ROOT_SERVER=$( echo "${nbdroot}" | /bin/busybox sed 's/:.*//')
|
||||
NBD_ROOT_PORT=$( echo "${nbdroot}" | /bin/busybox sed 's/.*://')
|
||||
;;
|
||||
nbdserver=*)
|
||||
NBD_ROOT_SERVER="${arg#nbdserver=}"
|
||||
;;
|
||||
nbdport=*)
|
||||
NBD_ROOT_PORT="${arg#nbdport=}"
|
||||
;;
|
||||
nfsoverlay=*)
|
||||
NFS_OVERLAY="${arg#nfsoverlay=}"
|
||||
break=*)
|
||||
BREAK="${arg#*=}"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
@ -92,10 +74,6 @@ NFS_OVERLAY="192.168.1.1:/var/lib/overlay"
|
||||
fi
|
||||
}
|
||||
|
||||
error() {
|
||||
echo "Error Code: $1 that means: $2"
|
||||
}
|
||||
|
||||
debug_shell() {
|
||||
echo "### Starting debugging shell... type exit to quit ###"
|
||||
|
||||
@ -105,29 +83,66 @@ NFS_OVERLAY="192.168.1.1:/var/lib/overlay"
|
||||
/bin/busybox sh </dev/tty1 >/dev/tty1 2>&1
|
||||
}
|
||||
|
||||
error() {
|
||||
# Display fatal error message
|
||||
# $1:action which caused error, $2:message
|
||||
echo "*** Error in $BOOT_STEP: $1: $2 ***"
|
||||
if [ -z "$DEBUG" ]; then
|
||||
/bin/busybox halt
|
||||
else
|
||||
debug_shell
|
||||
fi
|
||||
}
|
||||
|
||||
break_after() {
|
||||
# Start debug shell after boot step $1
|
||||
case $BREAK in
|
||||
all|*$1*)
|
||||
debug_shell
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Mount handlers
|
||||
# All handlers take the following parameters:
|
||||
# $1:target, $2:mountpoint, $3:mount options, [$4:fs type]
|
||||
|
||||
mount_common() {
|
||||
# Common mount handler, handles block devices and filesystem images
|
||||
MOUNT_OPTIONS="-o $3"
|
||||
[ -n "$4" ] && MOUNT_OPTIONS="-t $4 $MOUNT_OPTIONS"
|
||||
|
||||
for i in 1 2 3 4 5 6 7 8 9 10; do
|
||||
ERR_ENV=1
|
||||
|
||||
$IONICE /bin/busybox mount $MOUNT_OPTIONS $1 $2 > /dev/null 2>&1
|
||||
[ "$?" -eq "0" ] && ERR_ENV=0 && break
|
||||
|
||||
/bin/busybox usleep 1000000
|
||||
done
|
||||
[ "$ERR_ENV" -ne "0" ] && error "mount_common" "Could not mount $1"
|
||||
}
|
||||
|
||||
mount_part() {
|
||||
# progress "check filesystem $1 ..."
|
||||
# /sbin/fsck -M -T -a $1 > /dev/null 2>&1
|
||||
# Mount a local or network filesystem
|
||||
# $1:[TYPE=]target, $2:mountpoint, $3:mount options, [$4:fs type]
|
||||
MOUNT_TARGET="${1#*=}"
|
||||
|
||||
for i in 1 2 3 4 5 6 7 8 9 10; do
|
||||
ERR_ENV=1
|
||||
MOUNT_OPTIONS="-o $3 $1 $2"
|
||||
|
||||
if [ -n "$4" ]; then
|
||||
MOUNT_OPTIONS="-t $4 $MOUNT_OPTIONS"
|
||||
fi
|
||||
|
||||
progress "mount filesystem $1 ..."
|
||||
$IONICE /bin/busybox mount $MOUNT_OPTIONS > /dev/null 2>&1
|
||||
[ "$?" -eq "0" ] && ERR_ENV=0 && break
|
||||
|
||||
/bin/busybox usleep 1000000
|
||||
done
|
||||
[ "$ERR_ENV" -ne "0" ] && error "INIT_4" "Could not mount $1" && debug_shell
|
||||
progress "mount filesystem $1 ..."
|
||||
case $1 in
|
||||
LABEL=*|UUID=*|/*)
|
||||
MOUNT_CMD="mount_common"
|
||||
MOUNT_TARGET="$1"
|
||||
;;
|
||||
*)
|
||||
error "mount_part" "Unknown filesystem $1"
|
||||
;;
|
||||
esac
|
||||
$MOUNT_CMD "$MOUNT_TARGET" "$2" "$3" "$4"
|
||||
}
|
||||
|
||||
update() {
|
||||
if [ -f "$UPDATE_DIR/$2" ]; then
|
||||
if [ -f "$UPDATE_DIR/$2" -a -f "$3" ]; then
|
||||
echo "updating $1..."
|
||||
$IONICE /bin/busybox mount -o remount,rw /flash
|
||||
$IONICE /bin/busybox mv $UPDATE_DIR/$2 $3
|
||||
@ -154,83 +169,73 @@ NFS_OVERLAY="192.168.1.1:/var/lib/overlay"
|
||||
done
|
||||
}
|
||||
|
||||
mount_nbd() {
|
||||
retry_nr=0
|
||||
retry_delay=20
|
||||
OVERLAY_DIR=`cat /sys/class/net/eth0/address | /bin/busybox tr -d :`
|
||||
|
||||
while [ ${retry_nr} -lt ${retry_delay} ] && [ ! -e /sysroot/sbin/init ]; do
|
||||
[ ${retry_nr} -gt 0 ] && \
|
||||
$IONICE /bin/busybox nbd-client $NBD_ROOT_SERVER $NBD_ROOT_PORT /dev/nbd0 && \
|
||||
mount_part "/dev/nbd0" "/sysroot" "ro" "squashfs"
|
||||
|
||||
retry_nr=$(( ${retry_nr} + 1 ))
|
||||
|
||||
[ ! -e /sysroot/sbin/init ] && /bin/busybox usleep 1000000
|
||||
|
||||
[ ${retry_nr} -gt 0 ]
|
||||
load_modules() {
|
||||
progress "Loading kernel modules"
|
||||
[ ! -f "/etc/modules" ] && return
|
||||
for module in $(cat /etc/modules); do
|
||||
progress "Loading kernel module $module"
|
||||
/bin/busybox insmod "$MODULE_DIR/$module" || \
|
||||
error "load_modules" "Failed to load kernel module $module"
|
||||
done
|
||||
|
||||
if [ ! -e /sysroot/sbin/init ]; then
|
||||
error "INIT_2" "Could not mount NBD root from $NBD_ROOT_SERVER port $NBD_ROOT_PORT"
|
||||
debug_shell
|
||||
fi
|
||||
|
||||
mount_part "$NFS_OVERLAY" "/sysroot/storage" "rw,nolock,retrans=10" "nfs"
|
||||
|
||||
if [ ! -d /sysroot/storage/$OVERLAY_DIR ]; then
|
||||
mkdir /sysroot/storage/$OVERLAY_DIR
|
||||
fi
|
||||
|
||||
/bin/busybox umount /sysroot/storage
|
||||
mount_part "$NFS_OVERLAY/$OVERLAY_DIR" "/sysroot/storage" "rw,nolock" "nfs"
|
||||
}
|
||||
|
||||
mount_disk() {
|
||||
# deal with hfs partitions
|
||||
check_disks() {
|
||||
progress "Checking disks"
|
||||
if [ -x /sbin/fsck_hfs ]; then
|
||||
# deal with hfs partitions
|
||||
hfsdiskprep
|
||||
fi
|
||||
}
|
||||
|
||||
mount_disks() {
|
||||
progress "Mounting disks"
|
||||
mount_part "$boot" "/flash" "ro,noatime"
|
||||
mount_part "$disk" "/storage" "rw,noatime"
|
||||
}
|
||||
|
||||
if [ -n "$disk" ]; then
|
||||
mount_part "$disk" "/storage" "rw,noatime"
|
||||
|
||||
if [ -f "/flash/MACH_KERNEL" ]; then
|
||||
IMAGE_KERNEL="MACH_KERNEL"
|
||||
fi
|
||||
|
||||
update "Kernel" "$IMAGE_KERNEL" "/flash/$IMAGE_KERNEL"
|
||||
update "System" "$IMAGE_SYSTEM" "/flash/$IMAGE_SYSTEM"
|
||||
|
||||
if test "$REBOOT" -eq "1"; then
|
||||
echo "System reboots now..." && \
|
||||
/bin/busybox reboot
|
||||
fi
|
||||
check_update() {
|
||||
progress "Checking for updates"
|
||||
if [ -f "/flash/MACH_KERNEL" ]; then
|
||||
IMAGE_KERNEL="MACH_KERNEL"
|
||||
fi
|
||||
|
||||
if [ -f "/flash/$IMAGE_SYSTEM" ]; then
|
||||
mount_part "/flash/$IMAGE_SYSTEM" "/sysroot" "ro,loop"
|
||||
[ "$ERR_ENV" -ne "0" ] && debug_shell
|
||||
else
|
||||
error "INIT_2" "Could not find system."
|
||||
debug_shell
|
||||
fi
|
||||
update "Kernel" "$IMAGE_KERNEL" "/flash/$IMAGE_KERNEL"
|
||||
update "System" "$IMAGE_SYSTEM" "/flash/$IMAGE_SYSTEM"
|
||||
|
||||
# move /flash and /storage to /sysroot
|
||||
/bin/busybox mount --move /flash /sysroot/flash
|
||||
|
||||
if [ -n "$disk" ]; then
|
||||
/bin/busybox mount --move /storage /sysroot/storage
|
||||
if test "$REBOOT" -eq "1"; then
|
||||
echo "System reboots now..." && \
|
||||
/bin/busybox reboot
|
||||
fi
|
||||
}
|
||||
|
||||
if [ -z "$NETBOOT" ]; then
|
||||
mount_disk
|
||||
else
|
||||
mount_nbd
|
||||
fi
|
||||
prepare_sysroot() {
|
||||
progress "Preparing system"
|
||||
|
||||
if [ -f "/flash/$IMAGE_SYSTEM" ]; then
|
||||
# /flash is filesystem with system image file
|
||||
mount_part "/flash/$IMAGE_SYSTEM" "/sysroot" "ro,loop"
|
||||
/bin/busybox mount --move /flash /sysroot/flash
|
||||
else
|
||||
# /flash is actual root filesystem
|
||||
/bin/busybox mount --move /flash /sysroot
|
||||
fi
|
||||
/bin/busybox mount --move /storage /sysroot/storage
|
||||
|
||||
[ -f "/sysroot/sbin/init" ] || error "final_check" "Could not find system."
|
||||
}
|
||||
|
||||
# main boot sequence
|
||||
for BOOT_STEP in \
|
||||
load_modules \
|
||||
check_disks \
|
||||
mount_disks \
|
||||
check_update \
|
||||
prepare_sysroot; do
|
||||
$BOOT_STEP
|
||||
[ -n "$DEBUG" ] && break_after $BOOT_STEP
|
||||
done
|
||||
|
||||
BOOT_STEP=final
|
||||
|
||||
# move some special filesystems
|
||||
/bin/busybox mount --move /dev /sysroot/dev
|
||||
@ -240,5 +245,4 @@ NFS_OVERLAY="192.168.1.1:/var/lib/overlay"
|
||||
# switch to new sysroot and start real init
|
||||
exec /bin/busybox switch_root /sysroot /sbin/init
|
||||
|
||||
error "INIT_3" "Error in initramfs. Could not switch to new root"
|
||||
debug_shell
|
||||
error "switch_root" "Error in initramfs. Could not switch to new root"
|
||||
|
Loading…
x
Reference in New Issue
Block a user