#!/bin/bash
#
# This script is heavily based on the pack script from the Allwinner SDK.
#
# pack/pack
# (c) Copyright 2013
# Allwinner Technology Co., Ltd. <www.allwinnertech.com>
# James Deng <csjamesdeng@allwinnertech.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

localpath=$(cd $(dirname $0) && pwd)

source $localpath/utils.sh

PACK_OUT_DIR=$localpath/pack_out
PLAT_OUT=$localpath/plat_out
PACK_KERN=linux-6.6
PACK_CHIP=sun50iw9p1
PACK_BOARD=evb
BUSSINESS=
PACK_TYPE=linux
ARCH=arm64
PACK_NOR=default
PACK_DEBUG=uart0
PACK_MODE=normal
PACK_FUNC=android
PACK_SECURE=none
CHIP_CONFIG_DIR=
BRANDY_SPL_VER=
LINUX_DTBO_FILE=
REDUNDANT_ENV_SIZE=
ONE_ENV_SIZE=
TOOLS_DIR=$localpath/tools
PACK_PLATFORM=buildroot
UPDATE_BOOTIMG=
FLASH=default
CHIP=sun50iw9p1
PACK_IC=t507
BRANDY_UBOOT_VER=2018.07
UBOOT_DIR=$1
BRANDY_DEFCONF=sun50iw9p1_t507_evb_defconfig

function flashmap_check()
{
        if [ "x${BRANDY_UBOOT_VER}" = "x2023" ] ; then
                UBOOT_DTB_NAME=$(cat "${UBOOT_DIR}/bsp/configs/${BRANDY_DEFCONF}" | grep -w "CONFIG_DEFAULT_DEVICE_TREE" | awk -F= '{printf $2}')
        else
                UBOOT_DTB_NAME=$(cat "${UBOOT_DIR}/configs/${BRANDY_DEFCONF}" | grep -w "CONFIG_DEFAULT_DEVICE_TREE" | awk -F= '{printf $2}')
        fi
        UBOOT_DTB_NAME="${UBOOT_DTB_NAME//\"/}"

        if [ "x${ARCH}" = "xriscv32" ] || [ "x${ARCH}" = "xriscv64" ] ; then
                UBOOT_ARCH_DIR=riscv
        elif [ "x${ARCH}" = "xarm" ] || [ "x${ARCH}" = "xarm64" ] ; then
                UBOOT_ARCH_DIR=arm
        else
                LOGE "ARCH is error"
                return 0
        fi

        if [ "x${BRANDY_UBOOT_VER}" = "x2023" ] ; then
                if [ "x${FLASH}" = "xdefault" ] ; then
                        FLASHMAP_ENABLE=$(sunxi_flashmap_tool -f check_flashmap_enable -t mmc -d ${UBOOT_DIR}/arch/${UBOOT_ARCH_DIR}/dts/uboot-board.dtb)
                elif [ "x${FLASH}" = "xnor" ] ; then
                        FLASHMAP_ENABLE=$(sunxi_flashmap_tool -f check_flashmap_enable -t flash -d ${UBOOT_DIR}/arch/${UBOOT_ARCH_DIR}/dts/uboot-board.dtb)
                else
                        LOGE "FLASH type is error"
                        return 0
                fi
        else
                if [ "x${FLASH}" = "xdefault" ] ; then
                        FLASHMAP_ENABLE=$(sunxi_flashmap_tool -f check_flashmap_enable -t mmc -d ${UBOOT_DIR}/arch/${UBOOT_ARCH_DIR}/dts/${UBOOT_DTB_NAME}.dtb)
                elif [ "x${FLASH}" = "xnor" ] ; then
                        FLASHMAP_ENABLE=$(sunxi_flashmap_tool -f check_flashmap_enable -t flash -d ${UBOOT_DIR}/arch/${UBOOT_ARCH_DIR}/dts/${UBOOT_DTB_NAME}.dtb)
                else
                        LOGE "FLASH type is error"
                        return 0
                fi
        fi

        if [ "x${PACK_SECURE}" = "xsecure" ]; then
                check_toc_size=`stat toc1.fex --format="%s"`
                if [ -f toc0_sdcard.fex ] ; then
                        check_boot0_size=`stat toc0_sdcard.fex --format="%s"`
                elif [ -f toc0_nand.fex ] ; then
                        check_boot0_size=`stat toc0_nand.fex --format="%s"`
                else
                        check_boot0_size=`stat toc0.fex --format="%s"`
                fi
        elif [ "x${PACK_NOR}" = "xnor" ]; then
                check_toc_size=`stat boot_package_nor.fex --format="%s"`
                check_boot0_size=`stat boot0_spinor.fex --format="%s"`
        else
                check_toc_size=`stat boot_package.fex --format="%s"`
                check_boot0_size=`stat boot0_sdcard.fex --format="%s"`
        fi

        if [ "x${FLASHMAP_ENABLE}" = "xenabled" ] ; then
                LOGD "flashmap is enable"
                if [ "x${FLASH}" = "xdefault" ] ; then
                        LOGD "TODO..."
                elif [ "x${FLASH}" = "xnor" ] ; then
                        if [ "x${PACK_SECURE}" = "xsecure" ] ; then
                                attribute_check flash uboot_start secure_logic_offset ${check_toc_size} ${UBOOT_ARCH_DIR} ${UBOOT_DTB_NAME}
                                attribute_check flash boot0_start boot_param_start ${check_boot0_size} ${UBOOT_ARCH_DIR} ${UBOOT_DTB_NAME}
                        else
                                attribute_check flash uboot_start logic_offset ${check_toc_size} ${UBOOT_ARCH_DIR} ${UBOOT_DTB_NAME}
                                attribute_check flash boot0_start boot_param_start ${check_boot0_size} ${UBOOT_ARCH_DIR} ${UBOOT_DTB_NAME}
                        fi
                else
                        LOGD "storage_type type is error"
                        return 0
                fi
        else
                LOGD "flashmap is disable"
        fi
}

