Boots into initramfs then switch_root
This commit is contained in:
@@ -1,24 +1,114 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
mount -t devtmpfs devtmpfs /dev
|
||||
mount -t proc proc /proc
|
||||
mount -t sysfs sysfs /sys
|
||||
log() {
|
||||
echo "[init] $*" >&2
|
||||
}
|
||||
|
||||
# Spin the fan
|
||||
echo 100 > /sys/class/hwmon/hwmon0/pwm1
|
||||
panic() {
|
||||
echo "initramfs panic: $*" >&2
|
||||
exec sh
|
||||
}
|
||||
|
||||
mount_or_panic() {
|
||||
mount "$@" || panic "mount failed: $*"
|
||||
}
|
||||
|
||||
mount_retry() {
|
||||
dev="$1"
|
||||
target="$2"
|
||||
fstype="$3"
|
||||
opts="$4"
|
||||
|
||||
i=0
|
||||
while :; do
|
||||
if mount -o "$opts" -t "$fstype" "$dev" "$target"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
i=$((i + 1))
|
||||
[ "$i" -ge 50 ] && panic "Timed out mounting $dev on $target"
|
||||
sleep 0.2
|
||||
done
|
||||
}
|
||||
|
||||
wait_for_path() {
|
||||
path="$1"
|
||||
i=0
|
||||
while [ ! -e "$path" ]; do
|
||||
i=$((i + 1))
|
||||
[ "$i" -ge 50 ] && panic "Timed out waiting for $path"
|
||||
sleep 0.2
|
||||
done
|
||||
}
|
||||
|
||||
mkdir -p /dev /proc /sys /run
|
||||
mount_or_panic -t devtmpfs devtmpfs /dev
|
||||
mount_or_panic -t proc proc /proc
|
||||
mount_or_panic -t sysfs sysfs /sys
|
||||
mount_or_panic -t tmpfs tmpfs /run
|
||||
|
||||
echo 1 > /proc/sys/kernel/printk
|
||||
|
||||
# Optional but nice
|
||||
mkdir -p /dev/pts
|
||||
mount -t devpts devpts /dev/pts
|
||||
mount_or_panic -t devpts devpts /dev/pts
|
||||
|
||||
echo "Booting kernel took $(cut -d' ' -f1 /proc/uptime) seconds."
|
||||
echo "Dropping to shell on ttyS0..."
|
||||
# Optional early fan kick. Do not fail boot if this path is not ready yet.
|
||||
if [ -w /sys/class/hwmon/hwmon0/pwm1 ]; then
|
||||
echo 100 > /sys/class/hwmon/hwmon0/pwm1 || true
|
||||
fi
|
||||
|
||||
. /etc/build-info
|
||||
log "Booting kernel took $(cut -d' ' -f1 /proc/uptime) seconds."
|
||||
|
||||
while true; do
|
||||
setsid cttyhack /bin/sh
|
||||
echo "Shell exited. Starting another one..."
|
||||
. /etc/build-info || panic "failed to source /etc/build-info"
|
||||
|
||||
ROOT_DEV=""
|
||||
DATA_DEV=""
|
||||
|
||||
for arg in $(cat /proc/cmdline); do
|
||||
case "$arg" in
|
||||
root=*)
|
||||
ROOT_DEV="${arg#root=}"
|
||||
;;
|
||||
data=*)
|
||||
DATA_DEV="${arg#data=}"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
exec poweroff -f
|
||||
[ -n "$ROOT_DEV" ] || {
|
||||
log "No root= specified in cmdline"
|
||||
exec sh
|
||||
}
|
||||
|
||||
[ -n "$DATA_DEV" ] || {
|
||||
log "No data= specified in cmdline"
|
||||
exec sh
|
||||
}
|
||||
|
||||
wait_for_path "$DATA_DEV"
|
||||
|
||||
e2fsck -p "$DATA_DEV" || {
|
||||
echo "Auto fsck failed, forcing repair"
|
||||
e2fsck -y "$DATA_DEV" || panic "fsck failed on $DATA_DEV"
|
||||
}
|
||||
|
||||
mkdir -p /newroot
|
||||
mount_retry "$ROOT_DEV" /newroot ext4 ro
|
||||
mount_retry "$DATA_DEV" /newroot/data ext4 rw
|
||||
|
||||
mount_or_panic --bind /newroot/data/var /newroot/var
|
||||
|
||||
mount_or_panic -t overlay overlay \
|
||||
-o lowerdir=/newroot/etc,upperdir=/newroot/data/etc-overlay/upper,workdir=/newroot/data/etc-overlay/work \
|
||||
/newroot/etc
|
||||
|
||||
mount_or_panic --move /dev /newroot/dev
|
||||
mount_or_panic --move /proc /newroot/proc
|
||||
mount_or_panic --move /sys /newroot/sys
|
||||
mount_or_panic --move /run /newroot/run
|
||||
|
||||
log "Switching root to $ROOT_DEV"
|
||||
exec switch_root /newroot /sbin/init
|
||||
|
||||
panic "switch_root returned unexpectedly"
|
||||
|
||||
Reference in New Issue
Block a user