1#!/bin/sh 2 3kgetopt () 4{ 5 _cmdline="$(cat /proc/cmdline)" 6 _optname="$1" 7 _optval="$2" 8 for _opt in $_cmdline 9 do 10 case "$_opt" in 11 "${_optname}"=*) 12 _optval="${_opt##"${_optname}"=}" 13 ;; 14 *) 15 ;; 16 esac 17 done 18 [ -n "$_optval" ] && echo "$_optval" 19} 20 21fslist="proc sys dev run" 22rodir=/mnt/rofs 23mmcdev="/dev/mmcblk0" 24rwfsdev="/dev/disk/by-partlabel/rwfs" 25 26cd / 27 28# We want to make all the directories in $fslist, not one directory named by 29# concatonating the names with spaces 30# 31# shellcheck disable=SC2086 32mkdir -p $fslist 33 34mount dev dev -tdevtmpfs 35mount sys sys -tsysfs 36mount proc proc -tproc 37mount tmpfs run -t tmpfs -o mode=755,nodev 38 39# Wait up to 5s for the mmc device to appear. Continue even if the count is 40# exceeded. A failure will be caught later like in the mount command. 41count=0 42while [ $count -lt 5 ]; do 43 if [ -e "${mmcdev}" ]; then 44 break 45 fi 46 sleep 1 47 count=$((count + 1)) 48done 49 50# Move the secondary GPT to the end of the device if needed. Look for the GPT 51# header signature "EFI PART" located 512 bytes from the end of the device. 52if ! tail -c 512 "${mmcdev}" | hexdump -C -n 8 | grep -q "EFI PART"; then 53 sgdisk -e "${mmcdev}" 54 partprobe 55fi 56 57# There eMMC GPT labels for the rootfs are rofs-a and rofs-b, and the label for 58# the read-write partition is rwfs. Run udev to make the partition labels show 59# up. Mounting by label allows for partition numbers to change if needed. 60udevd --daemon 61udevadm trigger --type=devices --action=add 62udevadm settle --timeout=10 63# The real udevd will be started a bit later by systemd-udevd.service 64# so kill the one we started above now that we have the needed 65# devices loaded 66udevadm control --exit 67 68mkdir -p $rodir 69if ! mount /dev/disk/by-partlabel/"$(kgetopt root=PARTLABEL)" $rodir -t ext4 -o ro; then 70 /bin/sh 71fi 72 73# Determine if a factory reset has been requested 74mkdir -p /var/lock 75resetval=$(fw_printenv -n rwreset 2>/dev/null) 76if gpiopresent=$(gpiofind factory-reset-toggle) ; then 77 # gpiopresent contains both the gpiochip and line number as 78 # separate words, and gpioget needs to see them as such. 79 # shellcheck disable=SC2086 80 gpioval=$(gpioget $gpiopresent) 81else 82 gpioval="" 83fi 84# Prevent unnecessary resets on first boot 85if [ -n "$gpioval" ] && [ -z "$resetval" ]; then 86 fw_setenv rwreset "$gpioval" 87 resetval=$gpioval 88fi 89if [ "$resetval" = "true" ] || [ -n "$gpioval" ] && [ "$resetval" != "$gpioval" ]; then 90 echo "Factory reset requested." 91 if ! mkfs.ext4 -F "${rwfsdev}"; then 92 echo "Reformat for factory reset failed." 93 /bin/sh 94 else 95 # gpioval will be an empty string if factory-reset-toggle was not found 96 fw_setenv rwreset "$gpioval" 97 echo "rwfs has been formatted." 98 fi 99fi 100 101fsck.ext4 -p "${rwfsdev}" 102if ! mount "${rwfsdev}" $rodir/var -t ext4 -o rw; then 103 /bin/sh 104fi 105 106rm -rf $rodir/var/persist/etc-work/ 107mkdir -p $rodir/var/persist/etc $rodir/var/persist/etc-work $rodir/var/persist/home/root 108mount overlay $rodir/etc -t overlay -o lowerdir=$rodir/etc,upperdir=$rodir/var/persist/etc,workdir=$rodir/var/persist/etc-work 109 110init="$(kgetopt init /sbin/init)" 111 112for f in $fslist; do 113 mount --move "$f" "$rodir/$f" 114done 115 116exec switch_root $rodir "$init" 117