meta-nuvoton: npcm8xx-bootloader: initial recipe

Add new recipe npcm8xx-bootloader to replace npcm8xx-igps-native, and
also remove relative merge/sign functions and settings.

Tested:
TIP/No TIP/SA boot OK.
Settings replace function work, hardening replace work.

Change-Id: I1db20b483cf1de72ce05ca2a14df0a75fdb37d36
Signed-off-by: Brian Ma <chma0@nuvoton.com>
diff --git a/meta-nuvoton/conf/machine/evb-npcm845.conf b/meta-nuvoton/conf/machine/evb-npcm845.conf
index 92641ab..b6a4778 100644
--- a/meta-nuvoton/conf/machine/evb-npcm845.conf
+++ b/meta-nuvoton/conf/machine/evb-npcm845.conf
@@ -18,8 +18,6 @@
 FLASH_ROFS_OFFSET:flash-65536 = "12288"
 FLASH_RWFS_OFFSET:flash-65536 = "61440"
 
-BB_ALIGN = "524288"
-
 IMAGE_FSTYPES += "cpio.${INITRAMFS_CTYPE}.u-boot"
 IMAGE_FSTYPES += "${@bb.utils.contains('DISTRO_FEATURES', \
         'phosphor-mmc', \
diff --git a/meta-nuvoton/conf/machine/include/igps-keys.inc b/meta-nuvoton/conf/machine/include/igps-keys.inc
deleted file mode 100644
index dcc5f7c..0000000
--- a/meta-nuvoton/conf/machine/include/igps-keys.inc
+++ /dev/null
@@ -1,20 +0,0 @@
-# There are two valid types: "openssl" or "HSM".
-# Currently, default support openssl only.
-SIGN_TYPE ?= "openssl"
-
-KEY_BB_INDEX ?= "1"
-SKMT_BL31_KEY_INDEX ?= "1"
-SKMT_BL32_KEY_INDEX ?= "1"
-SKMT_BL33_KEY_INDEX ?= "1"
-
-KEY_BB_ID ?= "11"
-KEY_BL31_ID ?= "11"
-KEY_OPTEE_ID ?= "11"
-KEY_UBOOT_ID ?= "11"
-
-KEY_FOLDER ?= ""
-KEY_FOLDER_DEFAULT ?= "${DEPLOY_DIR_IMAGE}/${SIGN_TYPE}"
-KEY_BB ?= "skmt_ecc_key_1.der"
-KEY_BL31 ?= "skmt_ecc_key_1.der"
-KEY_OPTEE ?= "skmt_ecc_key_1.der"
-KEY_UBOOT ?= "skmt_ecc_key_1.der"
diff --git a/meta-nuvoton/conf/machine/include/npcm8xx.inc b/meta-nuvoton/conf/machine/include/npcm8xx.inc
index 218b81f..84f4bdf 100644
--- a/meta-nuvoton/conf/machine/include/npcm8xx.inc
+++ b/meta-nuvoton/conf/machine/include/npcm8xx.inc
@@ -3,7 +3,6 @@
 #@DESCRIPTION: Common machine configuration for Nuvoton NPCM8XX Chip
 
 require conf/machine/include/nuvoton.inc
-require conf/machine/include/igps-keys.inc
 
 KERNEL_IMAGETYPE ?= "Image"
 
@@ -29,14 +28,6 @@
 
 SERIAL_CONSOLES ?= "115200;ttyS0"
 
-BB_ALIGN ?= "524288"
-ATF_ALIGN ?= "4096"
-OPTEE_ALIGN ?= "4096"
-UBOOT_ALIGN ?= "4096"
-ALIGN_END ?= "4096"
-PAD_ALIGN ?= "32"
-SA_ALIGN ?= "524288"
-
 SOC_FAMILY = "npcm8xx"
 include conf/machine/include/soc-family.inc
 MACHINEOVERRIDES .= ":npcm8xx"
@@ -57,8 +48,6 @@
 
 OPTEEMACHINE ?= "nuvoton"
 
-SECURED_IMAGE ?= "True"
-
 TIP_IMAGE ?= "True"
 
 SA_TIP_IMAGE ?= "False"
