Initial commit
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
#!/bin/sh
|
||||
|
||||
kgetopt ()
|
||||
{
|
||||
_cmdline="$(cat /proc/cmdline)"
|
||||
_optname="$1"
|
||||
_optval="$2"
|
||||
for _opt in $_cmdline
|
||||
do
|
||||
case "$_opt" in
|
||||
"${_optname}"=*)
|
||||
_optval="${_opt##"${_optname}"=}"
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
done
|
||||
[ -n "$_optval" ] && echo "$_optval"
|
||||
}
|
||||
|
||||
fslist="proc sys dev run"
|
||||
rodir=/mnt/rofs
|
||||
mmcdev="/dev/mmcblk0"
|
||||
rwfsdev="/dev/disk/by-partlabel/rwfs"
|
||||
|
||||
cd /
|
||||
|
||||
# We want to make all the directories in $fslist, not one directory named by
|
||||
# concatonating the names with spaces
|
||||
#
|
||||
# shellcheck disable=SC2086
|
||||
mkdir -p $fslist
|
||||
|
||||
mount dev dev -tdevtmpfs
|
||||
mount sys sys -tsysfs
|
||||
mount proc proc -tproc
|
||||
mount tmpfs run -t tmpfs -o mode=755,nodev
|
||||
|
||||
# Wait up to 5s for the mmc device to appear. Continue even if the count is
|
||||
# exceeded. A failure will be caught later like in the mount command.
|
||||
count=0
|
||||
while [ $count -lt 5 ]; do
|
||||
if [ -e "${mmcdev}" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
count=$((count + 1))
|
||||
done
|
||||
|
||||
# Move the secondary GPT to the end of the device if needed. Look for the GPT
|
||||
# header signature "EFI PART" located 512 bytes from the end of the device.
|
||||
if ! tail -c 512 "${mmcdev}" | hexdump -C -n 8 | grep -q "EFI PART"; then
|
||||
sgdisk -e "${mmcdev}"
|
||||
partprobe
|
||||
fi
|
||||
|
||||
# There eMMC GPT labels for the rootfs are rofs-a and rofs-b, and the label for
|
||||
# the read-write partition is rwfs. Run udev to make the partition labels show
|
||||
# up. Mounting by label allows for partition numbers to change if needed.
|
||||
udevd --daemon
|
||||
udevadm trigger --type=devices --action=add
|
||||
udevadm settle --timeout=10
|
||||
|
||||
mkdir -p $rodir
|
||||
if ! mount /dev/disk/by-partlabel/"$(kgetopt root=PARTLABEL)" $rodir -t ext4 -o ro; then
|
||||
/bin/sh
|
||||
fi
|
||||
|
||||
# Determine if a factory reset has been requested
|
||||
mkdir -p /var/lock
|
||||
resetval=$(fw_printenv -n rwreset 2>/dev/null)
|
||||
if gpiopresent=$(gpiofind factory-reset-toggle) ; then
|
||||
# gpiopresent contains both the gpiochip and line number as
|
||||
# separate words, and gpioget needs to see them as such.
|
||||
# shellcheck disable=SC2086
|
||||
gpioval=$(gpioget $gpiopresent)
|
||||
else
|
||||
gpioval=""
|
||||
fi
|
||||
# Prevent unnecessary resets on first boot
|
||||
if [ -n "$gpioval" ] && [ -z "$resetval" ]; then
|
||||
fw_setenv rwreset "$gpioval"
|
||||
resetval=$gpioval
|
||||
fi
|
||||
if [ "$resetval" = "true" ] || [ -n "$gpioval" ] && [ "$resetval" != "$gpioval" ]; then
|
||||
echo "Factory reset requested."
|
||||
if ! mkfs.ext4 -F "${rwfsdev}"; then
|
||||
echo "Reformat for factory reset failed."
|
||||
/bin/sh
|
||||
else
|
||||
# gpioval will be an empty string if factory-reset-toggle was not found
|
||||
fw_setenv rwreset "$gpioval"
|
||||
echo "rwfs has been formatted."
|
||||
fi
|
||||
fi
|
||||
|
||||
fsck.ext4 -p "${rwfsdev}"
|
||||
if ! mount "${rwfsdev}" $rodir/var -t ext4 -o rw; then
|
||||
/bin/sh
|
||||
fi
|
||||
|
||||
rm -rf $rodir/var/persist/etc-work/
|
||||
mkdir -p $rodir/var/persist/etc $rodir/var/persist/etc-work $rodir/var/persist/home/root
|
||||
mount overlay $rodir/etc -t overlay -o lowerdir=$rodir/etc,upperdir=$rodir/var/persist/etc,workdir=$rodir/var/persist/etc-work
|
||||
|
||||
init="$(kgetopt init /sbin/init)"
|
||||
|
||||
for f in $fslist; do
|
||||
mount --move "$f" "$rodir/$f"
|
||||
done
|
||||
|
||||
exec switch_root $rodir "$init"
|
||||
Reference in New Issue
Block a user