#!/bin/sh
#1.init console
sleep 2
mknod -m 666  /dev/console  c 5 1
busybox echo "INITRAMFS: mknod /dev/console" > /dev/console

1>/dev/console 2>&1

#2.mount sys&proc
echo "Exec initramfs init ... ..."
echo "Mounting proc and sys ... ..."
mount -t proc proc /proc > /dev/console 2>&1
mount -t sysfs sysfs /sys > /dev/console 2>&1

mdev -s > /dev/console 2>&1
#chmod 777 /lib/cryptfs

#identify the ab partition and cmdline root=? rootfstype=? and /init param
is_ab_partition=0
rootfs_value=""
dm_name=""
params="$@"
mount_system_a=0
mount_system_b=0
mount_system=0
rootfs_fstype="squashfs"
if grep -q 'root=' /proc/cmdline; then
    rootfs_value=$(awk -F'root=' '
        /root=/{
        gsub(/\r|\n/, "")
        print $2
    }' /proc/cmdline | cut -d' ' -f1)
else
    echo "root= not found in /proc/cmdline" > /dev/console 2>&1
fi

if grep -q 'rootfstype=' /proc/cmdline; then
    rootfs_fstype=$(awk -F'rootfstype=' '
        /rootfstype=/{
        gsub(/\r|\n/, "")
        print $2
    }' /proc/cmdline | cut -d' ' -f1)
else
    echo "rootfstype= not found in /proc/cmdline, user defalut value: squashfs" > /dev/console 2>&1
fi

while true
do
    if [ -e $rootfs_value ]; then
        break
    fi
    mdev -s
    echo "waiting root dev ready: $rootfs_value" > /dev/console 2>&1
done

#let found_sd=`grep "/dev/mmcblk1p" /proc/cmdline -o | wc -l`
#if [ $found_sd -ne 0 ]; then
        for folder in $(ls /sys/class/block/ | grep 'mmcblk1p');do
            id=${folder#*mmcblk1p}
            subname=$(awk -F'PARTNAME=' '
            /PARTNAME=/{
            gsub(/\r|\n/, "")
            print $2
            }' /sys/class/block/mmcblk1/$folder/uevent | cut -d' ' -f1)
            if [ "$rootfs_value" == "/dev/mmcblk1p$id" ]; then
                dm_name=$subname
            fi
            ln -s /dev/mmcblk1p$id /dev/$subname
        done
#fi

#let found_nand=`grep "/dev/ubi0" /proc/cmdline -o | wc -l`
#if [ $found_nand -ne 0 ]; then
        for folder in $(ls /sys/class/ubi/ubi0 | grep 'ubi0_*');do
            id=${folder#*ubi0_}
            subname=$(awk -F'PARTNAME=' '
            /PARTNAME=/{
            gsub(/\r|\n/, "")
            print $2
            }' /sys/class/ubi/ubi0/$folder/name | cut -d' ' -f1)
            if [ "$rootfs_value" == "/dev/ubi0_$id" ]; then
                dm_name=$subname
            fi
            ln -s /dev/ubi0_$id /dev/$subname
        done
#if

#let found_mmc=`grep "/dev/mmcblk0p" /proc/cmdline -o | wc -l`
#if [ $found_mmc -ne 0 ]; then
        for folder in $(ls /sys/class/block/ | grep 'mmcblk0p');do
            id=${folder#*mmcblk0p}
            subname=$(awk -F'PARTNAME=' '
            /PARTNAME=/{
            gsub(/\r|\n/, "")
            print $2
            }' /sys/class/block/mmcblk0/$folder/uevent | cut -d' ' -f1)
            if [ "$rootfs_value" == "/dev/mmcblk0p$id" ]; then
                dm_name=$subname
            fi
            ln -s /dev/mmcblk0p$id /dev/$subname
        done
#if

#let found_ufs=`grep "/dev/sda" /proc/cmdline -o | wc -l`
#if [ $found_ufs -ne 0 ]; then
        for folder in $(ls /sys/block/sda/ | grep 'sda');do
            id=${folder#*sda}
            name=$(cat /sys/block/sda/$folder/uevent)
            subname=$(awk -F'PARTNAME=' '
            /PARTNAME=/{
            gsub(/\r|\n/, "")
            print $2
            }' /sys/block/sda/$folder/uevent | cut -d' ' -f1)
            if [ "$rootfs_value" == "/dev/sda$id" ]; then
                dm_name=$subname
            fi
            ln -s /dev/sda$id /dev/$subname
        done
#fi

#/bin/sh < /dev/ttyS1 > /dev/ttyS1 2>&1
#/bin/sh < /dev/console > /dev/console 2>&1

if ls /dev/ | grep -q '^system_'; then
        is_ab_partition=1
fi

echo "is_ab_partition = $is_ab_partition" > /dev/console 2>&1
echo "root= $rootfs_value" > /dev/console 2>&1
echo "dm_name= $dm_name" > /dev/console 2>&1

#/bin/sh < /dev/ttyS1 > /dev/ttyS1 2>&1
#/bin/sh < /dev/console > /dev/console 2>&1

function rootfs_reboot() {
    /usr/bin/fw_setenv dm_verity_fail 1
    reboot -f
}


if [ -e "/usr/bin/unisoc-fscrypt" ]; then
    if [ "$is_ab_partition" = "1" ]; then
            mount -t $rootfs_fstype /dev/system_a /mnt
            if [ $? -eq 0 ]; then
                mount_system_a=1
                umount /mnt
            fi
            mount -t $rootfs_fstype /dev/system_b /mnt
            if [ $? -eq 0 ]; then
                mount_system_b=1
                umount /mnt
            fi
    else
        mount -t $rootfs_fstype /dev/system /mnt
        if [ $? -eq 0 ]; then
            mount_system=1
            umount /mnt
        fi
    fi

    #3.Cryptfs & resize2fs
    echo "Begin cryptfs ... ..." > /dev/console 2>&1
    if [ "$mount_system_a" = "1" ]; then
            echo "ab partition" > /dev/console 2>&1
            /usr/bin/unisoc-fscrypt /dev/system_a /mnt $rootfs_fstype system_a 1 0 > /var/cryptfs.log 2>&1 &
            wait $!
            ret=$?
            while IFS= read -r line; do
            echo "$line" > /dev/console 2>&1
            done < /var/cryptfs.log

            if [ $ret -eq 255 ]; then
                echo "first boot rootfs:$dm_name encrypt failed, Reboot......" > /dev/console
                poweroff -f
            fi
    fi
    if [ "$mount_system_b" = "1" ]; then
            /usr/bin/unisoc-fscrypt /dev/system_b /mnt $rootfs_fstype system_b 1 0 > /var/cryptfs_0.log 2>&1 &
            wait $!
            ret=$?
            while IFS= read -r line; do
            echo "$line" > /dev/console 2>&1
            done < /var/cryptfs_0.log

            if [ $ret -eq 255 ]; then
                echo "first boot rootfs:$dm_name encrypt failed, Reboot......" > /dev/console
                poweroff -f
            fi
    fi
    if [ "$mount_system" = "1" ]; then
            echo "a partition" > /dev/console 2>&1
            /usr/bin/unisoc-fscrypt $rootfs_value /mnt $rootfs_fstype $dm_name 1 0 > /var/cryptfs_1.log 2>&1 &
            wait $!
            ret=$?
            while IFS= read -r line; do
            echo "$line" > /dev/console 2>&1
            done < /var/cryptfs_1.log
            if [ $ret -eq 255 ]; then
                echo "first boot rootfs:$dm_name encrypt failed, Reboot......" > /dev/console
                poweroff -f
            fi
    fi

    echo "mount root" > /var/cryptfs_2.log 2>&1 &
    /usr/bin/unisoc-fscrypt $rootfs_value /mnt $rootfs_fstype $dm_name 1 0 > /var/cryptfs_2.log 2>&1 &
    wait $!
    dev_minor=$?
    while IFS= read -r line; do
    echo "$line" > /dev/console 2>&1
    done < /var/cryptfs_2.log
    if [ $dev_minor -eq 255 ]; then
        echo "rootfs:$dm_name encrypt failed, Reboot......" > /dev/console
        rootfs_reboot
    fi
    echo "Success cryptfs ... ..." > /dev/console 2>&1
    rootfs_value="/dev/dm-$dev_minor"

    if [ -e "/usr/bin/anti-rollback" ]; then
        /usr/bin/anti-rollback $dm_name > /dev/console 2>&1 &
        wait $!
        if [ $? -eq 1 ]; then
            echo "rootfs anti-rollback verify success" > /dev/console
        else
            echo "rootfs anti-rollback verify failed, Reboot......" > /dev/console
            umount /mnt
            poweroff -f
        fi
    fi
    echo "umount rootfs" > /dev/console 2>&1
    umount /mnt
fi
echo "root= $rootfs_value" > /dev/console 2>&1

# for dm-verity
if [ -e "/usr/bin/veritymgr" ]; then
    echo "veritymgr for rootfs begin..." > /dev/console 2>&1
    /usr/bin/veritymgr $rootfs_value $rootfs_fstype $dm_name > /dev/console 2>&1
    ret=$?
    echo "ret=$ret" > /dev/console
    # if return value of veritymgr less than 0, means error, the following ret will be set to ret+256
    #     255(-1): verity fail
    #     252(-4): verity disabled
    if [ $ret -eq 255 ]; then
        echo "veritymgr for rootfs fail, will reboot..." > /dev/console
        rootfs_reboot
    elif [ $ret -eq 252 ]; then
        echo "veritymgr for rootfs disabled, skip verity..." > /dev/console
    else
        echo "veritymgr for rootfs success..." > /dev/console
        rootfs_value="/dev/dm-$ret"
        echo "change root to $rootfs_value" > /dev/console 2>&1
    fi
fi

#4.switch rootfs
echo "Mount rootfs ... ..." > /dev/console
ls -al /mnt > /dev/console
mount -t $rootfs_fstype $rootfs_value /mnt > /dev/console 2>&1

# need dev/console as output&input
#/bin/sh < /dev/ttyS1 > /dev/ttyS1 2>&1
#/bin/sh < /dev/console > /dev/console 2>&1
echo "Mount --move proc sys dev ... ..." > /dev/console
mount --move /proc /mnt/proc
mount --move /sys /mnt/sys
mount --move /dev /mnt/dev
rm /dev/console

echo "Switch to real rootfs... PID=$$" > /dev/console
exec switch_root /mnt /sbin/init $params
echo "exec switch_root end" > /dev/console

