#!/bin/sh

# Copyright (C) 2022, Kiloview Electronics Co., Ltd.
# Gongxing Jiang <jiangjianghu@kiloview.com>
# Jacob Zuo <jacob@kiloview.com>

# If user hold the button while starting up, it will fall into
# the RECOVERY mode, that is, show a menu to prompt user to 
# select 'RECOVER from SDCARD', 'RECOVER from USB', and 'REBOOT'.

BUTTON=458  # The BUTTON is FPGA PL I/O: 338+78+42
LED2=426  # The LED2 is FPGA PL I/O: 338+78+10
LED3=339  # The LED3 is FPGA PL I/O: 338+1
LED_ON=0
LED_OFF=1
led2_pid=

#GPIO system path
GPIO_PATH=/sys/class/gpio


#The external boot device (sd/tf-card), which is /dev/${EXT_SD_DEVICE}
EXT_SD_DEVICE=mmcblk0

# /dev/mmcblk0p2

#Mount the disk partitions at:
MOUNT_AT=/media

#Each partition mounting with this prefix:
MOUNT_PREFIX=sd-mmcblk0
EXT_MOUNT_PREFIX=sd-mmcblk1

#Partition BOOT
PART_BOOT=p1

#Partition ROOTFS
PART_ROOTFS=p2

PART_DATA=p3

#Partition UPGRADE temporary files.
PART_UPGRADE=p4


#Partition LOG
PART_LOG=p6


check_dir(){
    if [ ! -d $1 ]; then
        if [ -e $1 ]; then
            rm -rf $1
        fi
        mkdir -p $1
    fi
}


umount_devce() {
    if [ -z "$1" ]; then
        echo "Cannot umount null device."
        return
    fi

    all_mounts=`grep $1 /proc/mounts | awk '{print $2}'`
    for dev in $all_mounts; do
        echo "Umount $dev ..."
        counter=0
        umount "$dev" 2>/dev/null

        while [ $? -ne 0 -a $counter -lt 5 ]; do
            counter=$(expr $counter + 1)
            upd_warn "Umount $dev failed! wait a while ..."
            sleep 1
            umount "$dev"
        done

        if [ $counter -ge 5 ]; then
            # quit 1
            echo "Umount $dev failed!"
            return
        fi
    done
}


do_switch_root() {
    rootfs_part=$1
    if [ -z "$rootfs_part" ]; then
        echo "Mount root filesystem failed! Enter the recovery mode instead!"
        exec /sbin/init
    fi

    rootfs_dir=`grep ${rootfs_part} /proc/mounts | awk '{print$2}'`
    if [ -n "$rootfs_dir" ]; then
        umount_devce $rootfs_part
    fi
    check_dir /mnt

    mount -t ext4 $rootfs_part /mnt

    if [ $? -eq 0 ]; then
        echo "Checking the filesystem of $rootfs_part ..."
        init_entry=""
        # if [ -x /mnt/initrc ]; then
        #     init_entry="/initrc"
        # elif [ -x /mnt/init ]; then
        #     init_entry="/init"
        if [ -x /mnt/sbin/init ]; then
            init_entry="/sbin/init"
        fi
        if [ -z "${init_entry}" ]; then
            echo "FATAL: The partition $rootfs_part without a valid root filesystem. Anything wrong?"
            echo "Enter the recovery mode instead!"
            exec /sbin/init
        else
            echo "Switched root to $rootfs_part, start at ${init_entry} ..."
            exec switch_root /mnt ${init_entry}
        fi
    else
        echo "Mount root filesystem of $rootfs_part failed! Enter the recovery mode instead!"
        exec /sbin/init
    fi
}

echo "Mounting /proc ..."
mount -t proc proc /proc
echo "Mounting /sys ..."
mount -t sysfs sysfs /sys
echo "Hardware probing ..."
mdev -s

roootfs_dev="/dev/${EXT_SD_DEVICE}${PART_ROOTFS}"
data_dev="/dev/${EXT_SD_DEVICE}${PART_DATA}"
upgrade_dev="/dev/${EXT_SD_DEVICE}${PART_UPGRADE}"

/fsck.ext4 -yf $roootfs_dev
echo "fsck the part of $roootfs_dev ... ret: $?"
/fsck.ext4 -yf $data_dev
echo "fsck the part of $data_dev ... ret: $?"
/fsck.ext4 -yf $upgrade_dev
echo "fsck the part of $upgrade_dev ... ret: $?"

if [ -b ${roootfs_dev} ] ; then
    echo "Preparing switch root to ${roootfs_dev} ..."
    do_switch_root  ${roootfs_dev}
else
    echo "The boot device ${roootfs_dev} looks to be not a valid root filesystem. Enter the recovery mode instead!"
    exec /sbin/init
fi