function check_toc1_size()
{
        local max_toc_size=2097152
        local special_platform_size
        local special_platform=("sun55iw3p1" "sun55iw6p1" "sun8iw22p1" "sun60iw2p1")
        local special_toc_size=(3145728 3145728 3145728 3145728)

        if [ ${FLASH} == nor ] ; then
                if [ $1 -gt ${max_toc_size} ];then
                        LOGF "boot_package.fex/toc1.fex More than ${max_toc_size} bytes limit too large!!!"
                fi
        fi

        special_platform_size=${#special_platform[@]}

        for ((i=0; i<$special_platform_size; i++))
        do
                if [ "$CHIP" == "${special_platform[i]}" ]; then
                        if [ $1 -gt ${special_toc_size[i]} ];then
                                LOGF "boot_package.fex/toc1.fex More than ${special_toc_size[i]} bytes limit too large!!!"
                        else
                                return 0
                        fi
                fi
        done

        if [ $1 -gt ${max_toc_size} ];then
                LOGF "boot_package.fex/toc1.fex More than ${max_toc_size} bytes limit too large!!!"
        fi
}

function do_finish()
{
        # Yeah, it should contain all files into full_img.fex for spinor
        # Because, as usually, spinor image size is very small.
        # If fail to create full_img.fex, we should fake it empty.

        # WTF, it is so ugly!!! It must be sunxi_mbr.fex & sys_partition.bin,
        # not sunxi_mbr_xxx.fex & sys_partition_xxx.bin. In order to advoid this
        # loathsome thing, we need to backup & copy files. Check whether
        # sys_partition_nor.bin is exist, and create sunxi_mbr.fex for Nor.

        local IMG_NAME="${PACK_IC}_${PACK_TYPE}${PACK_PLATFORM_VERSION}_${PACK_BOARD}_${PACK_DEBUG}"
        if [ "x${PACK_MODE}" = "xdump" ] ; then
                IMG_NAME="${IMG_NAME}_${PACK_MODE}"
        fi

        if [ "x${PACK_FUNC}" = "xprvt" ]; then
                IMG_NAME="${IMG_NAME}_${PACK_FUNC}"
        fi

        if [ "x${PACK_SECURE}" = "xsecure" ] ; then
                IMG_NAME="${IMG_NAME}_${PACK_SECURE}"
        fi

        if [ "x${PACK_FUNC}" = "xprev_refurbish" ] ; then
                IMG_NAME="${IMG_NAME}_${PACK_FUNC}"
        fi

        if [ "x${PACK_NOR}" = "xnor" ] ; then
                IMG_NAME="${IMG_NAME}_${PACK_NOR}"
        fi

	if [ "x${PACK_SECURE}" != "xnone" ]; then
                local MAIN_VERION=$(readcfg dragon_toc.cfg rollback_ver ver)
                if [ ! -n "${MAIN_VERION}" ]; then
                        local MAIN_VERION="$(echo '__unique:;@echo ${MAIN_VERSION}' | make -f - -f ${PACK_OUT_DIR}/version_base.mk --no-print-directory __unique)"
                fi
                if [ -z "${MAIN_VERION}" ]; then
                        LOGF "Anti-rollback version is empty!"
                fi
                IMG_NAME="${IMG_NAME}_v${MAIN_VERION}.img"
        else
                IMG_NAME="${IMG_NAME}.img"
        fi

        # don't add wrapper_run_logd, this script needs modify local var
        [ -e ${CHIP_CONFIG_DIR}/configs/default/pack-pre-finish ] &&
                source ${CHIP_CONFIG_DIR}/configs/default/pack-pre-finish

        # don't add wrapper_run_logd, this script needs modify local var
        [ -e ${CHIP_CONFIG_DIR}/configs/${PACK_BOARD}/pack-pre-finish ] &&
                source ${CHIP_CONFIG_DIR}/configs/${PACK_BOARD}/pack-pre-finish

        local IMG_PROGRAMMER_NAME="${IMG_NAME%.*}_programmer.img"

        echo $(date +"%Y-%m-%d %H:%M:%S") >> ${PACK_OUT_DIR}/sunxi_version.fex
        echo "imagename = $IMG_NAME" >> ${PACK_OUT_DIR}/image.cfg
        echo "" >> ${PACK_OUT_DIR}/image.cfg

        local imagesize
        local toc_size

        if [ "x${PACK_SECURE}" = "xsecure" ]; then
                toc_size=`stat toc1.fex --format="%s"`
        else
                if [ "x${FLASH}" == "xnor" ] ; then
                        toc_size=`stat boot_package_nor.fex --format="%s"`
                else
                        toc_size=`stat boot_package.fex --format="%s"`
                fi
        fi

	check_toc1_size ${toc_size}

        flashmap_check

        if [ "x${PACK_NOR}" = "xnor" ] ; then
                NOR_LOGIC_START=2016
                NOR_UBOOT_START=128
                NOR_FLASH_SIZE=65536 #32M
                NOR_LOGIC_START_KB=`expr ${NOR_LOGIC_START} / 2`
                NOR_UBOOT_START_KB=`expr ${NOR_UBOOT_START} / 2`

                local uboot_dts=""
                if [ -n "${BRANDY_UBOOT_VER}" ] && [ ${BRANDY_UBOOT_VER} -ge 2023 ]; then
                        uboot_dts="${LICHEE_BOARD_CONFIG_DIR}/uboot-${BRANDY_UBOOT_VER}/uboot-board.dts"
                fi

                if [ ! -f ${uboot_dts} ]; then
                        uboot_dts="${LICHEE_BOARD_CONFIG_DIR}/uboot-board.dts"
                fi

                if [ -f ${uboot_dts} ] && [ x"$(grep "nor_map" ${uboot_dts})" != x"" ]; then
                        LOGD "get flashmap from ${uboot_dts}"
                        NOR_FLASH_SIZE=$(awk '/nor_map {/,/}/ {print NR ": " $0}' ${uboot_dts} \
                                | grep  "\bflash_size\b" | grep -oP "(?<=\<)\d+(?=\>)")

                        NOR_LOGIC_START=$(awk '/nor_map {/,/}/ {print NR ": " $0}' ${uboot_dts} \
                                | grep  "\blogic_offset\b" | grep -oP "(?<=\<)\d+(?=\>)")

                        NOR_UBOOT_START=$(awk '/nor_map {/,/}/ {print NR ": " $0}' ${uboot_dts} \
                                | grep  "\buboot_start\b" | grep -oP "(?<=\<)\d+(?=\>)")

                        [ x"${NOR_FLASH_SIZE}" = x"" -o x"${NOR_LOGIC_START}" = x"" -o x"${NOR_UBOOT_START}" = x"" ] && {
                                LOGW "flash_size,logic_offset,uboot_start maybe not set in uboot-board.dts"
                                NOR_LOGIC_START=2016
                                NOR_UBOOT_START=128
                                NOR_FLASH_SIZE=65536 #32M
                        }

                        NOR_LOGIC_START_KB=`expr ${NOR_LOGIC_START} / 2`
			NOR_UBOOT_START_KB=`expr ${NOR_UBOOT_START} / 2`
                        LOGD "flash size:${NOR_FLASH_SIZE}, logic start:${NOR_LOGIC_START}, uboot start:${NOR_UBOOT_START}"
                fi

                wrapper_run_logd update_mbr sys_partition_nor.bin 1 sunxi_mbr_nor.fex dlinfo.fex \
                                ${NOR_FLASH_SIZE} ${NOR_LOGIC_START} 1

                if [ $? -ne 0 ]; then
                        LOGF "update_mbr failed"
                fi
                LOGD '----------programmer nor image is full_img.fex ----------'
                if [ "x${PACK_KERN}" = "xlinux-3.4" ] ; then
                #when use devicetree, the size of uboot+dtb is larger then 256K
                        #BOOT1_FILE=u-boot-spinor.fex
                        #LOGIC_START=240 #240+16=256K
                        #merge_package full_img.fex boot0_spinor.fex \
                        #        u-boot-spinor.fex sunxi_mbr_nor.fex sys_partition_nor.bin
                        merge_full_img --out full_img.fex --boot0 boot0_spinor.fex --boot1u-boot-spinor.fex \
                                                        --mbr sunxi_mbr_nor.fex  --partition sys_partition_nor.bin \
                                                        --logic_start 240 > /dev/null
                else
                        merge_full_img --out full_img.fex --boot0 boot0_spinor.fex --boot1 boot_package_nor.fex \
                                --mbr sunxi_gpt.fex --partition sys_partition_nor.bin \
                                --logic_start ${NOR_LOGIC_START_KB} --uboot_start ${NOR_UBOOT_START_KB} > /dev/null
                fi

                if [ $? -ne 0 ]; then
                        LOGF "merge_full_img failed"
                fi
                imagesize=$(du --apparent-size -sh ${PACK_OUT_DIR}/full_img.fex | awk '{print $1}')
                LOGI "$imagesize\t${PACK_OUT_DIR}/full_img.fex"
                mv sys_partition_nor.fex sys_partition.fex
        fi
	if [ ! -f sys_partition_nor.bin ]; then
                wrapper_run_logd update_mbr          sys_partition.bin 4
                if [ $? -ne 0 ]; then
                        LOGF "update_mbr failed"
                fi

                #40960 is the mbr location for emmc/ufs
                #0  is emmc/nand ; 1 is spinor; 2 is ufs;
		 if [ -f programmer_img_ufs.cfg ]; then
                        LOGD "get flashmap from programmer_img_ufs.cfg"
                        FLASH_TOTAL_SECTORS=$(grep "^flash_total_sectors=" "programmer_img_ufs.cfg" | cut -d '=' -f 2)
                        LOGIC_OFFSET=$(grep "^logic_offset=" "programmer_img_ufs.cfg" | cut -d '=' -f 2)

                        [ x"${FLASH_TOTAL_SECTORS}" = x"" ] && {
                                echo "flash_total_sectors not set in programmer_img_ufs.cfg"
                                FLASH_TOTAL_SECTORS=249970688
                        }

                        [ x"${LOGIC_OFFSET}" = x"" ] && {
                                echo "logic_offset not set in programmer_img_ufs.cfg"
                                LOGIC_OFFSET=40960
                        }
                        update_mbr sys_partition.bin 4 sunxi_mbr.fex dlinfo.fex ${FLASH_TOTAL_SECTORS} ${LOGIC_OFFSET} 2
                elif [ -f programmer_img.cfg ]; then
                        LOGD "get flashmap from programmer_img.cfg"
                        FLASH_TOTAL_SECTORS=$(grep "^flash_total_sectors=" "programmer_img.cfg" | cut -d '=' -f 2)
                        LOGIC_OFFSET=$(grep "^logic_offset=" "programmer_img.cfg" | cut -d '=' -f 2)

			#15269888 is from emmc datasheet, sec_count in Extended CSD is 0xe90000 = 15269888.
                        [ x"${FLASH_TOTAL_SECTORS}" = x"" ] && {
                                LOGW "flash_total_sectors not set in programmer_img.cfg"
                                FLASH_TOTAL_SECTORS=15269888
                        }

                        [ x"${LOGIC_OFFSET}" = x"" ] && {
                                LOGW "logic_offset not set in programmer_img.cfg"
                                LOGIC_OFFSET=40960
                        }
                        wrapper_run_logd update_mbr sys_partition.bin 4 sunxi_mbr.fex dlinfo.fex ${FLASH_TOTAL_SECTORS} ${LOGIC_OFFSET} 0
                else
                        wrapper_run_logd update_mbr sys_partition.bin 4 sunxi_mbr.fex dlinfo.fex 61079552 40960 0
                fi
                if [ $? -ne 0 ]; then
                        LOGF "update_mbr_gpt failed"
                fi
        fi

        if [ x"${PACK_PLATFORM}" = x"openwrt" ]; then
                LOGD "===================================="
                LOGD "show sys_partition.fex message"
                show_partition_message sys_partition.fex
        fi

	local e cfgadd cfgget lastcfgline localfile filename
        local imgcfg_add_list=(
                # localfile             filename-in-cfg        maintype  subtype
                'vmlinux.fex            vmlinux.fex            12345678  123456789VMLINUX'
                'vendor_boot-debug.fex  vendor_boot-debug.fex  RFSFAT16  VENDOR_BOOTDEBUG'
                'dragon_toc.cfg         dragon_toc.fex         12345678  12345678DGTOCCFG'
                )

        for e in "${imgcfg_add_list[@]}"; do
                localfile="$(awk '{print $1}' <<< $e)"
                filename="$(awk '{print $2}' <<< $e)"
                maintype="$(awk '{print $3}' <<< $e)"
                subtype="$(awk '{print $4}' <<< $e)"
                cfgget="$(sed -n '/^\s*{\s*filename\s*=\s*"'$filename'"\s*,/p' image.cfg)"
                lastcfgline="$(sed -n '/^\s*{\s*filename\s*=/=' image.cfg | tail -1)"

                [ ! -f "$localfile" -o -n "$cfgget" -o -z "$lastcfgline" ] && continue
                [ "$localfile" != "$filename" ] && ln -sf $localfile $filename
                cfgadd='    {filename = "'$filename'",'
                cfgadd+='     maintype = "'$maintype'",'
                cfgadd+='     subtype  = "'$subtype'",},'
                sed -i -e  ''"${lastcfgline}"'a\' -e "$cfgadd" image.cfg
        done

        wrapper_run_logd dragon image.cfg    sys_partition.fex
        if [ $? -ne 0 ]; then
                LOGF "pack fail"
        fi

        if [ -e ${IMG_NAME} ]; then
                imagesize=$(du --apparent-size -sh ${IMG_NAME} | awk '{print $1}')
                LOGD '----------image is at----------'
                LOGI "$imagesize\t${IMG_NAME}"
        fi
        cd ..
	if [ "x${PACK_PROGRAMMER}" = "xprogrammer" ]; then
                if [ -f  $PACK_OUT_DIR/super.fex ]; then
                        mv $PACK_OUT_DIR/super.fex $PACK_OUT_DIR/super.bak.fex
                        simg2img  $PACK_OUT_DIR/super.bak.fex $PACK_OUT_DIR/super.fex
                fi
                LOGD "waiting to ceate programmer img..."
                img_to_programmer ${IMG_PROGRAMMER_NAME} $LICHEE_OUT_DIR/${LICHEE_IC}/${LICHEE_BOARD}/${LICHEE_LINUX_DEV}/${IMG_NAME}
                if [ $? -eq 0 ]; then
                        if [ -e ${IMG_PROGRAMMER_NAME} ]; then
                                mv $PACK_OUT_DIR/${IMG_PROGRAMMER_NAME} $LICHEE_OUT_DIR/${LICHEE_IC}/${LICHEE_BOARD}/${LICHEE_LINUX_DEV}/${IMG_PROGRAMMER_NAME}
                                rm -f $LICHEE_OUT_DIR/${IMG_PROGRAMMER_NAME}
                                ln -f $LICHEE_OUT_DIR/$LICHEE_IC/$LICHEE_BOARD/$LICHEE_LINUX_DEV/${IMG_PROGRAMMER_NAME}  $LICHEE_OUT_DIR/${IMG_PROGRAMMER_NAME}
                                imagesize=$(du --apparent-size -sh $LICHEE_OUT_DIR/${LICHEE_IC}/${LICHEE_BOARD}/${LICHEE_LINUX_DEV}/${IMG_PROGRAMMER_NAME} | awk '{print $1}')
                                LOGD '----------programmer image is at----------'
                                LOGI "$imagesize\t${LICHEE_OUT_DIR}/${IMG_PROGRAMMER_NAME}"
                        fi
                fi
        fi
        cd ..
        
	LOGD "pack finish\n"
        return 0
}

function get_realpath()
{
        local src=$(cd $1; pwd);
        local dst=$(cd $2; pwd);
        local res="./";
        local tmp="$dst"

        while [ "${src##*$tmp}" == "${src}" ]; do
                tmp=${tmp%/*};
                res=$res"../"
        done
        res="$res${src#*$tmp/}"

        printf "%s" $res
}

function do_pack_linux()
{
        local link_real=$(get_realpath ${PLAT_OUT} ./)
        local recovery_path=${link_real}/recovery.img

        LOGD "packing for linux"

        [ -f kernel.itb ] && mv kernel.itb   kernel.fex
        [ -f kernel-dtb.itb ] && mv kernel-dtb.itb   kernel-dtb.fex
	ln -sf kernel.fex boot.fex
                
        ln -sf ${link_real}/rootfs.ext4     rootfs.fex

        ln -sf ${link_real}/rootfs.ubifs     rootfs-ubifs.fex

        if [ -f "$recovery_path" ]; then
                ln -sf ${recovery_path}     recovery.fex
        fi

}

function generate_env_for_uboot()
{
        # u_boot_env_gen env_nor.cfg env_nor.fex >/dev/null
        u_boot_env_gen $1 $2 >/dev/null
}

function maybe_busybox()
{
        if [ "x$(which busybox)" == "x" ]; then
                LOGF "Tool busybox does not exist!"
        fi

        busybox $@ || $@
}

function do_common()
{
        cd ${PACK_OUT_DIR}/

        echo $(date +"%Y-%m-%d %H:%M:%S") > ${PACK_OUT_DIR}/sunxi_version.fex

        # Here, we can switch uart to card or normal
        if [ "x${PACK_DEBUG}" = "xcard0" -a "x${PACK_MODE}" != "xdump" \
                -a "x${PACK_FUNC}" != "xprvt" ] ; then \
                uart_switch
        else
                sed -i -e '/^auto_print_used/s\1\0\' ${PACK_OUT_DIR}/sys_config.fex
        fi

        if [ "x${PACK_SECURE}" = "xsecure" ]; then
                LOGD "Add secure configs to 'sys_config.fex'"
                # Add 'burn_secure_mode=1' in `[target]` section
                sed -i -e '/^\[target\]/a\burn_secure_mode=1' ${PACK_OUT_DIR}/sys_config.fex
                # Add 'secure_without_OS=0' in `[platform]` section
                sed -i -e '/^\[platform\]/a\secure_without_OS=0' ${PACK_OUT_DIR}/sys_config.fex
                rm -f ${PACK_OUT_DIR}/optee-monitor.fex
        else
                sed -i '/^burn_secure_mod/d' ${PACK_OUT_DIR}/sys_config.fex
                sed -i '/^secure_without_OS/d' ${PACK_OUT_DIR}/sys_config.fex
                if [ -f ${PACK_OUT_DIR}/optee-monitor.fex ]; then
                        mv -v ${PACK_OUT_DIR}/optee-monitor.fex ${PACK_OUT_DIR}/optee.fex
                fi
        fi

        if [ ! -f board_config.fex ]; then
                echo "[empty]" > board_config.fex
        fi
	maybe_busybox unix2dos sys_config.fex
        maybe_busybox unix2dos board_config.fex
        script  sys_config.fex > /dev/null
        cp -f   sys_config.bin config.fex
        script  board_config.fex > /dev/null
        cp -f board_config.bin board.fex

        maybe_busybox unix2dos sys_partition.fex
        script  sys_partition.fex > /dev/null


        if [ "x${PACK_TYPE}" = "xdragonboard" ] ; then
                maybe_busybox dos2unix test_config.fex
                cp test_config.fex boot-resource/
                maybe_busybox unix2dos test_config.fex
                script test_config.fex > /dev/null
                cp test_config.bin boot-resource/
        fi

        if [ "x${PACK_TYPE}" = "xdragonabts" ] ; then
                maybe_busybox dos2unix test_config.fex
                cp test_config.fex boot-resource/
                maybe_busybox unix2dos test_config.fex
                script test_config.fex > /dev/null
                cp test_config.bin boot-resource/
        fi

	# Those files for SpiNor. We will try to find sys_partition_nor.fex
        if [ "x${PACK_NOR}" = "xnor" ] ; then

                if [ ! -f sys_partition_nor.fex ];  then
                        LOGF "sys partition for nor not exist"
                fi

                if [ ! -f ${CHIP_CONFIG_DIR}/tools/arisc_config_parse.sh ]; then
                        if [ -f "scp.fex" ]; then
                                LOGD "update scp"
                                update_scp scp.fex sunxi.fex >/dev/null
                        fi
                fi

                # Here, will create sys_partition_nor.bin
                maybe_busybox unix2dos sys_partition_nor.fex
                script  sys_partition_nor.fex > /dev/null

                if [ "x${BRANDY_SPL_VER}" != "xv2" ]; then
                        update_boot0 boot0_spinor.fex   sys_config.bin SPINOR_FLASH > /dev/null
                        update_chip boot0_spinor.fex   > /dev/null
                        update_fes1  fes1.fex           sys_config.bin > /dev/null
                        if [ -f pmboot_spinor.fex ]; then
                                LOGD "update pmboot_spinor.fex"
                                update_boot0 pmboot_spinor.fex sys_config.bin SPINOR_FLASH > /dev/null
                        fi
                fi

                if [ "x${PACK_KERN}" = "xlinux-3.4" ] ; then
                        update_uboot -merge u-boot-spinor.fex  sys_config.bin > /dev/null
                else
                        update_uboot -no_merge u-boot-spinor.fex  sys_config.bin > /dev/null
                        update_uboot -no_merge u-boot-spinor-secure.fex  sys_config.bin > /dev/null
                        [ -f u-boot-efex.fex ] && {
                                update_uboot -no_merge u-boot-efex.fex  sys_config.bin > /dev/null
                        }
                fi

		 while read line
                do
                        compress_name=(`echo $line | awk '($1 !~ ";" && ($2 ~ "lzma" || $2 ~ "lz4" || $2 ~ "gz")) {print $2}'`)
                        source_name=(`echo $compress_name | cut -d \.  -f 1,2 | cut -d \  -f 2`)
                        compress_type=(`echo $compress_name | cut -d \.  -f 3 | cut -d \  -f 2`)
                        [ -z "$compress_name" ] && continue
                        case $compress_type in
                        "gz")
                                [ -f $source_name ] && gzip -c $source_name > $compress_name || LOGE "no exist $source_name"
                                LOGD "compress name: $compress_name"
                                ;;
                        "lzma")
                                [ -f $source_name ] && lzma -k $source_name || LOGE "no exist $source_name"
                                mv $source_name.lzma $compress_name >/dev/null 2<&1
                                LOGD "compress name: $compress_name"
                                ;;
                        "lz4")
                                [ -f $source_name ] && lz4 -f $source_name $compress_name || LOGD "no exist $source_name"
                                LOGD "compress name: $compress_name"
                                ;;
                        *)
                                LOGE "no match compress type"
                                ;;
                        esac
                        LOGD "compress type: $compress_type"
                done < boot_package_nor.cfg

                if [ -f boot_package_nor.cfg ]; then
                        mv u-boot-spinor-crash.fex u-boot-crash.fex
                        LOGD "pack boot package"
                        maybe_busybox unix2dos boot_package_nor.cfg
                        wrapper_run_logd dragonsecboot -pack boot_package_nor.cfg
                        cp boot_package.fex boot_package_nor.fex
                fi

		# Ugly, but I don't have a better way to change it.
                # We just set env's downloadfile name to env_nor.cfg in sys_partition_nor.fex
                # And if env_nor.cfg is not exist, we should copy one.
                if [ ! -f env_nor.cfg ]; then
                        cp -f env.cfg env_nor.cfg >/dev/null 2<&1
                fi

                #card sprite
                if [ "x${BRANDY_SPL_VER}" != "xv2" ]; then
                        if [ -f "boot0_sdcard.fex" ]; then
                                update_boot0 boot0_sdcard.fex   sys_config.bin SDMMC_CARD > /dev/null
                                update_chip boot0_sdcard.fex > /dev/null
                        fi
                fi

                # Fixup boot mode for SPINor, just can bootm
                sed -i '/^boot_normal/s#\<boota\>#bootm#g' env_nor.cfg

                LOGD "1:REDUNDANT_ENV_SIZE:$REDUNDANT_ENV_SIZE"
                if [ "x${REDUNDANT_ENV_SIZE}" != "x" ]  || [ "x${ONE_ENV_SIZE}" != "x" ]; then
                        generate_env_use_mkenvimage env_nor.cfg env_nor.fex ${REDUNDANT_ENV_SIZE}
                else
                        generate_env_for_uboot env_nor.cfg env_nor.fex
                fi
        else
                if [ "x${BRANDY_SPL_VER}" != "xv2" ]; then
                        if [ -f "boot0_spinor.fex" ]; then
                                update_boot0 boot0_spinor.fex   sys_config.bin SPINOR_FLASH > /dev/null
                                update_chip boot0_spinor.fex   > /dev/null
                        fi
                        update_boot0 boot0_nand.fex     sys_config.bin NAND > /dev/null
                        update_boot0 boot0_sdcard.fex   sys_config.bin SDMMC_CARD > /dev/null
                        update_boot0 boot0_ufs.fex   sys_config.bin UFS > /dev/null
                        update_chip boot0_nand.fex >/dev/null
                        update_chip boot0_sdcard.fex >/dev/null
                        update_chip boot0_ufs.fex >/dev/null
                        if [ -f boot0_offline_secure.fex ]; then
                                LOGD "update boot0_offline_secure.fex"
                                update_boot0 boot0_offline_secure.fex sys_config.bin SDMMC_CARD > /dev/null
                        fi
                        if [ -f pmboot_nand.fex ]; then
                                LOGD "update pmboot_nand.fex"
                                update_boot0 pmboot_nand.fex sys_config.bin NAND > /dev/null
                        fi
                        if [ -f pmboot_sdcard.fex ]; then
                                LOGD "update pmboot_sdcard.fex"
                                update_boot0 pmboot_sdcard.fex sys_config.bin SDMMC_CARD > /dev/null
                        fi
                fi
        fi

        if [ ! -f "u-boot-crash.fex" ]; then
                touch "u-boot-crash.fex"
                echo "ensure u-boot-crash.fex is not empty" > u-boot-crash.fex
        fi

        if [ -f "sunxi.fex" ]; then
                update_dtb sunxi.fex 4096
        fi

	if [ ! -f ${CHIP_CONFIG_DIR}/tools/arisc_config_parse.sh ]; then
                if [ -f "scp.fex" ]; then
                        LOGD "update scp"
                        update_scp scp.fex sunxi.fex >/dev/null
                fi
        fi

        if [ -f "optee.fex" ]; then
                LOGD "update optee"
                update_optee optee.fex sunxi.fex >/dev/null
        fi

        # Those files for Nand or Card
        if [ "x${PACK_KERN}" = "xlinux-3.4" ] ; then
                update_uboot -merge u-boot.fex sys_config.bin > /dev/null
        else
                update_uboot -no_merge u-boot.fex sys_config.bin > /dev/null
                [ -f u-boot-nodtb.fex ] && {
                        update_uboot -no_merge u-boot-nodtb.fex sys_config.bin > /dev/null
                }
                [ -f u-boot-efex.fex ] && {
                        update_uboot -no_merge u-boot-efex.fex  sys_config.bin > /dev/null
                }
        fi

        if [ "x${BRANDY_SPL_VER}" != "xv2" ]; then
                if [ -f "fes1_uart.fex" ]; then
                        update_fes1  fes1_uart.fex           sys_config.bin > /dev/null
                fi

                wrapper_run_logd update_fes1  fes1.fex           sys_config.bin > /dev/null
        fi

	if [ -f ${TOOLS_DIR}/mod_update/update_sboot ];then
                if [ "x${BRANDY_SPL_VER}" != "xv2" ]; then
                        wrapper_run_logd update_sboot sboot.bin  sys_config.bin  > /dev/null
                fi
                if [ $? -ne 0 ]; then
                        LOGF "update sboot run error"
                fi
        fi
        wrapper_run_logd fsbuild      boot-resource.ini  split_xxxx.fex > /dev/null

        if [ -f Reserve0.ini ]; then
                sed -i 's/\\Reserve0/\/Reserve0/g' ${PACK_OUT_DIR}/Reserve0.ini
                wrapper_run_logd fsbuild      Reserve0.ini       split_xxxx.fex > /dev/null
        fi

        if [ -f boot_package_uartburn.cfg ]; then
                wrapper_run_logd dragonsecboot -pack boot_package_uartburn.cfg
                if [ $? -ne 0 ]; then
                        LOGF "dragon pack boot_package_uartburn run error"
                fi
                mv boot_package.fex boot_package_uartburn.fex
        fi

	if [ -f boot_package.cfg ]; then
                if [ "x$LINUX_DTBO_FILE" = "x" ]; then
                        LOGD "do not set LINUX_DTBO_FILE"
                        line_num=`sed -n -e "/default.dtbo/=" boot_package.cfg`
                        if [ "x$line_num" != "x" ]; then
                                sed -i "$line_num s/^/;/g" boot_package.cfg
                        fi
                else
                        if [ -f $LINUX_DTBO_FILE ]; then
                                sed -i "s/default.dtbo/$LINUX_DTBO_FILE/g" boot_package.cfg
                        else
                                line_num=`sed -n -e "/default.dtbo/=" boot_package.cfg`
                                if [ "x$line_num" != "x" ]; then
                                        sed -i "$line_num s/^/;/g" boot_package.cfg
                                fi
                        fi
                fi

                LOGD "pack boot package"
                wrapper_run_logd maybe_busybox unix2dos boot_package.cfg
                wrapper_run_logd dragonsecboot -pack boot_package.cfg

                if [ $? -ne 0 ]; then
                        LOGF "dragon pack run error"
                fi
        fi

	LOGD "2:REDUNDANT_ENV_SIZE:$REDUNDANT_ENV_SIZE"
        if [ "x${PACK_FUNC}" = "xprvt" ] ; then
                if [ "x${REDUNDANT_ENV_SIZE}" != "x" ] || [ "x${ONE_ENV_SIZE}" != "x" ]; then
                        generate_env_use_mkenvimage env_burn.cfg env.fex ${REDUNDANT_ENV_SIZE}
                else
                        generate_env_for_uboot env_burn.cfg env.fex
                fi
        else
                if [ "x${REDUNDANT_ENV_SIZE}" != "x" ] || [ "x${ONE_ENV_SIZE}" != "x" ] ; then
                        generate_env_use_mkenvimage env.cfg env.fex ${REDUNDANT_ENV_SIZE}
                else
                        generate_env_for_uboot env.cfg env.fex
                fi
        fi
}

function uboot_ini_to_dts()
{
        local TARGET_UBOOT
        local PLATFORM_ADDR
        local SOC_ADDR
        local DTC_FLAGS=""
        local DTC_COMPILER=dtc

        if [ x${BRANDY_UBOOT_VER} == x2023 ]; then
                LOGI "skip split fdt"
                return
        fi

        if [ "x${PACK_NOR}" == "xnor" ]; then
                TARGET_UBOOT=${PACK_OUT_DIR}/u-boot-spinor.fex
        else
                TARGET_UBOOT=${PACK_OUT_DIR}/u-boot.fex
        fi
        sunxi_ubootools split ${TARGET_UBOOT} > /dev/null
        if [ $? -ne 0 ]; then
                LOGW "split uboot and fdt failed!!"
                return
        fi

        [ "$(readlink -f .)" != "$(readlink -f ${PACK_OUT_DIR})" ] && {
                mv temp_fdt.dtb  ${PACK_OUT_DIR}
                mv temp_ubootnodtb.bin  ${PACK_OUT_DIR}
        }

        # to dts
        $DTC_COMPILER ${DTC_FLAGS} -I dtb -O dts -o ${PACK_OUT_DIR}/.uboot.dtb.dts.tmp ${PACK_OUT_DIR}/temp_fdt.dtb  2>/dev/null

	PLATFORM_ADDR=`grep -Po "(?<=platform@)(\w+)(?=\s*{)" ${PACK_OUT_DIR}/.uboot.dtb.dts.tmp | head -1`
        SOC_ADDR=`grep -Po "(?<=soc@)(\w+)(?=\s*{)" ${PACK_OUT_DIR}/.uboot.dtb.dts.tmp | head -1`

        if [ "x${PACK_TYPE}" = "xdragonboard" -o "x${PACK_TYPE}" = "xdragonabts" ] ; then
                LOGI "PACK TYPE dragonboard or dragonabts"
		cat <<- EOF >> ${PACK_OUT_DIR}/.uboot.dtb.dts.tmp
		/{
			soc@${SOC_ADDR} {
				platform@${PLATFORM_ADDR} {
				dragonboard_test = <1>;
				};
			};
		};
		EOF
        fi

        # to dtb
        $DTC_COMPILER ${DTC_FLAGS} -I dts -O dtb -o ${PACK_OUT_DIR}/temp_fdt.dtb ${PACK_OUT_DIR}/.uboot.dtb.dts.tmp  2>/dev/null

        # get update_to_ubootfdt value from sysconfig
        sunxi_ubootools subkey_value sys_config.bin sunxi_ubootools update_to_ubootfdt > /dev/null
        if [ $? -eq 1 ]; then
                LOGD "uboot ini to dts"
                $DTC_COMPILER -p 2048 ${DTC_FLAGS} -@ -O dtb -o ${PACK_OUT_DIR}/new_fdt.dtb      \
                        -b 0                    \
                        -i ${PACK_OUT_DIR}       \
                        -F $DTC_INI_FILE \
                        -d ${PACK_OUT_DIR}/temp_fdt.dtb ${PACK_OUT_DIR}/.uboot.dtb.dts.tmp 2>/dev/null
        else
                mv ${PACK_OUT_DIR}/temp_fdt.dtb  ${PACK_OUT_DIR}/new_fdt.dtb
        fi

	sunxi_ubootools merge ${PACK_OUT_DIR}/temp_ubootnodtb.bin ${PACK_OUT_DIR}/new_fdt.dtb > /dev/null
        cp -f ${PACK_OUT_DIR}/temp_ubootnodtb.bin ${TARGET_UBOOT}
        # .uboot.dts is the last dts of uboot
        $DTC_COMPILER ${DTC_FLAGS} -I dtb -O dts -o ${PACK_OUT_DIR}/.uboot.dts ${PACK_OUT_DIR}/new_fdt.dtb 2>/dev/null
}

function do_ini_to_dts()
{
        cd ${PACK_OUT_DIR}/

        busybox unix2dos sys_config.fex
        script sys_config.fex > /dev/null

	local DTC_SRC_PATH=${PLAT_OUT}
        local DTC_COMPILER=${PLAT_OUT}/dtc
        local DTC_FLAGS=""
	
        uboot_ini_to_dts

        if [ "x${PACK_KERN}" == "xlinux-3.4" \
                        -o "x${PACK_KERN}" == "xlinux-3.10" \
                        -o "x${PACK_KERN}" == "xlinux-4.4" \
                        -o "x${PACK_KERN}" == "xlinux-5.4" \
                        -o "x${PACK_KERN}" == "xlinux-5.4-ansc" \
                        -o "x${PACK_KERN}" == "xlinux-5.10" \
                        -o "x${PACK_KERN}" == "xlinux-5.10-rt" \
                        -o "x${PACK_KERN}" == "xlinux-5.10-origin" \
                        -o "x${PACK_KERN}" == "xlinux-5.10-xenomai" \
                        -o "x${PACK_KERN}" == "xlinux-5.10-euler" \
                        -o "x${PACK_KERN}" == "xlinux-5.15" \
                        -o "x${PACK_KERN}" == "xlinux-5.15-origin" ] || [[  ${PACK_KERN/linux-} > 5.15 ]]; then
                # For debug: sunxi.dtb -> .sunxi.dts
                $DTC_COMPILER ${DTC_FLAGS} -I dtb -O dts -o ${PLAT_OUT}/.sunxi.dts ${PLAT_OUT}/sunxi.dtb 2>/dev/null
                return
        fi
local dtc_file_list=(
                .board.dtb.d.dtc.tmp:.board.dtb.dts.tmp
                .${PACK_CHIP}-${PACK_BOARD}.dtb.d.dtc.tmp:.${PACK_CHIP}-${PACK_BOARD}.dtb.dts.tmp
                .${PACK_CHIP}-${BUSSINESS}.dtb.d.dtc.tmp:.${PACK_CHIP}-${BUSSINESS}.dtb.dts.tmp
                .${PACK_CHIP}-soc.dtb.d.dtc.tmp:.${PACK_CHIP}-soc.dtb.dts.tmp)

        local DTC_INI_FILE_BASE=${PACK_OUT_DIR}/sys_config.fex
        local DTC_INI_FILE=${PACK_OUT_DIR}/sys_config_fix.fex

        cp $DTC_INI_FILE_BASE $DTC_INI_FILE
        sed -i "s/\(\[dram\)_para\(\]\)/\1\2/g" $DTC_INI_FILE
        sed -i "s/\(\[nand[0-9]\)_para\(\]\)/\1\2/g" $DTC_INI_FILE

        if [ ! -f $DTC_COMPILER ]; then
                LOGF "Script_to_dts: Can not find dtc compiler.\n"
        fi

        local DTC_DEP_FILE DTC_SRC_FILE
        for e in ${dtc_file_list[@]}; do
                DTC_DEP_FILE=$DTC_SRC_PATH/${e/:*}
                if [ -f $DTC_DEP_FILE ]; then
                        DTC_SRC_FILE=$DTC_SRC_PATH/${e#*:}
                        break
                fi
        done

        LOGD "sunxi_dtb create"
        $DTC_COMPILER -p 2048 ${DTC_FLAGS} -@ -O dtb -o ${PLAT_OUT}/sunxi.dtb    \
                -b 0                    \
                -i $DTC_SRC_PATH        \
                -F $DTC_INI_FILE        \
                -d $DTC_DEP_FILE $DTC_SRC_FILE 2>/dev/null

        if [ $? -ne 0 ]; then
                LOGF "Conver script to dts failed"
        fi

        LOGD "Conver script to dts ok."

        # It'is used for debug dtb
        $DTC_COMPILER ${DTC_FLAGS} -I dtb -O dts -o ${PLAT_OUT}/.sunxi.dts ${PLAT_OUT}/sunxi.dtb 2>/dev/null
        return
}

function main()
{
	do_ini_to_dts
	do_common
	do_pack_linux
	do_finish
	return $?
}

main "$@"