diff --git a/meta-nuvoton/recipes-bsp/images/npcm8xx-bootloader/settings.json b/meta-nuvoton/recipes-bsp/images/npcm8xx-bootloader/settings.json
new file mode 100644
index 0000000..8a741dc
--- /dev/null
+++ b/meta-nuvoton/recipes-bsp/images/npcm8xx-bootloader/settings.json
@@ -0,0 +1,13 @@
+{
+    "BootBlockAndHeader.xml":
+    {
+        "MC_CONFIG": "0x04"
+    },
+    "key_setting_edit_me.py":
+    {
+        "COMBO1_OFFSET": "2048*1024"
+    },
+    "BootBlockAndHeader_no_tip.xml":
+    {
+    }
+}
diff --git a/meta-nuvoton/recipes-bsp/images/npcm8xx-bootloader_0.1.0.bb b/meta-nuvoton/recipes-bsp/images/npcm8xx-bootloader_0.1.0.bb
new file mode 100644
index 0000000..69ceeae
--- /dev/null
+++ b/meta-nuvoton/recipes-bsp/images/npcm8xx-bootloader_0.1.0.bb
@@ -0,0 +1,92 @@
+SUMMARY = "Nuvoton NPCM8XX bootloader"
+DESCRIPTION = "This is front end recipe for NPCM8XX IGPS. It replace \
+original IGPS recipe which need implement many redundant function in \
+recipe or class. After we add some hook in IGPS, now we can generate \
+full bootbloader by IGPS script. We only need collect all built images \
+from deploy folder, put them to IGPS input folder, and run script."
+HOMEPAGE = "https://github.com/Nuvoton-Israel/igps-npcm8xx"
+LICENSE = "GPL-2.0-only"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=b234ee4d69f5fce4486a80fdaf4a4263"
+
+IGPS_BRANCH ?= "main"
+SRC_URI = " \
+    git://github.com/Nuvoton-Israel/igps-npcm8xx;branch=${IGPS_BRANCH};protocol=https \
+"
+SRCREV = "518d3f58f4f157373a5b1aaebaf22f80bb13d0d9"
+
+S = "${WORKDIR}/git"
+
+DEPENDS = " \
+    npcm8xx-tip-fw npcm8xx-bootblock trusted-firmware-a optee-os \
+    u-boot-nuvoton npcm7xx-bingo-native openssl-native \
+"
+inherit obmc-phosphor-utils
+inherit python3native deploy
+FILE_FMT = "file://{}"
+
+# Sign keys, replace them for production
+IGPS_KEYS = ""
+# Configuration files, clean them if no need
+IGPS_CSVS = ""
+IGPS_SETTINGS = "settings.json"
+IGPS_CONFS = "${IGPS_KEYS} ${IGPS_CSVS} ${IGPS_SETTINGS}"
+SRC_URI += "${@compose_list(d, 'FILE_FMT', 'IGPS_CONFS')}"
+
+IGPS_SCRIPT_BASE = "${S}/py_scripts/ImageGeneration"
+BB_BIN = "arbel_a35_bootblock"
+BB_BIN .= "${@'_no_tip.bin' if d.getVar("TIP_IMAGE") != 'True' else '.bin'}"
+
+do_configure[dirs] = "${WORKDIR}"
+do_configure() {
+    KEY_FOLDER=${IGPS_SCRIPT_BASE}/keys/openssl
+    CSV_FOLDER=${IGPS_SCRIPT_BASE}/inputs/registers
+    # keys
+    install -d ${KEY_FOLDER}
+    if [ -n "${IGPS_KEYS}" ];then
+        cp -v ${IGPS_KEYS} ${KEY_FOLDER}
+    fi
+
+    # csv files
+    install -d ${CSV_FOLDER}
+    if [ -n "${IGPS_CSVS}" ];then
+        cp -v ${IGPS_CSVS} ${CSV_FOLDER}
+    fi
+
+    # change customized settings for XML and key setting
+    if [ -n "${IGPS_SETTINGS}" ];then
+        cd ${S}
+        python3 ${IGPS_SCRIPT_BASE}/config_replacer.py ${WORKDIR}/${IGPS_SETTINGS}
+    fi
+}
+
+do_compile() {
+    # copy Openbmc built images
+    cd ${DEPLOY_DIR_IMAGE}
+    cp -v ${BB_BIN} bl31.bin tee.bin u-boot.bin ${IGPS_SCRIPT_BASE}/inputs
+
+    cd ${IGPS_SCRIPT_BASE}
+    install -d output_binaries/tmp
+    install -d inputs/key_input
+    if [ "${TIP_IMAGE}" = "True" ] || [ "${SA_TIP_IMAGE}" = "True" ];then
+      # Do not sign combo0 image again
+      python3 ${S}/py_scripts/GenerateAll.py openssl ${DEPLOY_DIR_IMAGE}
+    else
+      # for No TIP, we can run IGPS script directly
+      python3 ${S}/py_scripts/GenerateAll.py openssl
+    fi
+}
+
+do_deploy() {
+    OUT=${IGPS_SCRIPT_BASE}/output_binaries
+    BOOTLOADER=u-boot.bin.merged
+    install -d ${DEPLOYDIR}
+    if [ "${SA_TIP_IMAGE}" = "True" ];then
+        install -m 644 ${OUT}/Secure/image_no_tip_SA.bin ${DEPLOYDIR}/${BOOTLOADER}
+    elif [ "${TIP_IMAGE}" = "True" ];then
+        install -m 644 ${OUT}/Secure/Kmt_TipFwL0_Skmt_TipFwL1_BootBlock_BL31_Tee_uboot.bin ${DEPLOYDIR}/${BOOTLOADER}
+    else
+        install -m 644 ${OUT}/Basic/image_no_tip.bin ${DEPLOYDIR}/${BOOTLOADER}
+    fi
+}
+addtask deploy before do_build after do_compile
+PACKAGE_ARCH = "${MACHINE_ARCH}"
diff --git a/meta-nuvoton/recipes-bsp/images/npcm8xx-igps-native_04.01.03.bb b/meta-nuvoton/recipes-bsp/images/npcm8xx-igps-native_04.01.03.bb
deleted file mode 100644
index 78210af..0000000
--- a/meta-nuvoton/recipes-bsp/images/npcm8xx-igps-native_04.01.03.bb
+++ /dev/null
@@ -1,4 +0,0 @@
-# tag IGPS_04.01.03
-SRCREV = "ae5ddb6c8ff350835d411b9e3bfb4443db596067"
-
-require npcm8xx-igps.inc
diff --git a/meta-nuvoton/recipes-bsp/images/npcm8xx-igps.inc b/meta-nuvoton/recipes-bsp/images/npcm8xx-igps.inc
deleted file mode 100644
index 7c043f8..0000000
--- a/meta-nuvoton/recipes-bsp/images/npcm8xx-igps.inc
+++ /dev/null
@@ -1,46 +0,0 @@
-SUMMARY = "Image Generation and Programming Scripts for NPCM8XX (Arbel) devices"
-DESCRIPTION = "Image Generation and Programming Scripts for NPCM8XX (Arbel) devices"
-HOMEPAGE = "https://github.com/Nuvoton-Israel/igps-npcm8xx"
-LICENSE = "GPLv2"
-LIC_FILES_CHKSUM = "file://LICENSE;md5=b234ee4d69f5fce4486a80fdaf4a4263"
-
-IGPS_BRANCH ?= "main"
-SRC_URI = " \
-    git://github.com/Nuvoton-Israel/igps-npcm8xx;branch=${IGPS_BRANCH};protocol=https \
-"
-
-S = "${WORKDIR}/git"
-
-DEST = "${D}${datadir}/${BPN}"
-
-# Adjust paths for use with bitbake
-do_patch() {
-	sed -i -e 's,output_binaries/tmp/,,g' ${S}/py_scripts/ImageGeneration/references/*.xml \
-		${S}/py_scripts/ImageGeneration/inputs/*.xml
-}
-
-do_install() {
-	install -d ${DEST}
-    if [ "${TIP_IMAGE}" = "True" ] ; then
-        install py_scripts/ImageGeneration/references/BootBlockAndHeader_${DEVICE_GEN}_${IGPS_MACHINE}.xml ${DEST}
-	else
-        install py_scripts/ImageGeneration/references/BootBlockAndHeader_${DEVICE_GEN}_${IGPS_MACHINE}_NoTip.xml ${DEST}
-    fi
-	install py_scripts/ImageGeneration/references/UbootHeader_${DEVICE_GEN}.xml ${DEST}
-	install py_scripts/ImageGeneration/inputs/BL31_AndHeader.xml ${DEST}
-	install py_scripts/ImageGeneration/inputs/OpTeeAndHeader.xml ${DEST}
-	install py_scripts/ImageGeneration/asn1.py ${DEST}
-	install py_scripts/ImageGeneration/BinarySignatureGenerator.py ${DEST}
-}
-
-inherit deploy
-
-do_deploy () {
-	# copy default keys to deploy folder
-	install -d ${DEPLOYDIR}
-	cp -vur py_scripts/ImageGeneration/keys/${SIGN_TYPE} ${DEPLOYDIR}/
-}
-
-inherit native
-
-addtask deploy before do_build after do_compile
diff --git a/meta-phosphor/classes/image_types_phosphor_nuvoton_npcm8xx.bbclass b/meta-phosphor/classes/image_types_phosphor_nuvoton_npcm8xx.bbclass
index 56aa082..4d593a0 100644
--- a/meta-phosphor/classes/image_types_phosphor_nuvoton_npcm8xx.bbclass
+++ b/meta-phosphor/classes/image_types_phosphor_nuvoton_npcm8xx.bbclass
@@ -1,291 +1,34 @@
-UBOOT_BINARY := "u-boot.${UBOOT_SUFFIX}"
-BB_HEADER_BINARY := "BootBlockAndHeader.bin"
-BL31_HEADER_BINARY := "bl31AndHeader.bin"
-OPTEE_HEADER_BINARY := "teeAndHeader.bin"
-KMT_TIPFW_BINARY := "Kmt_TipFwL0_Skmt_TipFwL1.bin"
-KMT_TIPFW_BB_BINARY = "Kmt_TipFw_BootBlock.bin"
-KMT_TIPFW_BB_BL31_BINARY = "Kmt_TipFw_BootBlock_BL31.bin"
-KMT_TIPFW_BB_BL31_TEE_BINARY = "Kmt_TipFw_BootBlock_BL31_Tee.bin"
-KMT_TIPFW_BB_UBOOT_BINARY = "u-boot.bin.merged"
-SA_KMT_TIPFW_BINARY := "SA_Kmt_TipFwL0.bin"
-
-BB_BL31_BINARY = "BootBlock_BL31_no_tip.bin"
-BB_BL31_TEE_BINARY = "BootBlock_BL31_Tee_no_tip.bin"
-BB_BL31_TEE_UBOOT_BINARY = "BootBlock_BL31_Tee_Uboot_no_tip.bin"
-BB_BL31_TEE_UBOOT_SA_BINARY = "BootBlock_BL31_Tee_Uboot_no_tip_SA.bin"
-
-FULL_SUFFIX = "full"
 MERGED_SUFFIX = "merged"
 UBOOT_SUFFIX:append = ".${MERGED_SUFFIX}"
-UBOOT_HEADER_BINARY := "${UBOOT_BINARY}.${FULL_SUFFIX}"
-
-IGPS_DIR = "${STAGING_DIR_NATIVE}/${datadir}/npcm8xx-igps"
-
-BB_BIN = "arbel_a35_bootblock.bin"
-BL31_BIN = "bl31.bin"
-OPTEE_BIN = "tee.bin"
-UBOOT_BIN = "u-boot.bin"
-BB_NO_TIP_BIN = "arbel_a35_bootblock_no_tip.bin"
 
 FIT_KERNEL_COMP_ALG:df-obmc-static-norootfs = "gzip"
 FIT_KERNEL_COMP_ALG_EXTENSION:df-obmc-static-norootfs = ".gz"
 
-# Align images if needed
-python do_pad_binary() {
-    TIP_IMAGE = d.getVar('TIP_IMAGE', True)
-    def Pad_bin_file_inplace(inF, align):
-        padding_size = 0
-
-        F_size = os.path.getsize(inF)
-
-        if ((F_size % align) == 0):
-            return
-
-        padding_size = align - (F_size % align)
-
-        infile = open(inF, "ab")
-        infile.seek(0, 2)
-        infile.write(b'\x00' * padding_size)
-        infile.close()
-
-    if TIP_IMAGE == "True":
-        Pad_bin_file_inplace(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True),
-        '%s' % d.getVar('BB_BIN',True)), int(d.getVar('PAD_ALIGN', True)))
-    else:
-        Pad_bin_file_inplace(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True),
-        '%s' % d.getVar('BB_NO_TIP_BIN',True)), int(d.getVar('PAD_ALIGN', True)))
-
-    Pad_bin_file_inplace(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True),
-    '%s' % d.getVar('BL31_BIN',True)), int(d.getVar('PAD_ALIGN', True)))
-
-    Pad_bin_file_inplace(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True),
-    '%s' % d.getVar('OPTEE_BIN',True)), int(d.getVar('PAD_ALIGN', True)))
-
-    Pad_bin_file_inplace(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True),
-        '%s' % d.getVar('UBOOT_BIN',True)), int(d.getVar('PAD_ALIGN', True)))
-}
-
-# Prepare the Bootblock and U-Boot images using npcm8xx-bingo
-do_prepare_bootloaders() {
-    local olddir="$(pwd)"
-    cd ${DEPLOY_DIR_IMAGE}
-
-    bingo ${IGPS_DIR}/BL31_AndHeader.xml \
-            -o ${BL31_HEADER_BINARY}
-
-    bingo ${IGPS_DIR}/OpTeeAndHeader.xml \
-            -o ${OPTEE_HEADER_BINARY}
-
-    if [ "${TIP_IMAGE}" = "True" ]; then
-    bingo ${IGPS_DIR}/BootBlockAndHeader_${DEVICE_GEN}_${IGPS_MACHINE}.xml \
-            -o ${BB_HEADER_BINARY}
-    else
-    bingo ${IGPS_DIR}/BootBlockAndHeader_${DEVICE_GEN}_${IGPS_MACHINE}_NoTip.xml \
-            -o ${BB_HEADER_BINARY}
-    fi
-
-    bingo ${IGPS_DIR}/UbootHeader_${DEVICE_GEN}.xml \
-            -o ${UBOOT_HEADER_BINARY}
-
-    cd "$olddir"
-}
-
-check_keys() {
-    if [ -n "${KEY_FOLDER}" ]; then
-        echo "local"
-    else
-        echo "default"
-    fi
-}
-
-# Sign images for secure os be enabled and TIP mode only
-do_sign_binary() {
-    if [ "${SECURED_IMAGE}" != "True" -o "${TIP_IMAGE}" != "True" ]; then
-       return
-    fi
-    checked=`check_keys`
-    if [ "${checked}" = "local" ]; then
-        bbnote "Sign image with local keys"
-        key_bb=${KEY_FOLDER}/${KEY_BB}
-        key_bl31=${KEY_FOLDER}/${KEY_BL31}
-        key_optee=${KEY_FOLDER}/${KEY_OPTEE}
-        key_uboot=${KEY_FOLDER}/${KEY_UBOOT}
-    else
-        bbnote "Sign image with default keys"
-        key_bb=${KEY_FOLDER_DEFAULT}/${KEY_BB}
-        key_bl31=${KEY_FOLDER_DEFAULT}/${KEY_BL31}
-        key_optee=${KEY_FOLDER_DEFAULT}/${KEY_OPTEE}
-        key_uboot=${KEY_FOLDER_DEFAULT}/${KEY_UBOOT}
-    fi
-    bbnote "BB sign key from ${checked}: ${key_bb}"
-    bbnote "BL31 sign key from ${checked}: ${key_bl31}"
-    bbnote "OPTEE sign key from ${checked}: ${key_optee}"
-    bbnote "UBOOT sign key from ${checked}: ${key_uboot}"
-    # Used to embed the key index inside the image, usually at offset 0x140
-    python3 ${IGPS_DIR}/BinarySignatureGenerator.py Replace_binary_single_byte \
-        ${DEPLOY_DIR_IMAGE}/${BB_HEADER_BINARY} 140 ${KEY_BB_INDEX}
-
-    python3 ${IGPS_DIR}/BinarySignatureGenerator.py Replace_binary_single_byte \
-        ${DEPLOY_DIR_IMAGE}/${BL31_HEADER_BINARY} 140 ${SKMT_BL31_KEY_INDEX}
-
-    python3 ${IGPS_DIR}/BinarySignatureGenerator.py Replace_binary_single_byte \
-        ${DEPLOY_DIR_IMAGE}/${OPTEE_HEADER_BINARY} 140 ${SKMT_BL32_KEY_INDEX}
-
-    python3 ${IGPS_DIR}/BinarySignatureGenerator.py Replace_binary_single_byte \
-        ${DEPLOY_DIR_IMAGE}/${UBOOT_HEADER_BINARY} 140 ${SKMT_BL33_KEY_INDEX}
-
-    # Sign specific image with specific key
-    res=`python3 ${IGPS_DIR}/BinarySignatureGenerator.py Sign_binary \
-        ${DEPLOY_DIR_IMAGE}/${BB_HEADER_BINARY} 112 ${key_bb} 16 \
-        ${DEPLOY_DIR_IMAGE}/${BB_HEADER_BINARY} ${SIGN_TYPE} 0 ${KEY_BB_ID}
-
-        python3 ${IGPS_DIR}/BinarySignatureGenerator.py Sign_binary \
-        ${DEPLOY_DIR_IMAGE}/${BL31_HEADER_BINARY} 112 ${key_bl31} 16 \
-        ${DEPLOY_DIR_IMAGE}/${BL31_HEADER_BINARY} ${SIGN_TYPE} 0 ${KEY_BL31_ID}
-
-        python3 ${IGPS_DIR}/BinarySignatureGenerator.py Sign_binary \
-        ${DEPLOY_DIR_IMAGE}/${OPTEE_HEADER_BINARY} 112 ${key_optee} 16 \
-        ${DEPLOY_DIR_IMAGE}/${OPTEE_HEADER_BINARY} ${SIGN_TYPE} 0 ${KEY_OPTEE_ID}
-
-        python3 ${IGPS_DIR}/BinarySignatureGenerator.py Sign_binary \
-        ${DEPLOY_DIR_IMAGE}/${UBOOT_HEADER_BINARY} 112 ${key_uboot} 16 \
-        ${DEPLOY_DIR_IMAGE}/${UBOOT_HEADER_BINARY} ${SIGN_TYPE} 0 ${KEY_UBOOT_ID}`
-
-    # Stop full image build process when sign binary got failed
-    set +e
-    err=`echo $res | grep -E "missing|Invalid|failed"`
-    if [ -n "${err}" ]; then
-        bbfatal "Sign binary failed: keys are not found or invalid. Please check your KEY_FOLDER and KEY definition."
-    fi
-    set -e
-}
-
-python do_merge_bootloaders() {
-    TIP_IMAGE = d.getVar('TIP_IMAGE', True)
-    SA_TIP_IMAGE = d.getVar('SA_TIP_IMAGE', True)
-    def Merge_bin_files_and_pad(inF1, inF2, outF, align, align_end):
-        padding_size = 0
-        padding_size_end = 0
-        F1_size = os.path.getsize(inF1)
-        F2_size = os.path.getsize(inF2)
-
-        if ((F1_size % align) != 0):
-            padding_size = align - (F1_size % align)
-
-        if ((F2_size % align_end) != 0):
-            padding_size_end = align_end - (F2_size % align_end)
-
-        with open(outF, "wb") as file3:
-            with open(inF1, "rb") as file1:
-                data = file1.read()
-                file3.write(data)
-
-            file3.write(b'\xFF' * padding_size)
-
-            with open(inF2, "rb") as file2:
-                data = file2.read()
-                file3.write(data)
-
-            file3.write(b'\xFF' * padding_size_end)
-
-    if TIP_IMAGE == "True":
-        Merge_bin_files_and_pad(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFW_BINARY',True)),
-        os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('BB_HEADER_BINARY',True)),
-        os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFW_BB_BINARY',True)),
-        int(d.getVar('BB_ALIGN', True)), int(d.getVar('ALIGN_END', True)))
-
-        Merge_bin_files_and_pad(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFW_BB_BINARY',True)),
-        os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('BL31_HEADER_BINARY',True)),
-        os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFW_BB_BL31_BINARY',True)),
-        int(d.getVar('ATF_ALIGN', True)), int(d.getVar('ALIGN_END', True)))
-
-        Merge_bin_files_and_pad(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFW_BB_BL31_BINARY',True)),
-        os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('OPTEE_HEADER_BINARY',True)),
-        os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFW_BB_BL31_TEE_BINARY',True)),
-        int(d.getVar('OPTEE_ALIGN', True)), int(d.getVar('ALIGN_END', True)))
-
-        Merge_bin_files_and_pad(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFW_BB_BL31_TEE_BINARY',True)),
-        os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('UBOOT_HEADER_BINARY',True)),
-        os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFW_BB_UBOOT_BINARY',True)),
-        int(d.getVar('UBOOT_ALIGN', True)), int(d.getVar('ALIGN_END', True)))
-    else:
-        Merge_bin_files_and_pad(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('BB_HEADER_BINARY',True)),
-        os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('BL31_HEADER_BINARY',True)),
-        os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('BB_BL31_BINARY',True)),
-        int(d.getVar('ATF_ALIGN', True)), int(d.getVar('ALIGN_END', True)))
-
-        Merge_bin_files_and_pad(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('BB_BL31_BINARY',True)),
-        os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('OPTEE_HEADER_BINARY',True)),
-        os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('BB_BL31_TEE_BINARY',True)),
-        int(d.getVar('OPTEE_ALIGN', True)), int(d.getVar('ALIGN_END', True)))
-
-        Merge_bin_files_and_pad(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('BB_BL31_TEE_BINARY',True)),
-        os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('UBOOT_HEADER_BINARY',True)),
-        os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('BB_BL31_TEE_UBOOT_BINARY',True)),
-        int(d.getVar('UBOOT_ALIGN', True)), int(d.getVar('ALIGN_END', True)))
-
-        if SA_TIP_IMAGE == "True":
-            Merge_bin_files_and_pad(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('BB_BL31_TEE_UBOOT_BINARY',True)),
-            os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('SA_KMT_TIPFW_BINARY',True)),
-            os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('BB_BL31_TEE_UBOOT_SA_BINARY',True)),
-            int(d.getVar('SA_ALIGN', True)), int(d.getVar('ALIGN_END', True)))
-
-            os.rename(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('BB_BL31_TEE_UBOOT_SA_BINARY',True)),
-            os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFW_BB_UBOOT_BINARY',True)))
-        else:
-            os.rename(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('BB_BL31_TEE_UBOOT_BINARY',True)),
-            os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True), '%s' % d.getVar('KMT_TIPFW_BB_UBOOT_BINARY',True)))
-}
-
-do_pad_binary[depends] += " \
-    ${@'npcm8xx-tip-fw:do_deploy' if d.getVar('TIP_IMAGE', True) == 'True' or d.getVar('SA_TIP_IMAGE', True) == 'True' else ''} \
-    npcm8xx-bootblock:do_deploy \
-    u-boot-nuvoton:do_deploy \
-    trusted-firmware-a:do_deploy \
-    optee-os:do_deploy \
-    npcm7xx-bingo-native:do_populate_sysroot \
-    npcm8xx-igps-native:do_populate_sysroot \
-    "
-
 # link images for we only need to flash partial image with idea name
 do_generate_ext4_tar:append() {
-    cd ${DEPLOY_DIR_IMAGE}
-    ln -sf ${UBOOT_BINARY}.${MERGED_SUFFIX} image-u-boot
-    ln -sf ${DEPLOY_DIR_IMAGE}/${FLASH_KERNEL_IMAGE} image-kernel
-    ln -sf ${S}/ext4/${IMAGE_LINK_NAME}.${FLASH_EXT4_BASETYPE}.zst image-rofs
-    ln -sf ${IMGDEPLOYDIR}/${IMAGE_LINK_NAME}.rwfs.${FLASH_EXT4_OVERLAY_BASETYPE} image-rwfs
-    ln -sf ${IMAGE_NAME}.rootfs.wic.gz image-emmc.gz
+    cd ${S}/ext4
+    install -m 644 image-u-boot ${IMGDEPLOYDIR}/image-u-boot
+    cd ${IMGDEPLOYDIR}
+    ln -sf ${IMAGE_LINK_NAME}.wic.gz image-emmc.gz
+    ln -sf ${FLASH_KERNEL_IMAGE} image-kernel
+    ln -sf ${IMAGE_LINK_NAME}.rwfs.${FLASH_EXT4_OVERLAY_BASETYPE} image-rwfs
 }
 
-addtask do_pad_binary before do_prepare_bootloaders
-addtask do_sign_binary before do_merge_bootloaders after do_prepare_bootloaders
-addtask do_prepare_bootloaders before do_generate_static after do_generate_rwfs_static
-addtask do_prepare_bootloaders before do_generate_static_norootfs after do_image_cpio
-addtask do_merge_bootloaders before do_generate_static after do_sign_binary
-addtask do_merge_bootloaders before do_generate_static_norootfs after do_sign_binary
-addtask do_merge_bootloaders before do_generate_ext4_tar after do_prepare_bootloaders
-
-# Include the full bootblock and u-boot in the final static image
-python do_generate_static:append() {
-    _append_image(os.path.join(d.getVar('DEPLOY_DIR_IMAGE', True),
-                               'u-boot.%s' % d.getVar('UBOOT_SUFFIX',True)),
-                  int(d.getVar('FLASH_UBOOT_OFFSET', True)),
-                  int(d.getVar('FLASH_KERNEL_OFFSET', True)))
+# clean up image-u-boot because we may generate different size bootbloder
+# with different build flags. Function do_generate_image_uboot_file use
+# notrunc flag which may generate redundant image if we don't clean deploy.
+do_clean_image_uboot() {
+    rm -rf ${IMGDEPLOYDIR}/image-u-boot
 }
 
-do_make_ubi:append() {
-    # Concatenate the uboot and ubi partitions
-    dd bs=1k conv=notrunc seek=${FLASH_UBOOT_OFFSET} \
-        if=${DEPLOY_DIR_IMAGE}/u-boot.${UBOOT_SUFFIX} \
-        of=${IMGDEPLOYDIR}/${IMAGE_NAME}.ubi.mtd
-}
+addtask do_clean_image_uboot after do_rootfs
+do_make_ubi[depends] += "npcm8xx-bootloader:do_deploy"
+do_generate_ubi_tar[depends] += "npcm8xx-bootloader:do_deploy"
+do_generate_static_tar[depends] += "npcm8xx-bootloader:do_deploy"
+do_generate_static[depends] += " \
+    npcm8xx-bootloader:do_deploy \
+    ${PN}:do_clean_image_uboot \
+"
+do_generate_static_norootfs[depends] += "npcm8xx-bootloader:do_deploy"
+do_generate_ext4_tar[depends] += "npcm8xx-bootloader:do_deploy"
 
-do_make_ubi[depends] += "${PN}:do_prepare_bootloaders"
-do_generate_ubi_tar[depends] += "${PN}:do_prepare_bootloaders"
-do_generate_ubi_tar[depends] += "${PN}:do_merge_bootloaders"
-do_generate_static_tar[depends] += "${PN}:do_prepare_bootloaders"
-do_generate_static_tar[depends] += "${PN}:do_merge_bootloaders"
-do_generate_static_norootfs[depends] += "${PN}:do_prepare_bootloaders"
-do_generate_static_norootfs[depends] += "${PN}:do_merge_bootloaders"
-do_generate_ext4_tar[depends] += "${PN}:do_prepare_bootloaders"
-do_generate_ext4_tar[depends] += "${PN}:do_merge_bootloaders"