NXP i.MX EVK board build tools
guowenxue
2023-09-26 75a960df1eb8abad7c1c693d8cad75db63478d6b
Add build-evkboard shell script tools

Signed-off-by: guowenxue <guowenxue@gmail.com>
9 files added
1621 ■■■■■ changed files
android/build.sh 251 ●●●●● patch | view | raw | blame | history
bootloader/build.sh 376 ●●●●● patch | view | raw | blame | history
config.json 17 ●●●●● patch | view | raw | blame | history
debian/build.sh 167 ●●●●● patch | view | raw | blame | history
images/build.sh 279 ●●●●● patch | view | raw | blame | history
kernel/build.sh 142 ●●●●● patch | view | raw | blame | history
tools/imgmnt 120 ●●●●● patch | view | raw | blame | history
tools/setup_tools.sh 120 ●●●●● patch | view | raw | blame | history
yocto/build.sh 149 ●●●●● patch | view | raw | blame | history
android/build.sh
New file
@@ -0,0 +1,251 @@
#!/bin/bash
PRJ_PATH=`pwd`
BOARD=evk_8mp
ANDROID_VER=imx-android-12.0.0_1.0.0
IMAGE_PATH=${PRJ_PATH}/android_image
IMAGE_NAME=${ANDROID_VER}-${BOARD}.img
IMAGE_SIZE=14336M  #14G
JOBS=`cat /proc/cpuinfo | grep processor | wc -l`
LOOP_DEV=`losetup  -f | cut -d/ -f3`
set -e
# display in green
function pr_info() {
    echo -e "\033[40;32m --I-- $1 \033[0m"
}
function exit_handler()
{
    pr_info "Shell script exit now, do some clean work"
    set +e
    if [ -L /dev/mapper/${LOOP_DEV}p1 ] ; then
        echo "kpartx -dv /dev/${LOOP_DEV}"
        kpartx -dv /dev/${LOOP_DEV} > /dev/null
    fi
    losetup -a | grep "${LOOP_DEV}" > /dev/null 2>&1
    if [ $? == 0 ]  ; then
        echo "losetup -d /dev/${LOOP_DEV}"
        losetup -d /dev/${LOOP_DEV} > /dev/null
    fi
}
function do_systool()
{
    if command -v simg2img > /dev/null 2>&1 ; then
        pr_info "system tools installed already."
        return ;
    fi
    pr_info "Start install system tools."
    # ubuntu22.04 miss android-sdk-ext4-utils
    sudo apt install -y uuid uuid-dev zlib1g-dev liblz-dev liblzo2-2 liblzo2-dev make libssl-dev \
        lzop git curl u-boot-tools mtd-utils device-tree-compiler gdisk m4 bison flex gcc-multilib \
        android-sdk-libsparse-utils android-sdk android-sdk-build-tools libncurses5
    sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 1
}
function do_fetch()
{
    if [ -f ${PRJ_PATH}/${ANDROID_VER}/imx_android_setup.sh ] ; then
        pr_info "android source code fetch already."
        return;
    fi
    pr_info "Start fetch source code."
    mkdir -p ${PRJ_PATH}/bin
    curl https://storage.googleapis.com/git-repo-downloads/repo > ${PRJ_PATH}/bin/repo
    chmod a+x ${PRJ_PATH}/bin/repo
    export PATH=${PATH}:${PRJ_PATH}/bin
    if [ ! -d $ANDROID_VER ] ; then
        tar -xzf $ANDROID_VER.tar.gz
    fi
    source ${PRJ_PATH}/${ANDROID_VER}/imx_android_setup.sh
    # By default, after preceding command finishes execution, current working directory changed to the
    # i.MX Android source code root directory.
    # ${MY_ANDROID} will be refered as the i.MX Android source code root directory in all i.MX Andorid
    # release documentation
    export MY_ANDROID=${PRJ_PATH}
}
function do_build()
{
    IMX_TARGET="bootloader kernel mxmwifi dtboimage bootimage vendorbootimage vendorimage"
    pr_info "Start build android source code."
    export AARCH64_GCC_CROSS_COMPILE=aarch64-linux-gnu-
    export MY_ANDROID=${PRJ_PATH}/android_build
    cd $MY_ANDROID
    source build/envsetup.sh
    #lunch ${BOARD}-eng
    lunch ${BOARD}-userdebug
    # Build U-Boot/kernel with imx-make.sh first, but not to build Android images.
    ./imx-make.sh -j${JOBS} ${IMX_TARGET} 2>&1 | tee build-log.txt
    # Start the process of build Android images with "make" function.
    make -j${JOBS} 2>&1 | tee -a build-log.txt
    # output in ${MY_ANDROID}/out/target/product/${BOARD}
    ls out/target/product/${BOARD}/*.img
}
function do_install()
{
    export MY_ANDROID=${PRJ_PATH}/android_build
    IMAGE_FILES="boot.img  dtbo-imx8mp.img  partition-table.img  super.img  \
        u-boot-imx8mp.imx  vbmeta-imx8mp.img  vendor_boot.img \
        fastboot_imx_flashall.* imx-sdcard-partition.* uuu_imx_android_flash.* "
    pr_info "Start install output images"
    mkdir -p $IMAGE_PATH && rm -f $IMAGE_PATH/*
    cd ${MY_ANDROID}/out/target/product/${BOARD}/
    for f in $IMAGE_FILES
    do
        cp $f ${IMAGE_PATH}
    done
    cd $PRJ_PATH
}
function do_image()
{
    cd $IMAGE_PATH
    # Generate android system image file and losetup for it
    pr_info "Start generate android system images: ${IMAGE_NAME}"
    cp partition-table.img ${IMAGE_NAME}
    chmod +x ${IMAGE_NAME}
    truncate -s ${IMAGE_SIZE} ${IMAGE_NAME}
    sgdisk -e ${IMAGE_NAME}
    gdisk -l ${IMAGE_NAME}
    losetup /dev/${LOOP_DEV}  ${IMAGE_NAME}
    kpartx -av /dev/${LOOP_DEV} > /dev/null
    # Android system image partition table and written images
    part1=(dtbo_a:dtbo-imx8mp.img)
    part2=(dtbo_b:dtbo-imx8mp.img)
    part3=(boot_a:boot.img)
    part4=(boot_b:boot.img)
    part5=(vendor_boot_a:vendor_boot.img)
    part6=(vendor_boot_b:vendor_boot.img)
    part7=(misc:zero)
    part8=(metadata:ext4)
    part9=(presistdata:zero)
    part10=(super:super.img)
    part11=(userdata:ext4)
    part12=(fbmisc:zero)
    part13=(vbmeta_a:vbmeta-imx8mp.img)
    part14=(vbmeta_b:vbmeta-imx8mp.img)
    pr_info "Start write built output images to android system images"
    for i in `seq 1 14`
    do
        eval var=\${part${i}[@]}
        for info in ${var}
        do
            partnum=$i
            partname=`echo ${info} | cut -d: -f1`
            imgfile=`echo ${info} | cut -d: -f2`
            echo "Flash partition${partnum}($partname): $imgfile "
            if [ "$imgfile" = "zero" ] ; then
                size=`gdisk -l ${IMAGE_NAME} | grep -w ${partname} | awk '{print $4}' | cut -d. -f1`
                unit=`gdisk -l ${IMAGE_NAME} | grep -w ${partname} | awk '{print $5}'`
                dd if=/dev/zero of=/dev/mapper/${LOOP_DEV}p${partnum} bs=1${unit} count=${size} conv=fsync,nocreat status=none
            elif [ "$imgfile" = "ext4" ] ; then
                mkfs.ext4 -F /dev/mapper/${LOOP_DEV}p${partnum} -L${partname} > /dev/null 2>&1
            elif [ "$imgfile" = "super.img" ] ; then
                simg2img $imgfile /dev/mapper/${LOOP_DEV}p${partnum}
            else
                dd if=$imgfile of=/dev/mapper/${LOOP_DEV}p${partnum} bs=10M conv=fsync,nocreat status=none
            fi
        done
    done
    pr_info "Start write u-boot image to android system images"
    dd if=u-boot-imx8mp.imx of=/dev/${LOOP_DEV} bs=1k seek=32 conv=fsync status=none
    sync
    pr_info "generate ${IMAGE_NAME} successful!"
}
function do_usage()
{
    echo ""
    echo "Usage:"
    echo " $0 [-b] [-g] [-h]"
    echo "     -b : build android source code SDK"
    echo "     -g : generate android system image"
    echo "     -h : show this help message"
    echo ""
    echo " WARNNING: Generate android image need run as sudo"
    echo ""
    echo " Build Example: $0 -b && sudo $0 -g"
    echo ""
    exit;
}
action="usage"
while getopts "bgh" OPTNAME
do
    case "${OPTNAME}" in
        "b")
            action="build"
            shift
            ;;
        "g")
            action="generate"
            shift
            ;;
        "h")
            action="usage"
            ;;
    esac
done
trap 'exit_handler' EXIT
#do_systool
if [ $action == "usage" ] ; then
    do_usage
elif [ $action == "build" ] ; then
    do_fetch
    do_build
    do_install
elif [ $action == "generate" ] ; then
    do_image
fi
bootloader/build.sh
New file
@@ -0,0 +1,376 @@
#!/bin/bash
# this project absolute path
PRJ_PATH=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
# top project absolute path
TOP_PATH=$(realpath $PRJ_PATH/..)
# binaries build prefix install path
PRFX_PATH=$PRJ_PATH/install
# binaries finally install path if needed
INST_PATH=/tftp
# config file path
CONF_FILE=$TOP_PATH/config.json
# shell script will exit once get command error
set -e
#+-------------------------+
#| Shell script functions  |
#+-------------------------+
function pr_error() {
    echo -e "\033[40;31m $1 \033[0m"
}
function pr_warn() {
    echo -e "\033[40;33m $1 \033[0m"
}
function pr_info() {
    echo -e "\033[40;32m $1 \033[0m"
}
# select firmware version by BSP version
function export_fmver()
{
    if [[ $BSP_VER =~ 6.1.22 ]] ;  then
        export FMW_IMX=firmware-imx-8.20
        export FMW_SENTINEL=firmware-sentinel-0.10
        export FMW_UPOWER=firmware-upower-1.3.0
    elif [[ $BSP_VER =~ 6.1.1 ]] ;  then
        export FMW_IMX=firmware-imx-8.19
        export FMW_SENTINEL=firmware-sentinel-0.9
        export FMW_UPOWER=firmware-upower-1.2.0
    elif [[ $BSP_VER =~ 5.15.71 ]] ;  then
        export FMW_IMX=firmware-imx-8.18
        export FMW_SENTINEL=firmware-sentinel-0.8
        export FMW_UPOWER=firmware-upower-1.1.0
    fi
    export FMWS="$FMW_IMX $FMW_SENTINEL $FMW_UPOWER"
    export FMW_URL=https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/
    export FMW_PATH=$PRJ_PATH/firmware/
}
# parser configure file and export environment variable
function export_env()
{
    export BOARD=`jq -r ".bsp.board" $CONF_FILE | tr 'A-Z' 'a-z'`
    export BSP_VER=`jq -r ".bsp.version" $CONF_FILE | tr 'A-Z' 'a-z'`
    export GIT_URL=`jq -r ".bsp.giturl" $CONF_FILE | tr 'A-Z' 'a-z'`
    export CROSS_COMPILE=`jq -r ".bsp.cortexAtool" $CONF_FILE | tr 'A-Z' 'a-z'`
    export MCORE_COMPILE=`jq -r ".bsp.cortexMtool" $CONF_FILE | tr 'A-Z' 'a-z'`
    export SRCS="imx-atf uboot-imx imx-mkimage"
    export BRANCH=$BSP_VER
    export JOBS=`cat /proc/cpuinfo | grep processor | wc -l`
    export ARCH=arm
    export_fmver
    export SRCS="imx-atf uboot-imx imx-mkimage"
    if [[ $BOARD =~ mx93 ]] ; then
        ATF_PLATFORM=imx93
        IMX_BOOT_SOC_TARGET=iMX9
        IMXBOOT_TARGETS=flash_singleboot
        IMXBOOT_DTB=imx93-11x11-evk.dtb
        MKIMG_BIN_PATH=$PRJ_PATH/imx-mkimage/iMX9/
    elif [[ $BOARD =~ mx8ulp ]] ; then
        MCORE_BUILD=yes
        MCORE_BOARD=evkmimx8ulp
        MCORE_IMAGE=m33_image.bin
        ATF_PLATFORM=imx8ulp
        IMX_BOOT_SOC_TARGET=iMX8ULP
        IMXBOOT_TARGETS=flash_singleboot_m33
        IMXBOOT_DTB=imx8ulp-evk.dtb
        MKIMG_BIN_PATH=$PRJ_PATH/imx-mkimage/iMX8ULP/
    elif [[ $BOARD =~ mx8mq ]] ; then
        ATF_PLATFORM=imx8mq
        IMX_BOOT_SOC_TARGET=iMX8M
        IMXBOOT_TARGETS=flash_ddr4_val
        IMXBOOT_DTB=imx8mq-ddr4-val.dtb
        MKIMG_BIN_PATH=$PRJ_PATH/imx-mkimage/iMX8M/
    elif [[ $BOARD =~ mx8mp ]] ; then
        ATF_PLATFORM=imx8mp
        IMX_BOOT_SOC_TARGET=iMX8MP
        IMXBOOT_TARGETS=flash_ddr4_evk
        IMXBOOT_DTB=imx8mp-ddr4-evk.dtb
        MKIMG_BIN_PATH=$PRJ_PATH/imx-mkimage/iMX8M/
    elif [[ $BOARD =~ mx8mm ]] ; then
        ATF_PLATFORM=imx8mm
        IMX_BOOT_SOC_TARGET=iMX8MM
        IMXBOOT_TARGETS=flash_ddr4_evk
        IMXBOOT_DTB=imx8mm-ddr4-evk.dtb
        MKIMG_BIN_PATH=$PRJ_PATH/imx-mkimage/iMX8M/
    elif [[ $BOARD =~ mx8mn ]] ; then
        ATF_PLATFORM=imx8mn
        IMX_BOOT_SOC_TARGET=iMX8MN
        IMXBOOT_TARGETS=flash_ddr4_evk
        IMXBOOT_DTB=imx8mn-ddr4-evk.dtb
        MKIMG_BIN_PATH=$PRJ_PATH/imx-mkimage/iMX8M/
    fi
}
function do_fetch()
{
    cd $PRJ_PATH
    for src in $SRCS
    do
        if [ -d $src ] ; then
            pr_info "$src source code fetched already"
            continue
        fi
        pr_info "start fetch $src source code"
        git clone $GIT_URL/$src.git -b $BRANCH
    done
    mkdir -p $FMW_PATH && cd $FMW_PATH
    for fmw in $FMWS
    do
        if [ -d $fmw ] ; then
            pr_info "Firmware $fmw fetch already"
            continue
        fi
        pr_info "start fetch $fmw firmware"
        wget $FMW_URL/$fmw.bin
        bash $fmw.bin --auto-accept > /dev/null 2>&1
    done
    rm -f *.bin
}
function build_atf()
{
    SRC=imx-atf
    pr_warn "start build $SRC"
    cd $PRJ_PATH/${SRC}
    make -j${JOBS} CROSS_COMPILE=${CROSS_COMPILE} PLAT=$ATF_PLATFORM bl31
    set -x
    cp build/$ATF_PLATFORM/release/bl31.bin $MKIMG_BIN_PATH
    set +x
}
# Cortex-M SDK download from https://mcuxpresso.nxp.com/ by manual
function build_cortexM()
{
    SRC=mcore-sdk
    DEMO_PATH=boards/$MCORE_BOARD/multicore_examples/rpmsg_lite_str_echo_rtos/armgcc
    DEMO_BIN=release/rpmsg_lite_str_echo_rtos.bin
    export ARMGCC_DIR=$(echo $MCORE_COMPILE | sed 's\/bin/.*\\')
    if [ ! -d $PRJ_PATH/$SRC ] ; then
        if [ "$MCORE_BUILD" == "yes" ] ; then
            pr_error "INFO: Please download $BOARD SDK from https://mcuxpresso.nxp.com"
            pr_error "      by manual and decompress it to folder '$SRC'"
            exit;
        else
            pr_warn "Skip build Cortex-M core SDK source code '$SRC'"
            return ;
        fi
    fi
    pr_warn "start build $SRC"
    cd $PRJ_PATH/${SRC}
    cd $DEMO_PATH
    #bash clean.sh
    if [ ! -s $DEMO_BIN ] ; then
        bash build_release.sh
    fi
    set -x
    cp $DEMO_BIN $MKIMG_BIN_PATH/$MCORE_IMAGE
    set +x
}
function build_uboot()
{
    SRC=uboot-imx
    pr_warn "start build $SRC"
    cd $PRJ_PATH/${SRC}
    defconfig=`echo ${BOARD} | sed 's/-/_/g'`_defconfig
    if [ ! -f .config ] ; then
        make ARCH=arm ${defconfig}
    fi
    make -j${JOBS} CROSS_COMPILE=${CROSS_COMPILE} ARCH=arm
    set -x
    cp u-boot.bin $MKIMG_BIN_PATH
    cp u-boot-nodtb.bin $MKIMG_BIN_PATH
    cp spl/u-boot-spl.bin $MKIMG_BIN_PATH
    cp arch/arm/dts/${BOARD}.dtb $MKIMG_BIN_PATH/$IMXBOOT_DTB
    cp tools/mkimage $MKIMG_BIN_PATH/mkimage_uboot
    set +x
}
# The diagram below illustrate a signed iMX8 flash.bin image layout:
#   reference: uboot-imx/doc/imx/habv4/guides/mx8m_secure_boot.txt
#
#                     +-----------------------------+
#                     |                             |
#                     |     *Signed HDMI/DP FW      |
#                     |                             |
#                     +-----------------------------+
#                     |           Padding           |
#             ------- +-----------------------------+ --------
#                 ^   |          IVT - SPL          |   ^
#          Signed |   +-----------------------------+   |
#           Data  |   |        u-boot-spl.bin       |   |
#                 |   |              +              |   |  SPL
#                 v   |           DDR FW            |   | Image
#             ------- +-----------------------------+   |
#                     |      CSF - SPL + DDR FW     |   v
#                     +-----------------------------+ --------
#                     |           Padding           |
#             ------- +-----------------------------+ --------
#          Signed ^   |          FDT - FIT          |   ^
#           Data  |   +-----------------------------+   |
#                 v   |          IVT - FIT          |   |
#             ------- +-----------------------------+   |
#                     |          CSF - FIT          |   |
#             ------- +-----------------------------+   |  FIT
#                 ^   |       u-boot-nodtb.bin      |   | Image
#                 |   +-----------------------------+   |
#          Signed |   |       OP-TEE (Optional)     |   |
#           Data  |   +-----------------------------+   |
#                 |   |        bl31.bin (ATF)       |   |
#                 |   +-----------------------------+   |
#                 v   |          u-boot.dtb         |   v
#             ------- +-----------------------------+ --------
#
#
# Reference: <<IMX_LINUX_USERS_GUIDE.pdf>> 4.5.13 How to build imx-boot image by using imx-mkimage
function build_imxboot()
{
    SRC=imx-mkimage
    pr_warn "start build $SRC"
    cd $PRJ_PATH/${SRC}
    if [[ $BOARD =~ mx93 ]] ; then
        pr_info "Copy iMX93 firmware to $MKIMG_BIN_PATH"
        cp $FMW_PATH/firmware-sentinel-*/mx93a0-ahab-container.img $MKIMG_BIN_PATH
        cp $FMW_PATH/firmware-imx-*/firmware/ddr/synopsys/lpddr4_imem_1d*.bin $MKIMG_BIN_PATH
        cp $FMW_PATH/firmware-imx-*/firmware/ddr/synopsys/lpddr4_dmem_1d*.bin $MKIMG_BIN_PATH
        cp $FMW_PATH/firmware-imx-*/firmware/ddr/synopsys/lpddr4_imem_2d*.bin $MKIMG_BIN_PATH
        cp $FMW_PATH/firmware-imx-*/firmware/ddr/synopsys/lpddr4_dmem_2d*.bin $MKIMG_BIN_PATH
    elif [[ $BOARD =~ mx8ulp ]] ; then
        pr_info "Copy iMX8ULP firmware to $MKIMG_BIN_PATH"
        cp $FMW_PATH/firmware-upower-*/upower_a1.bin $MKIMG_BIN_PATH/upower.bin
        cp $FMW_PATH/firmware-sentinel-*/mx8ulpa2-ahab-container.img $MKIMG_BIN_PATH
    elif [[ $BOARD =~ mx8 ]] ; then
        pr_info "Copy DDR4 firmware to $MKIMG_BIN_PATH"
        cp $FMW_PATH/firmware-imx-*/firmware/hdmi/cadence/signed_hdmi_imx8m.bin $MKIMG_BIN_PATH
        cp $FMW_PATH/firmware-imx-*/firmware/ddr/synopsys/ddr4_imem_1d*.bin $MKIMG_BIN_PATH
        cp $FMW_PATH/firmware-imx-*/firmware/ddr/synopsys/ddr4_dmem_1d*.bin $MKIMG_BIN_PATH
        cp $FMW_PATH/firmware-imx-*/firmware/ddr/synopsys/ddr4_imem_2d*.bin $MKIMG_BIN_PATH
        cp $FMW_PATH/firmware-imx-*/firmware/ddr/synopsys/ddr4_dmem_2d*.bin $MKIMG_BIN_PATH
    fi
    make SOC=$IMX_BOOT_SOC_TARGET REV=A2 $IMXBOOT_TARGETS
    cp $MKIMG_BIN_PATH/flash.bin u-boot-${BOARD}.imx
    chmod a+x u-boot-${BOARD}.imx
    cp u-boot-${BOARD}.imx $PRFX_PATH
}
function do_build()
{
    cd $PRJ_PATH
    mkdir -p $PRFX_PATH
    build_atf
    build_cortexM
    build_uboot
    build_imxboot
}
function do_install()
{
    cd $PRJ_PATH
    echo ""
    pr_info "bootloader installed to '$PRFX_PATH'"
    ls $PRFX_PATH && echo ""
    if [[ -n "$INST_PATH" && -w $INST_PATH ]] ; then
        pr_info "install bootloader to '$INST_PATH'"
        cp $PRFX_PATH/u-boot-${BOARD}.imx $INST_PATH
    fi
}
function do_clean()
{
    for d in $SRCS
    do
        rm -rf $PRJ_PATH/$d
    done
    rm -rf $PRJ_PATH/firmware
    rm -rf $PRFX_PATH
}
#+-------------------------+
#| Shell script body entry |
#+-------------------------+
cd $PRJ_PATH
export_env
if [[ $# == 1 && $1 == -c ]] ;then
    pr_warn "start clean bootloader"
    do_clean
    exit;
fi
pr_warn "start build bootloader for ${BOARD}"
do_fetch
do_build
do_install
config.json
New file
@@ -0,0 +1,17 @@
{
    "bsp":
    {
        "board":"imx8mp-evk",
        "version":"lf-6.1.22-2.0.0",
        "giturl":"https://github.com/nxp-imx/",
        "cortexAtool":"/opt/gcc-aarch64-10.3-2021.07/bin/aarch64-none-linux-gnu-",
        "cortexMtool":"/opt/gcc-cortexM-10.3-2021.07/bin/arm-none-eabi-"
    },
    "system":
    {
        "distro":"yocto",
        "version":"mickledore",
        "imgsize":"2048",
        "bootsize":"100"
    }
}
debian/build.sh
New file
@@ -0,0 +1,167 @@
#!/bin/bash
# This shell script used to fetch debian root file system
# this project absolute path
PRJ_PATH=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
# the target board name and ARCH(armel/armhf/arm64)
BOARD=igkboard
ARCH=armhf
ARCH=arm64
# Debian 11 (bullseye)
CODENAME=bullseye
VERSION=11
# Debian 12 (bookworm)
CODENAME=bookworm
VERSION=12
# rootfs directory name
ROOTFS_DIR=rootfs-debian-$CODENAME
# rootfs configuration
DEF_PASSWD=12345
# shell script will exit once get command error
set -e
#+-------------------------+
#| Shell script functions  |
#+-------------------------+
function pr_error() {
    echo -e "\033[40;31m $1 \033[0m"
}
function pr_warn() {
    echo -e "\033[40;33m $1 \033[0m"
}
function pr_info() {
    echo -e "\033[40;32m $1 \033[0m"
}
# Debian 12 depends on the new keyring
# https://packages.debian.org/sid/all/debian-archive-keyring/download
function update_keyring()
{
    debname=debian-archive-keyring
    debversion=2023.3
    set +e
    dpkg -l $debname > /dev/null 2>&1
    if [ $? == 0 ] ; then
        dpkg -s debian-archive-keyring | grep Version: | grep $debversion > /dev/null 2>&1
        if [ $? != 0 ] ; then
            pr_info "updating $debname"
            apt purge -y $debname
        else
            pr_info "$debname is latest"
            return;
        fi
    fi
    set -e
    pr_info "install $debname now"
    wget http://ftp.us.debian.org/debian/pool/main/d/$debname/${debname}_${debversion}_all.deb > /dev/null
    dpkg -i ${debname}_${debversion}_all.deb
    rm -f ${debname}_${debversion}_all.deb
}
function do_install()
{
    pr_warn "\ninstall system tools"
    update_keyring
    debootstrap --version > /dev/null 2>&1
    if [ $? == 0 ] ; then
       pr_info "system tools installed already"
       return ;
    fi
    apt install binfmt-support qemu qemu-user-static debootstrap
}
function do_fetch()
{
    pr_warn "\ndebootstrap fetch"
    if [ -f ${ROOTFS_DIR}/bin/bash ] ; then
       pr_info "debain rootfs fetched already"
       return ;
    fi
    debootstrap --arch=${ARCH} --foreign ${CODENAME} ${ROOTFS_DIR} http://ftp.debian.org/debian/
    cp -f /usr/bin/qemu-arm-static ${ROOTFS_DIR}/usr/bin/
    DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true LC_ALL=C LANGUAGE=C LANG=C chroot ${ROOTFS_DIR} debootstrap/debootstrap --second-stage
    DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true LC_ALL=C LANGUAGE=C LANG=C chroot ${ROOTFS_DIR} dpkg --configure -a
    rm -f ${ROOTFS_DIR}/usr/bin/qemu-arm-static
}
function modify_rootfs()
{
    pr_warn "\nmodify rootfs environment"
    # update hostnmae and issue
    echo $BOARD > ${ROOTFS_DIR}/etc/hostname
    echo "Debian GNU/Linux $VERSION \n \l, default password '$DEF_PASSWD'" > ${ROOTFS_DIR}/etc/issue
    # update dns server
    echo "nameserver 223.5.5.5" > ${ROOTFS_DIR}/etc/resolv.conf
    echo "nameserver 114.114.114.114" >> ${ROOTFS_DIR}/etc/resolv.conf
    set +e
    # add ls alias for display with color
    grep "color=auto" ${ROOTFS_DIR}/etc/profile > /dev/null 2>&1
    if [ $? != 0 ] ; then
       echo "alias ls='ls --color=auto'" >> ${ROOTFS_DIR}/etc/profile
    fi
    grep "^PermitRootLogin" ${ROOTFS_DIR}/etc/ssh/sshd_config > /dev/null 2>&1
    if [ $? != 0 ] ; then
       echo "PermitRootLogin yes" >> ${ROOTFS_DIR}/etc/ssh/sshd_config
    fi
    set -e
}
function do_conf()
{
    EXTRA_APPS="vim net-tools network-manager tree file parted locales lsb-release tzdata wireless-tools openssh-server"
    pr_warn "\ndebootstrap configure"
    cp -f /usr/bin/qemu-arm-static ${ROOTFS_DIR}/usr/bin/
    DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true LC_ALL=C LANGUAGE=C LANG=C chroot ${ROOTFS_DIR} apt update
    DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true LC_ALL=C LANGUAGE=C LANG=C chroot ${ROOTFS_DIR} apt install -y ${EXTRA_APPS}
    DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true LC_ALL=C LANGUAGE=C LANG=C chroot ${ROOTFS_DIR} sh -c "echo root:${DEF_PASSWD} | chpasswd"
    rm -f ${ROOTFS_DIR}/usr/bin/qemu-arm-static
    modify_rootfs
}
function do_pack()
{
    pr_warn "\npackage $ROOTFS_DIR"
    cd $PRJ_PATH/$ROOTFS_DIR
    tar -cJf ../$ROOTFS_DIR.tar.xz *
}
#+-------------------------+
#| Shell script body start |
#+-------------------------+
if [ `id -u` != 0 ] ; then
   pr_error "ERRROR: This shell script must excuted as root privilege."
   exit 0;
fi
do_install
do_fetch
do_conf
do_pack
images/build.sh
New file
@@ -0,0 +1,279 @@
#!/bin/bash
# this project absolute path
PRJ_PATH=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
# top project absolute path
TOP_PATH=$(realpath $PRJ_PATH/..)
# binaries build prefix install path
PRFX_PATH=$PRJ_PATH/install
# binaries finally install path if needed
INST_PATH=/tftp
# config file path
CONF_FILE=$TOP_PATH/config.json
# shell script will exit once get command error
set -e
set -u
#+-------------------------+
#| Shell script functions  |
#+-------------------------+
function pr_error() {
    echo -e "\033[40;31m $1 \033[0m"
}
function pr_warn() {
    echo -e "\033[40;33m $1 \033[0m"
}
function pr_info() {
    echo -e "\033[40;32m $1 \033[0m"
}
# decompress a packet to destination path
function do_unpack()
{
    tarball=$1
    dstpath=`pwd`
    if [[ $# == 2 ]] ; then
        dstpath=$2
    fi
    pr_info "decompress $tarball => $dstpath"
    mkdir -p $dstpath
    case $tarball in
        *.tar.gz)
            tar -xzf $tarball -C $dstpath
            ;;
        *.tar.bz2)
            tar -xjf $tarball -C $dstpath
            ;;
        *.tar.xz)
            tar -xJf $tarball -C $dstpath
            ;;
        *.tar.zst)
            tar -I zstd -xf $tarball -C $dstpath
            ;;
        *.tar)
            tar -xf $tarball -C $dstpath
            ;;
        *.zip)
            unzip -qo $tarball -d $dstpath
            ;;
        *)
            pr_error "decompress Unsupport packet: $tarball"
            return 1;
            ;;
    esac
}
# parser configure file and export environment variable
function export_env()
{
    export BOARD=`jq -r ".bsp.board" $CONF_FILE | tr 'A-Z' 'a-z'`
    export BSP_VER=`jq -r ".bsp.version" $CONF_FILE | tr 'A-Z' 'a-z'`
    export DIS_VER=`jq -r ".system.version" $CONF_FILE | tr 'A-Z' 'a-z'`
    export IMAGE_SIZE=`jq -r ".system.imgsize" $CONF_FILE | tr 'A-Z' 'a-z'`
    export BOOT_SIZE=`jq -r ".system.bootsize" $CONF_FILE | tr 'A-Z' 'a-z'`
    export LOOP_DEV=`losetup  -f | cut -d/ -f3`
    export MNT_POINT=$PRJ_PATH/mnt
    export ROOTFS=rootfs-${DIS_VER}
    export UBOOT_BINPATH=$TOP_PATH/bootloader/install/
    export KERNEL_BINPATH=$TOP_PATH/kernel/install/
    export ROOTFS_BINPATH=$TOP_PATH/yocto/install/
    if [[ $BOARD =~ mx8ulp ]] || [[ $BOARD =~ mx8mq ]] || [[ $BOARD =~ mx8mm ]] ; then
        export UBOOT_OFFSET_SECTOR=66
    elif [[ $BOARD =~ mx8mn ]] || [[ $BOARD =~ mx8mp ]] || [[ $BOARD =~ mx93 ]] ; then
        export UBOOT_OFFSET_SECTOR=64
    elif [[ $BOARD =~ mx6 ]] || [[ $BOARD =~ mx7 ]] ; then
        export UBOOT_OFFSET_SECTOR=2
    fi
}
function do_fetch()
{
    cd $PRJ_PATH
    SRCS=$ROOTFS
    for src in $SRCS
    do
        if [ -d $ROOTFS/bin ] ; then
            pr_info "$src fetched already"
            continue
        fi
        for tarball in $ROOTFS_BINPATH/rootfs.tar.*
        do
            if [ -s $tarball ] ; then
                mkdir -p $ROOTFS
                do_unpack $tarball $ROOTFS
                break;
            fi
        done
    done
}
# System image layout map:
# +-------------------+--------------------+----------------------+
# | Raw Part(10MB)    | FAT32 Part2(100MB) | EXT4 Part3(All left) |
# +-------------------+--------------------+----------------------+
# | U-boot on #64     |   Kernel and DTB   |   Root file system   |
# +-------------------+--------------------+----------------------+
function build_image()
{
    export IMAGE_NAME=$BOARD-$DIS_VER.img
    # Uboot size set be 10MB and deployed in 64th sector on eMMC/TFCard
    UBOOT_SIZE=10
    mkdir -p $MNT_POINT
    pr_info "start generate empty system image"
    dd if=/dev/zero of=${IMAGE_NAME} bs=1024k count=${IMAGE_SIZE} conv=sync
    chmod a+x ${IMAGE_NAME}
    pr_info "start partition system image"
    fat_start=$UBOOT_SIZE
    fat_end=`expr $UBOOT_SIZE + $BOOT_SIZE`
    parted ${IMAGE_NAME} mklabel msdos
    parted ${IMAGE_NAME} mkpart primary fat32 ${fat_start}M ${fat_end}M
    parted ${IMAGE_NAME} mkpart primary ext4 ${fat_end}M 100%
    sync
    pr_info "losetup system image on $LOOP_DEV"
    losetup /dev/${LOOP_DEV}  ${IMAGE_NAME}
    kpartx -av /dev/${LOOP_DEV}
    pr_info "start format system image"
    mkfs.vfat /dev/mapper/${LOOP_DEV}p1
    mkfs.ext4 /dev/mapper/${LOOP_DEV}p2
    sync
    pr_info "start install u-boot image"
    dd if=$UBOOT_BINPATH/u-boot-${BOARD}.imx of=${IMAGE_NAME} bs=512 seek=$UBOOT_OFFSET_SECTOR conv=notrunc,sync
    pr_info "start install linux kernel images"
    mount -t vfat /dev/mapper/${LOOP_DEV}p1 ${MNT_POINT}
    cp -rf $KERNEL_BINPATH/Image       ${MNT_POINT}/
    cp -rf $KERNEL_BINPATH/${BOARD}.dtb ${MNT_POINT}/
    sync && umount ${MNT_POINT}
    pr_info "update drivers in root filesystem"
    rm -rf $ROOTFS/lib/modules/
    mkdir -p $ROOTFS/lib/modules/
    cp -rf $KERNEL_BINPATH/lib/modules/[0-9]*\.[0-9]*\.[0-9]* $ROOTFS/lib/modules/
    pr_info "start install root filesystem"
    mount -t ext4 /dev/mapper/${LOOP_DEV}p2 ${MNT_POINT}
    cp -af $ROOTFS/* ${MNT_POINT}
    sync && umount ${MNT_POINT}
    pr_warn "Build $BOARD-$BSP_VER-$DIS_VER system image done"
}
function exit_handler()
{
    pr_warn "Shell script exit now, do some clean work\n"
    set +e
    if mountpoint ${MNT_POINT} > /dev/null 2>&1 ; then
        pr_info "umount ${MNT_POINT}"
        umount ${MNT_POINT} > /dev/null 2>&1
    fi
    rm -rf ${MNT_POINT}
    if [ -e /dev/mapper/${LOOP_DEV}p1 ] ; then
        pr_info "kpartx -dv /dev/${LOOP_DEV}"
        kpartx -dv /dev/${LOOP_DEV}
    fi
    losetup -a | grep "${LOOP_DEV}" > /dev/null 2>&1
    if [ $? == 0 ]  ; then
        pr_info "losetup -d /dev/${LOOP_DEV}"
        losetup -d /dev/${LOOP_DEV}
    fi
}
function do_build()
{
    cd $PRJ_PATH
    build_image
}
function do_install()
{
    cd $PRJ_PATH
    mkdir -p $PRFX_PATH
    cp $UBOOT_BINPATH/u-boot-${BOARD}.imx $PRFX_PATH
    mv $IMAGE_NAME $PRFX_PATH
    if [[ -n "$INST_PATH" && -w $INST_PATH ]] ; then
        pr_info "install bootloader and system image to '$INST_PATH'"
        cp $PRFX_PATH/u-boot-${BOARD}.imx $INST_PATH
        cp $PRFX_PATH/$IMAGE_NAME $INST_PATH
    fi
}
function do_clean()
{
    for d in rootfs-*
    do
        rm -rf $PRJ_PATH/$d
    done
    rm -rf $PRFX_PATH
    rm -f *.img
}
#+-------------------------+
#| Shell script body entry |
#+-------------------------+
if [ `id -u` != 0 ] ; then
    pr_error "ERROR: This shell script must run as root"
    exit;
fi
cd $PRJ_PATH
export_env
if [[ $# == 1 && $1 == -c ]] ;then
    pr_warn "start clean system image"
    do_clean
    exit;
fi
pr_warn "Build $BOARD-$BSP_VER-$DIS_VER system image"
trap 'exit_handler' EXIT
do_fetch
do_build
do_install
kernel/build.sh
New file
@@ -0,0 +1,142 @@
#!/bin/bash
# this project absolute path
PRJ_PATH=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
# top project absolute path
TOP_PATH=$(realpath $PRJ_PATH/..)
# binaries build prefix install path
PRFX_PATH=$PRJ_PATH/install
# binaries finally install path if needed
#INST_PATH=/tftp
# config file path
CONF_FILE=$TOP_PATH/config.json
# shell script will exit once get command error
set -e
#+-------------------------+
#| Shell script functions  |
#+-------------------------+
function pr_error() {
    echo -e "\033[40;31m $1 \033[0m"
}
function pr_warn() {
    echo -e "\033[40;33m $1 \033[0m"
}
function pr_info() {
    echo -e "\033[40;32m $1 \033[0m"
}
# parser configure file and export environment variable
function export_env()
{
    export BOARD=`jq -r ".bsp.board" $CONF_FILE | tr 'A-Z' 'a-z'`
    export BSP_VER=`jq -r ".bsp.version" $CONF_FILE | tr 'A-Z' 'a-z'`
    export GIT_URL=`jq -r ".bsp.giturl" $CONF_FILE | tr 'A-Z' 'a-z'`
    export CROSS_COMPILE=`jq -r ".bsp.cortexAtool" $CONF_FILE | tr 'A-Z' 'a-z'`
    export BRANCH=$BSP_VER
    export KER_PATH=$PRJ_PATH/linux-imx
    export JOBS=`cat /proc/cpuinfo | grep processor | wc -l`
    export ARCH=arm64
    export SRCS="linux-imx"
}
function build_kernel()
{
    cd $PRJ_PATH
    if [ -d $KER_PATH ] ; then
        pr_info "linux kernel source code fetched already"
    else
        pr_info "start fetch linux kernel source code"
        git clone $GIT_URL/linux-imx.git -b $BRANCH
    fi
    pr_info "Start build linux kernel source code"
    cd $KER_PATH
    defconfig=imx_v8_defconfig
    if [ ! -s .config ] ; then
        make ${defconfig}
    fi
    make -j ${JOBS}
}
function do_install()
{
    pr_info "start install linux kernel images"
    cd $KER_PATH
    if [ -d $PRFX_PATH ] ; then
        rm -rf $PRFX_PATH/*
    else
        mkdir -p $PRFX_PATH
    fi
    # Install image
    cp arch/arm64/boot/Image $PRFX_PATH
    cp arch/arm64/boot/dts/freescale/${BOARD}.dtb $PRFX_PATH
    # Install kernel modules
    make modules_install INSTALL_MOD_PATH=$PRFX_PATH INSTALL_MOD_STRIP=1
    echo ""
    pr_info "linux kernel installed to '$PRFX_PATH'"
    ls $PRFX_PATH && echo ""
    if [[ -n "$INST_PATH" && -w $INST_PATH ]] ; then
        pr_info "install linux kernel to '$INST_PATH'"
        cp $PRFX_PATH/Image $INST_PATH
        cp $PRFX_PATH/${BOARD}.dtb $INST_PATH
    fi
}
function do_build()
{
    cd $PRJ_PATH
    build_kernel
    do_install
}
function do_clean()
{
    cd $PRJ_PATH
    for d in $SRCS
    do
        rm -rf $PRJ_PATH/$d
    done
    rm -rf $PRFX_PATH
}
#+-------------------------+
#| Shell script body entry |
#+-------------------------+
export_env
if [[ $# == 1 && $1 == -c ]] ;then
    pr_warn "start clean linux kernel"
    do_clean
    exit;
fi
pr_warn "start build linux kernel for ${BOARD}"
do_build
tools/imgmnt
New file
@@ -0,0 +1,120 @@
#!/bin/bash
# This shell script used mount/umount an linux system image and update it
mnt_boot=boot
mnt_root=rootfs
function mount_image()
{
    img_file=$1
    loop_dev=`losetup  -f | cut -d/ -f3`
    if [ ! -s $img_file ] ; then
        echo "ERROR: $img_file not found!"
        exit 1;
    fi
    if [ -z $loop_dev ] ; then
        echo "ERROR: loop dev not found!"
        exit 2;
    fi
    echo "INFO: losetup /dev/${loop_dev} ${img_file}"
    losetup /dev/${loop_dev} ${img_file}
    if [ $? != 0 ] ; then
        echo "ERROR: losetup /dev/${loop_dev} ${img_file} failed!"
        exit 3;
    fi
    echo "INFO: kpartx -av /dev/${loop_dev}"
    kpartx -av /dev/${loop_dev}
    echo "INFO: mount ${mnt_boot} ${mnt_root}"
    mkdir -p ${mnt_boot} ${mnt_root}
    mount /dev/mapper/${loop_dev}p1 ${mnt_boot}
    mount /dev/mapper/${loop_dev}p2 ${mnt_root}
    echo "INFO: mount $img_file done."
}
function umount_image()
{
    img_file=$1
    mountpoint $mnt_boot > /dev/null 2>&1
    if [ $? == 0 ] ; then
        echo "INFO: umount ${mnt_boot}"
        umount ${mnt_boot}
        rmdir  ${mnt_boot}
    fi
    mountpoint $mnt_root > /dev/null 2>&1
    if [ $? == 0 ] ; then
        echo "INFO: umount ${mnt_root}"
        umount ${mnt_root}
        rmdir  ${mnt_root}
    fi
    # loop_dev should be 'loopX' such as 'loop9'.
    loop_dev=`losetup -a | grep $img_file| cut -d: -f1 | cut -d/ -f3`
    if [[ -z $loop_dev ]] ; then
        exit;
    fi
    if [[ -e /dev/mapper/${loop_dev}p1 ]] ; then
        echo "INFO: kpartx -dv /dev/${loop_dev}"
        kpartx -dv /dev/${loop_dev}
    fi
    echo "INFO: losetup -d /dev/${loop_dev}"
    losetup -d /dev/${loop_dev}
    echo "INFO: umount $img_file done."
}
function do_usage()
{
    echo ""
    echo "Usage:"
    echo "  $0 [-m] [-u] image_file"
    echo "     -m:  mount the image file"
    echo "     -u: umount the image file"
    echo ""
    exit;
}
action=
img_file=
while getopts "mu" OPTNAME
do
    case "${OPTNAME}" in
        "m")
            action=mount
            ;;
        "u")
            action=umount
            ;;
        "*")
            do_usage
            ;;
    esac
done
shift $(( $OPTIND-1 ))
img_file=$1
if [[ -z $img_file ]] || [[ -z $action ]] ; then
    do_usage
    exit;
fi
if [ $action == "mount" ] ; then
    mount_image $img_file
elif [ $action == "umount" ] ; then
    umount_image $img_file
fi
tools/setup_tools.sh
New file
@@ -0,0 +1,120 @@
#!/bin/bash
# This shell script used to install system tools
# display in red
function pr_error() {
    echo -e "\033[40;31m --E-- $1 \033[0m\n"
}
# display in green
function pr_info() {
    echo -e "\033[40;32m --I-- $1 \033[0m\n"
}
if [ `id -u` != 0 ] ; then
    echo ""
    pr_error "This shell script must be excuted as root privilege"
    exit;
fi
function install_systools()
{
    if command -v jq > /dev/null 2>&1 ; then
        pr_info "All system tools already installed, skip it"
        return 0;
    fi
    pr_info "start apt install system tools(commands)"
    systools="coreutils jq wget curl tree gawk sed unzip cpio bc lzop zstd rsync kmod kpartx \
        desktop-file-utils iputils-ping xterm diffstat chrpath asciidoc docbook-utils help2man \
        build-essential gcc g++ make cmake automake groff socat flex texinfo bison texi2html \
        git cvs subversion mercurial autoconf autoconf-archive parted dosfstools \
        python3 python3-pip python3-pexpect python3-git python3-jinja2 \
        lib32z1 libssl-dev libncurses-dev libgl1-mesa-dev libglu1-mesa-dev libsdl1.2-dev "
    apt update > /dev/null 2>&1
    apt install -y $systools
}
function install_devtools()
{
    if command -v debootstrap > /dev/null 2>&1 ; then
        pr_info "All development tools already installed, skip it"
        return 0;
    fi
    pr_info "start apt install devlopment tools(commands)"
    devtools="u-boot-tools mtd-utils device-tree-compiler binfmt-support \
                qemu qemu-user-static debootstrap debian-archive-keyring "
    apt install -y $devtools
}
# NXP document suggest cross compiler from ARM Developer:
#   https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads
function install_crosstool()
{
    ARMTOOL_VER=10.3-2021.07
    CortexM_PACK=gcc-arm-none-eabi-$ARMTOOL_VER-`uname -p`-linux
    CortexM_TAR=$CortexM_PACK.tar.bz2
    CortexM_URL=https://developer.arm.com/-/media/Files/downloads/gnu-rm/$ARMTOOL_VER/
    CortexM_NAME=gcc-cortexM-$ARMTOOL_VER
    # Crosstool for Cortex-M download from ARM Developer
    if [ -d /opt/$CortexM_NAME ]  ; then
        pr_info "Cortex-M crosstool /opt/$CortexM_NAME installed already, skip it"
    else
        if [ ! -s $CortexM_TAR ] ; then
            pr_info "start download cross compiler from ARM Developer for Cortex-M core"
            wget $CortexM_URL/$CortexM_TAR
        fi
        pr_info "start decompress cross compiler for Cortex-M core"
        tar -xjf $CortexM_TAR -C /opt
        mv /opt/gcc-arm-none-eabi-$ARMTOOL_VER /opt/$CortexM_NAME
        rm -f $CortexM_TAR
        /opt/$CortexM_NAME/bin/arm-none-eabi-gcc -v
        pr_info "cross compiler for Cortex-M installed to \"/opt/$CortexM_NAME\" successfully"
    fi
    # Crosstool for Cortex-A download from ARM Developer
    CortexA_PACK=gcc-arm-$ARMTOOL_VER-`uname -p`-aarch64-none-linux-gnu
    CortexA_TAR=$CortexA_PACK.tar.xz
    CortexA_URL=https://developer.arm.com/-/media/Files/downloads/gnu-a/$ARMTOOL_VER/binrel/
    CortexA_NAME=gcc-aarch64-$ARMTOOL_VER
    if [ -d /opt/$CortexA_NAME ]  ; then
        pr_info "Cortex-A crosstool /opt/$CortexA_NAME installed already, skip it"
    else
        if [ ! -s $CortexA_TAR ] ; then
            pr_info "start download cross compiler from ARM Developer for Cortex-A core"
            wget $CortexA_URL/$CortexA_TAR
        fi
        pr_info "start decompress cross compiler for Cortex-A core"
        tar -xJf $CortexA_TAR -C /opt
        mv /opt/$CortexA_PACK /opt/$CortexA_NAME
        rm -f $CortexA_TAR
        /opt/$CortexA_NAME/bin/aarch64-none-linux-gnu-gcc -v
        pr_info "cross compiler for Cortex-A installed to \"/opt/$CortexA_NAME\" successfully"
    fi
}
echo ""
set -e
install_systools
install_devtools
install_crosstool
yocto/build.sh
New file
@@ -0,0 +1,149 @@
#!/bin/bash
# bitbake target
BB_TARGET=imx-image-full
# this project absolute path
PRJ_PATH=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
# top project absolute path
TOP_PATH=$(realpath $PRJ_PATH/..)
# binaries install path
INST_PATH=$PRJ_PATH/install
# config file path
CONF_FILE=$TOP_PATH/config.json
# Download path
#DL_PATH="/srv/yocto_packets/"
# shell script will exit once get command error
set -e
#+-------------------------+
#| Shell script functions  |
#+-------------------------+
function pr_error() {
    echo -e "\033[40;31m $1 \033[0m"
}
function pr_warn() {
    echo -e "\033[40;33m $1 \033[0m"
}
function pr_info() {
    echo -e "\033[40;32m $1 \033[0m"
}
# parser configure file and export environment variable
function export_env()
{
    export BOARD=`jq -r ".bsp.board" $CONF_FILE | tr 'A-Z' 'a-z'`
    export BSP_VER=`jq -r ".bsp.version" $CONF_FILE | tr 'A-Z' 'a-z'`
    export GIT_URL=`jq -r ".bsp.giturl" $CONF_FILE | tr 'A-Z' 'a-z'`
    export YCT_VER=`jq -r ".system.version" $CONF_FILE | tr 'A-Z' 'a-z'`
    export YCT_PATH=$PRJ_PATH/$YCT_VER-$BSP_VER
    export BUILD_DIR=${BOARD}
    if [[ $BOARD =~ mx93 ]] ; then
        YCT_MACHINE=imx93evk
    elif [[ $BOARD =~ mx8ulp ]] ; then
        YCT_MACHINE=imx8ulp-lpddr4-evk
    elif [[ $BOARD =~ mx8mq ]] ; then
        YCT_MACHINE=imx8mqevk
    elif [[ $BOARD =~ mx8mp ]] ; then
        YCT_MACHINE=imx8mp-ddr4-evk
    elif [[ $BOARD =~ mx8mm ]] ; then
        YCT_MACHINE=imx8mm-ddr4-evk
    elif [[ $BOARD =~ mx8mn ]] ; then
        YCT_MACHINE=imx8mn-ddr4-evk
    fi
}
function do_fetch()
{
    mkdir -p $YCT_PATH && cd $YCT_PATH
    if [ ! -d sources ] ; then
        pr_info "start repo fetch Yocto $YCT_VER source code"
        if ! command -v repo > /dev/null 2>&1 ; then
            curl https://storage.googleapis.com/git-repo-downloads/repo > repo
            chmod a+x repo
            export PATH=$YCT_PATH:$PATH
        fi
        BSP_VER=`echo $BSP_VER | sed 's/lf/imx/'`
        repo init -u https://github.com/nxp-imx/imx-manifest -b imx-linux-$YCT_VER -m $BSP_VER.xml
        repo sync && rm -f repo
    else
        pr_warn "Yocto $YCT_VER source code fetched already"
    fi
}
function do_build()
{
    cd $YCT_PATH
    if [ ! -f ${BUILD_DIR}/conf/local.conf ] ; then
        pr_info "source imx-setup-release.sh for $BOARD"
        DISTRO=fsl-imx-wayland MACHINE=$YCT_MACHINE source imx-setup-release.sh -b $BUILD_DIR
    else
        pr_info "source poky/oe-init-build-env"
        source sources/poky/oe-init-build-env $BUILD_DIR
    fi
    if [[ -n "$DL_PATH" ]] ; then
        sed -i "s|^#DL_DIR.*|DL_DIR ?= \"$DL_PATH\"|g" conf/local.conf
        sed -i "s|^DL_DIR.*|DL_DIR ?= \"$DL_PATH\"|g" conf/local.conf
    fi
    bitbake $BB_TARGET
}
function do_install()
{
    cd $YCT_PATH
    echo ""
    pr_info "Yocto($YCT_VER) installed to '$INST_PATH'"
    mkdir -p ${INST_PATH}
    cp $BUILD_DIR/tmp/deploy/images/*/$BB_TARGET-*.rootfs.tar.zst ${INST_PATH}/rootfs.tar.zst
    cp $BUILD_DIR/tmp/deploy/images/*/imx-boot ${INST_PATH}/u-boot-${BOARD}.imx
    chmod a+x ${INST_PATH}/u-boot-${BOARD}.imx
    cp $BUILD_DIR/tmp/deploy/images/*/$BB_TARGET-*.wic.zst ${INST_PATH}
    ls ${INST_PATH} && echo ""
}
function do_clean()
{
    cd $PRJ_PATH
    rm -rf $INST_PATH
}
#+-------------------------+
#| Shell script body entry |
#+-------------------------+
export_env
if [[ $# == 1 && $1 == -c ]] ;then
    pr_warn "start clean Yocto source code"
    do_clean
    exit;
fi
pr_warn "start build Yocto $YCT_VER for ${BOARD}"
do_fetch
do_build
do_install