#!/bin/bash
echo "####################################################"
echo "############ ESUN ADRV9002 burn script #############"
echo "############ VERSION v1.0              #############"
echo "############ 2024-10-09                #############"
echo "############ Author: ZML               #############"
echo "####################################################"

# set -x                                                            # 开启命令回显用于调试

export LC_ALL=C LANGUAGE=C LANG=C # 强制将本地语言设置为英文。这可以避免在进行文本和字符串处理时出现问题。

[ "$(id -u)" -ne 0 ] && SUDO="sudo" || SUDO="" # 检查当前用户是否为 root，如果是则设置 SUDO 为空，否则设置为 sudo

export ZN_SCRIPT_DIR="$(cd $(dirname ${BASH_SOURCE}) && pwd)" # 获取脚本所在的目录

if [ -f "${ZN_SCRIPT_DIR}/common.sh" ]; then # 导入 common.sh 中的本地函数
  source common.sh
else
  printf "\033[31m[ERROR]\033[0m Could not find file '${ZN_SCRIPT_DIR}/common.sh'\n"
  return 1
fi

ZN_SCRIPT_NAME="$(basename ${BASH_SOURCE})" # 获取当前脚本的文件名

QSPI_DEVICE=${QSPI:="/dev/mtdblock0"} # 设置默认值，QSPI Flash位置
EMMC_DEVICE=${EMMC:="/dev/mmcblk1"}
#####################################################################
echo_info "[ $(date "+%Y/%m/%d %H:%M:%S") ] Starting ${ZN_SCRIPT_NAME}"

[ -e ${QSPI_DEVICE} ] && echo_info "检查 QSPI 设备： \"${QSPI_DEVICE}\" 存在!"
[ ! -e ${QSPI_DEVICE} ] && error_exit "检查 QSPI 设备： \"${QSPI_DEVICE}\" 不存在!"

[ -e ${EMMC_DEVICE} ] && echo_info "检查 eMMC 设备： \"${EMMC_DEVICE}\" 存在!"
[ ! -e ${EMMC_DEVICE} ] && error_exit "检查 eMMC 设备： \"${EMMC_DEVICE}\" 不存在!"

echo_info "卸载所有已挂载的分区"
for part in $(lsblk ${EMMC_DEVICE} -o mountpoint --noheadings); do
  echo "${SUDO} umount ${part} && sleep 1"
  ${SUDO} umount ${part} && sleep 1
done

echo_info "删除 eMMC 设备上的所有现有分区"
for PARTITION in $(${SUDO} parted ${EMMC_DEVICE} print | awk '/^ /{print $1}'); do
  echo "${SUDO} parted -s ${EMMC_DEVICE} rm ${PARTITION}"
  ${SUDO} parted -s ${EMMC_DEVICE} rm ${PARTITION}
done

read input

echo_info "选择 MBR 分区标准"
echo "${SUDO} parted -s ${EMMC_DEVICE} mklabel msdos"
${SUDO} parted -s ${EMMC_DEVICE} mklabel msdos

echo_info "创建 500MB 的 fat32 分区并设置为启动分区"
echo "${SUDO} parted -s ${EMMC_DEVICE} mkpart primary fat32 0% 500MiB && ${SUDO} parted -s ${EMMC_DEVICE} set 1 boot on"
${SUDO} parted -s ${EMMC_DEVICE} mkpart primary fat32 0% 500MiB && ${SUDO} parted -s ${EMMC_DEVICE} set 1 boot on

echo_info "创建 ext4 分区直到设备末尾"
echo "${SUDO} parted -s ${EMMC_DEVICE} mkpart primary ext4 500MiB 100%"
${SUDO} parted -s ${EMMC_DEVICE} mkpart primary ext4 500MiB 100%

echo_info "重新读取分区表而不重启 Linux 系统"
echo "${SUDO} partprobe ${EMMC_DEVICE} && sleep 1 && lsblk ${EMMC_DEVICE}"
${SUDO} partprobe ${EMMC_DEVICE} && sleep 1 && lsblk ${EMMC_DEVICE}

# 在新分区上创建文件系统
for PARTITION in $(lsblk -l ${EMMC_DEVICE} | grep part | awk '{print $1}'); do
  PARTNUM=${PARTITION##*[[:alpha:]]}
  case ${PARTNUM} in
  1)
    echo_info "在 /dev/${PARTITION} 上格式化 FAT32 文件系统，并设置磁盘标签为 'BOOT'"
    echo "${SUDO}  mkfs.vfat -F 32 -n "BOOT" /dev/${PARTITION}"
    ${SUDO} mkfs.vfat -F 32 -n "BOOT" /dev/${PARTITION}
    ;;
  2)
    echo_info "在 /dev/${PARTITION} 上格式化 ext4 文件系统，并设置磁盘标签为 'rootfs'"
    echo "echo y | ${SUDO} mkfs.ext4 -L rootfs /dev/${PARTITION}"
    echo y | ${SUDO} mkfs.ext4 -L rootfs /dev/${PARTITION}
    ;;
  *)
    echo_warn "意外的额外分区"
    ;;
  esac
