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