Files
BPI-CM9-Linux/amlbian/patches/ramfs/init
T

880 lines
28 KiB
Bash

#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
ROOT_MOUNT="/rootfs"
ROOT_ROMOUNT="/rom"
#ROOT_RWMOUNT="/data/overlay"
INIT="/sbin/init"
ROOT_DEVICE="/dev/system"
DATA_DEVICE="/dev/data"
DATA_MOUNT="/data" # mount point of /dev/data in ramdisk
MOUNT="/bin/mount"
UMOUNT="/bin/umount"
FIRMWARE=""
VENDOR_DEVICE="/dev/vendor"
DM_VERITY_STATUS_SYSTEM="disabled"
DM_VERITY_STATUS_VENDOR="disabled"
DM_DEV_COUNT=0
ACTIVE_SLOT=""
root_fstype="ext4"
OVERLAY_DIR="$DATA_MOUNT/overlay"
UNENCRYPTED_DIR="$DATA_MOUNT/unencrypted"
SWUPDATE_DIR="$DATA_MOUNT/swupdate"
VBMETA_DEVICE=""
OverlayFS="enabled"
data_fbe_keyblob="fbe_keyblob"
data_fbe_root_dir=""
keyring_key_id=""
DATA_FBE_STATUS="disabled"
SELINUX_REFPOLICY="@@REFPOLICY_TYPE@@"
load_ramdisk_ko() {
if [ -f /modules/ramdisk/ramdisk_install.sh ]; then
cd /modules/ramdisk
/modules/ramdisk/ramdisk_install.sh
cd -
fi
}
early_setup() {
mkdir -p /proc
mkdir -p /sys
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs none /dev
mkdir -p /run
mkdir -p /var/run
# load ramidsk ko for kernel 5.15
load_ramdisk_ko
# wait gpt partition ready and map to /dev/name
upstream_emmc_mount
}
wait_for_emmc_partition () {
i=1
while [ "$i" -le 30 ]
do
if [ -d /sys/block/mmcblk0/mmcblk0p4/ ]; then
echo "mmcblk0p4 ready"
break
fi
echo "mmcblk0p4 is not ready. Waited for 50ms"
sleep 0.05
i=$((i+1))
done
}
upstream_emmc_mount() {
echo " do upstream emmc mount"
if [ ! -f /dev/system ];then
echo "/dev/system not exist!"
wait_for_emmc_partition
if [ -d /sys/block/mmcblk0/mmcblk0p4/ ]; then
cd /sys/block/mmcblk0/
for part in mmcblk0p*
do
cd $part
# major=`cat uevent | grep MAJOR= | sed 's/.*=//'`
# minor=`cat uevent | grep MINOR= | sed 's/.*=//'`
partname=`cat uevent | grep PARTNAME= | sed 's/.*=//'`
# echo "part: $part, partname $partname, major $major, minor: $minor"
# mknod /dev/$partname b $major $minor
ln -s /dev/$part /dev/$partname
cd ..
done
fi
cd ~
else
echo "/dev/system exist!"
fi
}
read_args() {
[ -z "$CMDLINE" ] && CMDLINE=`cat /proc/cmdline`
for arg in $CMDLINE; do
optarg=`expr "x$arg" : 'x[^=]*=\(.*\)'`
case $arg in
root=*)
ROOT_DEVICE=$optarg ;;
rootfstype=*)
root_fstype=$optarg
modprobe $optarg 2> /dev/null ;;
androidboot.slot_suffix=*)
ACTIVE_SLOT=$optarg
ROOT_DEVICE=${ROOT_DEVICE}${ACTIVE_SLOT};;
androidboot.vbmeta.device=*)
VBMETA_DEVICE=$optarg ;;
LABEL=*)
label=$optarg ;;
video=*)
video_mode=$arg ;;
vga=*)
vga_mode=$arg ;;
console=*)
if [ -z "${console_params}" ]; then
console_params=$arg
else
console_params="$console_params $arg"
fi ;;
firmware=*)
FIRMWARE=$optarg ;;
init=*)
init=$optarg ;;
debugshell*)
if [ -z "$optarg" ]; then
shelltimeout=30
else
shelltimeout=$optarg
fi
esac
done
}
#on read-only rootfs, .autorelabel can not be deleted, so move this file under /data, in this situation,
#if do factory reset, selinux relabel will happen again
selinux_relabel() {
if [ "$OverlayFS" = "disabled" ]; then
if [ ! -e $ROOT_MOUNT/data/.autorelabel ] && [ -f /sbin/setfiles ]; then
echo "selinux relabel"
touch $ROOT_MOUNT/data/.autorelabel
chroot ${ROOT_MOUNT} /sbin/setfiles -F /etc/selinux/${SELINUX_REFPOLICY}/contexts/files/file_contexts /data
fi
else
if [ -f ${ROOT_MOUNT}/.autorelabel ]; then
echo "selinux relabel"
relabel_list="/data /etc"
if [ -d /$ROOT_MOUNT/lost+found ]; then
relabel_list="${relabel_list} /lost+found"
fi
chroot ${ROOT_MOUNT} /sbin/setfiles -F /etc/selinux/${SELINUX_REFPOLICY}/contexts/files/file_contexts ${relabel_list}
rm ${ROOT_MOUNT}/.autorelabel
fi
fi
}
check_set_machine_id() {
if [ "$OverlayFS" = "disabled" ]; then
if [ ! -e ${ROOT_MOUNT}/data/etc/machine-id ];then
mkdir -p $ROOT_MOUNT/data/etc
if [ -f ${ROOT_MOUNT}/etc/machine-id ]; then
cp ${ROOT_MOUNT}/etc/machine-id $ROOT_MOUNT/data/etc/
else
touch $ROOT_MOUNT/data/etc/machine-id
fi
fi
mount --bind $ROOT_MOUNT/data/etc/machine-id ${ROOT_MOUNT}/etc/machine-id
fi
if [ -f ${ROOT_MOUNT}/etc/machine-id ]; then
mid=$(cat ${ROOT_MOUNT}/etc/machine-id)
fi
if [ -z "$mid" ]; then
mid=$(cat /proc/cpuinfo | grep "^Serial" | md5sum | awk '{print $1}')
echo $mid > ${ROOT_MOUNT}/etc/machine-id
fi
}
boot_root() {
check_set_machine_id
# The rootfs does not yet contain kernel modules. Copy it!
if [ ! -d ${ROOT_MOUNT}/lib/modules ]; then
cp -rf /lib/modules ${ROOT_MOUNT}/lib/
cp -rf /lib/firmware ${ROOT_MOUNT}/lib/
cp -rf /etc/modprobe.d ${ROOT_MOUNT}/etc/
cp -rf /etc/modules-load.d ${ROOT_MOUNT}/etc/
cp -rf /etc/modules ${ROOT_MOUNT}/etc/
fi
mount -n --move /proc ${ROOT_MOUNT}/proc
mount -n --move /sys ${ROOT_MOUNT}/sys
mount -n --move /dev ${ROOT_MOUNT}/dev
if [ "$DM_VERITY_STATUS_VENDOR" = "disabled" ] && [ "${ACTIVE_SLOT}" != "" ]; then
slot=$(cat ${ROOT_MOUNT}/etc/fstab | grep -E "/dev/vendor" | awk '{print $1}' | cut -c 12-)
if [ "${ACTIVE_SLOT}" != "${slot}" ]; then
echo "switch vendor${slot} to vendor${ACTIVE_SLOT}"
sed -i "s/vendor\\${slot}/vendor\\${ACTIVE_SLOT}/" ${ROOT_MOUNT}/etc/fstab
fi
fi
selinux_relabel
cd $ROOT_MOUNT
# busybox switch_root supports -c option
exec switch_root -c /dev/console $ROOT_MOUNT $INIT ||
fatal "Couldn't switch_root, dropping to shell"
}
fatal() {
echo $1 >$CONSOLE
echo >$CONSOLE
exec sh
}
early_setup
[ -z "$CONSOLE" ] && CONSOLE="/dev/console"
read_args
#Waiting for device to become ready
wait_for_device () {
i=1
while [ "$i" -le 30 ]
do
if [ -b "${ROOT_DEVICE}" ]; then
echo "${ROOT_DEVICE} is ready now."
break
fi
echo "${ROOT_DEVICE} is not ready. Waited for ${i} second"
sleep 1
i=$((i+1))
done
}
start_init() {
echo "Starting native initramfs init (/init2)..."
# check /init2 exist
if [ -x /init2 ]; then
echo "Executing /init2..."
# exec /init2, then enter rootfs if success
exec /init2 "$@"
init2_exit_code=$?
echo "/init2 exited with code $init2_exit_code"
else
echo "Error: /init2 not found or not executable"
init2_exit_code=127
fi
echo "Native initramfs init (/init2) failed. Staying in ramfs for debugging..."
echo "Exit code: $init2_exit_code"
echo "You can inspect the system and try to fix the issue."
echo "Available commands: ls, mount, cat, ps, etc."
echo "To try again manually, run: /init2"
echo "To enter shell, type 'sh' or 'bash' if available."
# enter debug shell
exec /bin/sh
}
format_and_install() {
if [ -f "/${ROOT_MOUNT}/${FIRMWARE}" ] ; then
echo "formating file system"
export LD_LIBRARY_PATH=/usr/lib
umount /dev/system
mkfs.ext4 -F /dev/system
mkdir -p system
if ! mount -o rw,noatime,nodiratime -t ext4 /dev/system /system ; then
fatal "Could not mount system device"
fi
echo "extracting file system ..."
gunzip -c /${ROOT_MOUNT}/${FIRMWARE} | tar -xf - -C /system
if [ $? -ne 0 ]; then
echo "Error: untar failed."
else
echo "Done"
fi
device=/dev/boot
if [ -f "/${ROOT_MOUNT}/boot.img" ]; then
echo "Writing boot.img into boot partition(${device})..."
dd if=/${ROOT_MOUNT}/boot.img of=${device}
echo "Done"
fi
sync
echo "copying existing modules to rootfs"
cp -rf /lib/modules /system/lib/
cp -rf /lib/firmware /system/lib/
cp -rf /etc/modprobe.d /system/etc/
cp -rf /etc/modules-load.d /system/etc/
cp -rf /etc/modules /system/etc/
echo "update complete"
umount $ROOT_MOUNT
ROOT_DEVICE=/dev/system
ROOT_MOUNT=/system
else
echo "cannot locate ${FIRMWARE}"
echo "boot normally..."
fi
}
# fbe_check_modules
# Search for necessary external modules for FBE.
# In case of builtin modules, nothing should be done.
# Input: N/A
# Return: N/A
fbe_check_modules() {
modules=""
# If /dev/tee0 is up, it seems the optee.ko and optee_armtz.ko
# are already builtin.
if [[ ! -e /dev/tee0 ]]; then
echo "FBE: /dev/tee0 is not up. Trying to insert optee.ko optee_armtz.ko."
modules="optee.ko optee_armtz.ko"
fi
# If there is /proc/config.gz, it might be able to find some clues in it.
if [[ -e /proc/config.gz ]]; then
cat /proc/config.gz | gunzip | grep CONFIG_TRUSTED_KEYS=y > /dev/null 2>&1
is_builtin1=$?
cat /proc/config.gz | gunzip | grep CONFIG_TRUSTED_KEYS_TEE=y > /dev/null 2>&1
is_builtin2=$?
if [[ $is_builtin1 -ne 0 ]] || [[ $is_builtin2 -ne 0 ]]; then
modules="$modules trusted.ko"
fi
else
modules="$modules trusted.ko"
fi
if [[ -n "$modules" ]]; then
echo "searching for $modules"
for mod in $modules; do
module_path=`find ${ROOT_ROMOUNT}/lib/modules/ -name $mod`
if [ "$module_path" != "" ]; then
insmod $module_path
if [ $? -ne 0 ]; then
echo "FBE: Cannot insert $mod."
fi
else
echo "FBE: Cannot find $mod."
fi
done
fi
}
#fbe_kernel_keyring_setup
# Input: $1: mount point of /dev/data
# $2: newly formatted or not
# Return: 0: success
# 1: failed
# 2: not newly formatted and no sealed key found
# (FBE is not enabled for current system)
fbe_kernel_keyring_setup() {
if [ $2 -ne 0 ]; then
echo -n "FBE: Found newly formatted data partition. Creating Data FBE Key ... "
keyring_key_id=`keyctl add trusted data_fbe_key "new 64" @u`
else
if [ -f $1/$data_fbe_keyblob ]; then
echo -n "FBE: Sealed key found. Trying to add it to kernel keyring ..."
sealed_key=`cat $1/$data_fbe_keyblob`
keyring_key_id=`keyctl add trusted data_fbe_key "load $sealed_key" @u`
else
echo "FBE: No sealed key found!"
return 2
fi
fi
#echo "keyring_key_id = $keyring_key_id"
if expr "$keyring_key_id" + 0 > /dev/null 2>&1; then
echo "[ Success ]"
return 0
else
echo "[ Failed ]"
return 1
fi
}
fbe_check_packages() {
packages="keyctl fscryptctl"
for p in $packages; do
which $p 1> /dev/null
if [ $? -ne 0 ]; then
echo "FBE: Cannot find $p. It looks like DISTRO_FEATURE, FBE, is not enabled."
echo "FBE: Skip setup."
return 1
fi
done
return 0
}
fbe_fscrypt_setup() {
data_fbe_root_dir="fbe_root"
[ ! -d $1/$data_fbe_root_dir ] && mkdir -p $1/$data_fbe_root_dir
fscrypt_key_id=`echo $keyring_key_id | fscryptctl add_key_by_keyid $1/$data_fbe_root_dir`
#echo "fscrypt_key_id= $fscrypt_key_id"
echo -n "FBE: fscryptctl set_policy ... "
fscryptctl set_policy $fscrypt_key_id $1/$data_fbe_root_dir
if [ $? -ne 0 ]; then
echo "[ Failed ]"
return 1
fi
echo "[ Success ]"
return 0
}
data_fbe_bind() {
# param 1: mount point of /dev/data
if [ "$DATA_FBE_STATUS" = "setup" ]; then
# When DATA_FBE_STATUS = setup, it means FBE has been setup on <data mount point>/fbe_root
# We need to bind it to <root mount point>/data
mkdir -p $ROOT_MOUNT/data
mount --bind $1/$data_fbe_root_dir $ROOT_MOUNT/data
if [ $? != 0 ]; then
echo "FBE: Failed to bind $1/$data_fbe_root_dir to $ROOT_MOUNT/data"
DATA_FBE_STATUS="disabled"
return 1
fi
DATA_FBE_STATUS="bound"
return 0
else
return 2
fi
}
data_fbe_add_unencrypted_folders() {
if [[ -z "$1" ]]; then
echo "Invalid foler name provided"
return
fi
# When DATA_FBE_STATUS == bound, it means FBE has been setup and bound to $ROOT_MOUNT/data
if [[ "$DATA_FBE_STATUS" = "bound" ]]; then
[[ ! -d $1 ]] && mkdir -p $1
[[ ! -d $ROOT_MOUNT/$1 ]] && mkdir -p $ROOT_MOUNT/$1
mount --bind $1 $ROOT_MOUNT/$1
if [[ $? != 0 ]]; then
echo "FBE: Failed to add $1 to $ROOT_MOUNT/$1"
DATA_FBE_STATUS="Error add $1"
fi
fi
}
data_fbe_setup() {
#echo "param: $1 $2"
fbe_check_packages
ret=$?
if [ $ret -ne 0 ]; then
return $ret
fi
fbe_kernel_keyring_setup $1 $2
ret=$?
if [ $ret -eq 1 ]; then
fbe_check_modules
fbe_kernel_keyring_setup $1 $2
elif [[ $ret -eq 2 ]]; then
return $ret
fi
if expr "$keyring_key_id" + 0 > /dev/null 2>&1; then
fbe_fscrypt_setup $1
ret=$?
if [ $ret != 0 ]; then
return $ret
fi
# Only store key blob in case of newly created key
if [ $2 -ne 0 ]; then
keyctl pipe $keyring_key_id > $1/$data_fbe_keyblob
ret=$?
sync
if [ $ret -ne 0 ]; then
echo "FBE: Store key blob failed($ret)"
return $ret
else
echo "FBE: key blob saved as $1/$data_fbe_keyblob"
fi
fi
DATA_FBE_STATUS="setup"
else
echo "FBE: Error: Invalid key id($keyring_key_id)"
fi
}
data_ext4_handle() {
# param 1: mount point of /dev/data
echo -e "Partition formater on $DATA_DEVICE"
FsType=$(blkid $DATA_DEVICE | sed -n 's/.*TYPE=\"\([^\"]*\)\".*/\1/p')
newly_formatted=0
if [ "${FsType}" != "ext4" ]; then
echo -e "Formating $DATA_DEVICE to ext4 ..."
yes 2>/dev/null | mkfs.ext4 -q -m 0 -O encrypt $DATA_DEVICE
sync
FsType=$(blkid $DATA_DEVICE | sed -n 's/.*TYPE=\"\([^\"]*\)\".*/\1/p')
echo -e "After formating FSTYPE of $DATA_DEVICE = ${FsType} ..."
newly_formatted=1
else
echo -e "FSTYPE of $DATA_DEVICE is already ext4 ..."
FactoryReset=$(uenv get factory-reset | grep value | cut -d '[' -f2|cut -d ']' -f1)
if [ ${FactoryReset} == 1 ]; then
echo -e "factory reset, Formating $DATA_DEVICE to ext4 ..."
yes 2>/dev/null | mkfs.ext4 -q -m 0 -O encrypt $DATA_DEVICE
sync
uenv set factory-reset 0
fi
fi
[ ! -d $1 ] && mkdir -p $1
if ! mount -t ext4 -o rw,noatime,nodiratime $DATA_DEVICE $1 ; then
fatal "Could not mount $DATA_DEVICE"
fi
data_fbe_setup $1 $newly_formatted
}
dm_verity_setup() {
echo "setup dm-verity for ${1} partition(${2}) mount to ${3}"
VERITY_ENV=/usr/share/${1}-dm-verity.env
if [ "${root_fstype}" = "squashfs" ]; then
vbmeta_mtd_number=$(cat /proc/mtd | grep -E "vbmeta" | awk -F : '{print $1}' | grep -o '[0-9]\+')
VBMETA_DEVICE_REAL=/dev/mtdblock${vbmeta_mtd_number}
else
VBMETA_DEVICE_REAL=${VBMETA_DEVICE}${ACTIVE_SLOT}
# Change /dev/block/ to /dev/
if [ ! -b ${VBMETA_DEVICE_REAL} ]; then
VBMETA_DEVICE_REAL=`echo ${VBMETA_DEVICE_REAL} | sed "s/\/block\//\//g"`
fi
fi
echo "vbmeta device is $VBMETA_DEVICE_REAL"
if [ -b "${VBMETA_DEVICE_REAL}" ]; then
mkdir -p /tmp
AVB_DM_TOOL_PY=/usr/bin/avbtool-dm-verity.py
AVB_DM_TOOL_C=/usr/bin/aml-avb-dm-verity
if [ -x "${AVB_DM_TOOL_PY}" ]; then
AVB_DM_TOOL=${AVB_DM_TOOL_PY}
fi
if [ -x "${AVB_DM_TOOL_C}" ]; then
AVB_DM_TOOL=${AVB_DM_TOOL_C}
fi
if [ -x "${AVB_DM_TOOL}" ]; then
VERITY_ENV=/tmp/${1}-dm-verity.env
${AVB_DM_TOOL} print_partition_verity --image "${VBMETA_DEVICE_REAL}" --partition_name "${1}" --active_slot "${ACTIVE_SLOT}" --output "$VERITY_ENV"
if [ "$?" != "0" ]; then
echo "failed to read vbmeta device from ${VBMETA_DEVICE_REAL}"
fi
fi
fi
echo "verity env is $VERITY_ENV"
if [ -f $VERITY_ENV ]; then
. $VERITY_ENV
veritysetup --data-block-size=${DATA_BLOCK_SIZE} --hash-offset=${DATA_SIZE} \
create ${1} ${2} ${2} ${ROOT_HASH}
if [ $? = 0 ]; then
if [ "${3}" != "none" ]; then
#mount -o ro /dev/mapper/${1} ${3}
mount -o ro /dev/dm-${DM_DEV_COUNT} ${3}
else
echo "skip mounting ${2}"
fi
if [ "$1" = "system" ]; then
DM_VERITY_STATUS_SYSTEM="enabled"
elif [ "$1" = "vendor" ]; then
DM_VERITY_STATUS_VENDOR="enabled"
fi
DM_DEV_COUNT=$((DM_DEV_COUNT+1))
else
echo "dm-verity fails with return code $?"
if [ "$1" = "system" ]; then
DM_VERITY_STATUS_SYSTEM="disabled"
elif [ "$1" = "vendor" ]; then
DM_VERITY_STATUS_VENDOR="disabled"
fi
fi
else
echo "Cannot find root hash in initramfs"
if [ "$1" = "system" ]; then
DM_VERITY_STATUS_SYSTEM="disabled"
elif [ "$1" = "vendor" ]; then
DM_VERITY_STATUS_VENDOR="disabled"
fi
fi
}
enable_irdeto_write_protection() {
echo "Enable write protection for bl2,tpl,logo,recovery,hwconfig"
# enable write protection for bl2
echo 0 > /sys/class/mtd/mtd0/writeable
# enable write protection for tpl
echo 0 > /sys/class/mtd/mtd1/writeable
# enable write protection for logo
echo 0 > /sys/class/mtd/mtd2/writeable
# enable write protection for recovery
echo 0 > /sys/class/mtd/mtd3/writeable
# enable write protection for hwconfig
echo 0 > /sys/class/mtd/mtd14/writeable
}
# Try to mount the root image read-write and then boot it up.
# This function distinguishes between a read-only image and a read-write image.
# In the former case (typically an iso), it tries to make a union mount if possible.
# In the latter case, the root image could be mounted and then directly booted up.
mount_and_boot() {
mkdir $ROOT_MOUNT
mknod /dev/loop0 b 7 0 2>/dev/null
if [ "${root_fstype}" = "ubifs" ]; then
ubi_rootfs_mount
ubi_vendor_attach
elif [ "${root_fstype}" = "squashfs" ]; then
squashfs_rootfs_mount
else
if [ "${FIRMWARE}" != "" ]; then
ROOT_DEVICE="/dev/mmcblk1p1"
fi
wait_for_device
if [ "$ROOT_DEVICE" != "" ]; then
dm_verity_setup system ${ROOT_DEVICE} ${ROOT_MOUNT}
dm_verity_setup vendor ${VENDOR_DEVICE}${ACTIVE_SLOT} none
echo "dm-verity for system is $DM_VERITY_STATUS_SYSTEM"
if [ "$DM_VERITY_STATUS_SYSTEM" = "disabled" ]; then
if ! mount -o ro,noatime,nodiratime $ROOT_DEVICE $ROOT_MOUNT ; then
SYSTEM_DEV="/dev/mmcblk0p4"
if [ -e $SYSTEM_DEV ];then
echo "Found $SYSTEM_DEV, try switch to start it"
# fsck.ext4 -f -y $SYSTEM_DEV
mount $SYSTEM_DEV /rootfs
cd /rootfs
mount --move /dev dev
mount --move /proc proc
mount --move /sys sys
echo "Switch rootfs ....... "
exec switch_root . /sbin/init
fi
fatal "Could not mount rootfs device"
fi
fi
fi
if [ "${FIRMWARE}" != "" ]; then
format_and_install
fi
fi
if touch $ROOT_MOUNT/bin 2>/dev/null; then
echo "Root mount is RW"
# The root image is read-write, directly boot it up.
if [ "${root_fstype}" = "ext4" ]; then
data_ext4_handle $DATA_MOUNT
data_fbe_bind $DATA_MOUNT
if [[ $? -eq 0 ]]; then
if [[ -d $OVERLAY_DIR ]]; then
data_fbe_add_unencrypted_folders $OVERLAY_DIR
fi
data_fbe_add_unencrypted_folders $UNENCRYPTED_DIR
data_fbe_add_unencrypted_folders $SWUPDATE_DIR
[[ "$DATA_FBE_STATUS" = "bound" ]] && DATA_FBE_STATUS="enabled"
fi
if [[ "$DATA_FBE_STATUS" = "disabled" ]]; then
mkdir -p $ROOT_MOUNT/data
mount --move $DATA_MOUNT $ROOT_MOUNT/data
fi
echo "DATA FBE is: $DATA_FBE_STATUS!"
else
data_yaffs2_handle $ROOT_MOUNT/data
fi
boot_root
fi
# determine which unification filesystem to use
union_fs_type=""
if grep -q -w "overlay" /proc/filesystems; then
union_fs_type="overlay"
elif grep -q -w "aufs" /proc/filesystems; then
union_fs_type="aufs"
fi
# make a union mount if possible
case $union_fs_type in
"overlay")
mkdir -p $ROOT_ROMOUNT
if ! mount -n --move $ROOT_MOUNT $ROOT_ROMOUNT; then
rm -rf $ROOT_ROMOUNT
fatal "Could not move rootfs mount point"
else
echo "mount overlay"
if [ "${root_fstype}" = "ubifs" ]; then
if [ "$VENDOR_DEVICE" = "enabled" ]; then
data_ubi_handle 2 /data
else
data_ubi_handle 1 /data
fi
elif [ "${root_fstype}" = "squashfs" ]; then
data_ubi_handle 0 /data
else
data_ext4_handle $DATA_MOUNT
fi
mkdir -p $OVERLAY_DIR/upperdir $OVERLAY_DIR/work
mount -t overlay overlay -o "lowerdir=$ROOT_ROMOUNT,upperdir=$OVERLAY_DIR/upperdir,workdir=$OVERLAY_DIR/work" $ROOT_MOUNT
mkdir -p ${ROOT_MOUNT}/$ROOT_ROMOUNT
mount --move $ROOT_ROMOUNT ${ROOT_MOUNT}/$ROOT_ROMOUNT
data_fbe_bind $DATA_MOUNT
if [[ $? -eq 0 ]]; then
if [[ -d $OVERLAY_DIR ]]; then
data_fbe_add_unencrypted_folders $OVERLAY_DIR
fi
data_fbe_add_unencrypted_folders $UNENCRYPTED_DIR
data_fbe_add_unencrypted_folders $SWUPDATE_DIR
[[ "$DATA_FBE_STATUS" = "bound" ]] && DATA_FBE_STATUS="enabled"
fi
if [[ "$DATA_FBE_STATUS" = "disabled" ]]; then
mkdir -p $ROOT_MOUNT/data
mount --move $DATA_MOUNT $ROOT_MOUNT/data
fi
echo "DATA FBE is: $DATA_FBE_STATUS!"
fi
;;
"aufs")
mkdir -p /rootfs.ro /rootfs.rw
if ! mount -n --move $ROOT_MOUNT /rootfs.ro; then
rm -rf /rootfs.ro /rootfs.rw
fatal "Could not move rootfs mount point"
else
mount -t tmpfs -o rw,noatime,mode=755 tmpfs /rootfs.rw
mount -t aufs -o "dirs=/rootfs.rw=rw:/rootfs.ro=ro" aufs $ROOT_MOUNT
mkdir -p $ROOT_MOUNT/rootfs.ro $ROOT_MOUNT/rootfs.rw
mount --move /rootfs.ro $ROOT_MOUNT/rootfs.ro
mount --move /rootfs.rw $ROOT_MOUNT/rootfs.rw
fi
;;
"")
echo "OverlayFS is disabled"
OverlayFS="disabled"
if [ "${root_fstype}" = "ext4" ]; then
data_ext4_handle $DATA_MOUNT
data_fbe_bind $DATA_MOUNT
if [[ $? -eq 0 ]]; then
if [[ -d $OVERLAY_DIR ]]; then
data_fbe_add_unencrypted_folders $OVERLAY_DIR
fi
data_fbe_add_unencrypted_folders $UNENCRYPTED_DIR
data_fbe_add_unencrypted_folders $SWUPDATE_DIR
[[ "$DATA_FBE_STATUS" = "bound" ]] && DATA_FBE_STATUS="enabled"
fi
if [[ "$DATA_FBE_STATUS" = "disabled" ]]; then
mkdir -p $ROOT_MOUNT/data
mount --move $DATA_MOUNT $ROOT_MOUNT/data
fi
echo "DATA FBE is: $DATA_FBE_STATUS!"
elif [ "${root_fstype}" = "ubifs" ]; then
if [ "$VENDOR_DEVICE" = "enabled" ]; then
data_ubi_handle 2 /data
else
data_ubi_handle 1 /data
fi
elif [ "${root_fstype}" = "squashfs" ]; then
data_yaffs2_handle $ROOT_MOUNT/data
# data_ubi_handle 0 $ROOT_MOUNT/data
fi
;;
esac
# Use the existence of the 'casecure' directory to determine if it is the Irdeto bootloader version
#enable_irdeto_write_protection
# boot the image
boot_root
}
squashfs_rootfs_mount()
{
vendor_mtd_number=$(cat /proc/mtd | grep -E "vendor" | awk -F : '{print $1}' | grep -o '[0-9]\+')
VENDOR_DEVICE=/dev/mtdblock${vendor_mtd_number}
system_mtd_number=$(cat /proc/mtd | grep -E "system" | awk -F : '{print $1}' | grep -o '[0-9]\+')
ROOT_DEVICE=/dev/mtdblock${system_mtd_number}
if [ -n "$system_mtd_number" ]; then
ln -sf "${ROOT_DEVICE}" "/dev/system"${ACTIVE_SLOT}
dm_verity_setup system ${ROOT_DEVICE} ${ROOT_MOUNT}
fi
if [ -n "$vendor_mtd_number" ]; then
ln -sf "${VENDOR_DEVICE}" "/dev/vendor"${ACTIVE_SLOT}
dm_verity_setup vendor ${VENDOR_DEVICE} none
fi
echo "dm-verity for system is $DM_VERITY_STATUS_SYSTEM"
if [ "$DM_VERITY_STATUS_SYSTEM" = "disabled" ]; then
if ! mount -t squashfs -o ro,noatime,nodiratime $ROOT_DEVICE $ROOT_MOUNT ; then
fatal "Could not mount $ROOT_DEVICE"
fi
fi
}
ubi_rootfs_mount()
{
system_mtd_number=$(cat /proc/mtd | grep -E "system" | awk -F : '{print $1}' | grep -o '[0-9]\+')
ubiattach /dev/ubi_ctrl -m ${system_mtd_number}
if [ -c "/dev/ubi0_0" ]; then
if ! mount -t ubifs -o ro /dev/ubi0_0 $ROOT_MOUNT ; then
fatal "Could not mount /dev/ubi0_0"
fi
fi
}
ubi_vendor_attach()
{
vendor_mtd_number=$(cat /proc/mtd | grep -E "vendor" | awk -F : '{print $1}' | grep -o '[0-9]\+')
if [ -n "$vendor_mtd_number" ]; then
ubiattach /dev/ubi_ctrl -m ${vendor_mtd_number}
VENDOR_DEVICE="enabled"
fi
}
data_ubi_handle()
{
data_mtd_number=$(cat /proc/mtd | grep -E -w "data" | awk -F : '{print $1}' | grep -o '[0-9]\+')
mkdir -p $2
if ! uenv get factory-reset | grep -q 'value:\[1\]'; then
mount | grep 'data' && echo "Already mounted" && return 0
# sure ubi vol exist or not
ubiattach /dev/ubi_ctrl -m ${data_mtd_number}
if [ -c "/dev/ubi${1}_0" ]; then
data_vol_name=`cat /sys/class/ubi/ubi${1}_0/name`
if [ "${data_vol_name}" = "data" ]; then
mount -t ubifs /dev/ubi${1}_0 $2
return 0
fi
fi
ubidetach /dev/ubi_ctrl -d ${1}
else
uenv set factory-reset 0
fi
#format data
flash_eraseall /dev/mtd${data_mtd_number}
ubiattach /dev/ubi_ctrl -m ${data_mtd_number}
ubimkvol /dev/ubi${1} -m -N data
mount -t ubifs /dev/ubi${1}_0 $2
}
data_yaffs2_handle()
{
data_mtd_number=$(cat /proc/mtd | grep -E -w "data" | awk -F : '{print $1}' | grep -o '[0-9]\+')
mkdir -p $1
if ! uenv get factory-reset | grep -q 'value:\[1\]'; then
mount | grep 'data' && echo "Already mounted" && return 0
else
flash_eraseall /dev/mtd${data_mtd_number}
uenv set factory-reset 0
fi
#mount data
mount -t yaffs2 /dev/mtdblock${data_mtd_number} $1
}
# mount_and_boot
start_init