done

echo_info "[ $(date "+%Y/%m/%d %H:%M:%S") ] 完成emmc分区。"
###############################################################################
echo_info "部署启动镜像到 QSPI 闪存:"
echo "${SUDO} dd if=${ZN_SCRIPT_DIR}/../BOOT.bin of=${QSPI_DEVICE}"
${SUDO} dd if=${ZN_SCRIPT_DIR}/../BOOT.bin of=${QSPI_DEVICE}
if [ $? -eq 0 ]; then
  echo_info "部署启动镜像到 QSPI Flash 成功！！！"
else
  error_exit "部署启动镜像到 QSPI Flash 失败！！！"
fi
###############################################################################
echo_info "部署系统镜像到 eMMC:"
BOOT_MOUNT_POINT=/mnt/emmc/boot   # 启动分区挂载点
ROOT_MOUNT_POINT=/mnt/emmc/rootfs # 根文件系统挂载点
echo "${SUDO} mkdir -p ${BOOT_MOUNT_POINT} ${ROOT_MOUNT_POINT}"
${SUDO} mkdir -p ${BOOT_MOUNT_POINT} ${ROOT_MOUNT_POINT}

# 遍历 eMMC 设备上的所有分区
for PARTITION in $(lsblk -l ${EMMC_DEVICE} | grep part | awk '{print $1}'); do
  PARTNUM=${PARTITION##*[[:alpha:]]}
  case ${PARTNUM} in
  1)
    # 检查启动分区是否为 FAT32 文件系统
    [[ $(lsblk -no FSTYPE /dev/${PARTITION}) != 'vfat' ]] && error_exit "未找到可启动的设备"

    echo_info "挂载启动分区到 ${BOOT_MOUNT_POINT}"
    echo "${SUDO} mount -t vfat /dev/${PARTITION} ${BOOT_MOUNT_POINT}"
    ${SUDO} mount -t vfat /dev/${PARTITION} ${BOOT_MOUNT_POINT}

    echo_info "安装启动镜像到 ${BOOT_MOUNT_POINT}"
    # echo "${SUDO} rsync -rv ${ZN_SCRIPT_DIR}/boot/ ${BOOT_MOUNT_POINT} && sync"
    # ${SUDO} rsync -rv ${ZN_SCRIPT_DIR}/boot/ ${BOOT_MOUNT_POINT} && sync
    # 使用 cp 命令替代 rsync
    echo "${SUDO} cp -r ${ZN_SCRIPT_DIR}/../* ${BOOT_MOUNT_POINT} && sync"
    ${SUDO} cp -r ${ZN_SCRIPT_DIR}/../* ${BOOT_MOUNT_POINT} && sync

    echo_info "卸载启动分区从 ${BOOT_MOUNT_POINT}"
    echo "${SUDO} umount ${BOOT_MOUNT_POINT}"
    ${SUDO} umount ${BOOT_MOUNT_POINT}
    ;;
  2)
    # 检查根文件系统分区是否为 ext4 文件系统
    [[ $(lsblk -no FSTYPE /dev/${PARTITION}) != 'ext4' ]] && error_exit "未找到根文件系统分区"

    echo_info "挂载根文件系统分区到 ${ROOT_MOUNT_POINT}"
    echo "${SUDO} mount -t ext4 /dev/${PARTITION} ${ROOT_MOUNT_POINT}"
    ${SUDO} mount -t ext4 /dev/${PARTITION} ${ROOT_MOUNT_POINT}

    # 检查根文件系统分区是否为空
    if [ "$(ls -A ${ROOT_MOUNT_POINT})" != "lost+found" ]; then
      ${SUDO} umount ${ROOT_MOUNT_POINT}
      error_exit "根文件系统分区不为空，请清理！"
    fi

    echo_info "安装根文件系统镜像到 ${ROOT_MOUNT_POINT}"
    echo "${SUDO} tar zxf ${ZN_SCRIPT_DIR}/../rootfs.tar.gz -C ${ROOT_MOUNT_POINT} && sync"
    ${SUDO} tar zxf ${ZN_SCRIPT_DIR}/../rootfs.tar.gz -C ${ROOT_MOUNT_POINT} && sync

    echo_info "卸载根文件系统分区从 ${ROOT_MOUNT_POINT}"
    echo "${SUDO} umount ${ROOT_MOUNT_POINT}"
    ${SUDO} umount ${ROOT_MOUNT_POINT}
    ;;
  *)
    echo_warn "意外的额外分区"
    ;;
  esac
done

print_info "[ $(date "+%Y/%m/%d %H:%M:%S") ] 烧录完成，请关闭设备，将拨码开关切换至eMMC启动，然后重新上电。\n"
###############################################################################
