[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/meta/meta-mediatek/classes/add-pulseaudio-service.bbclass b/meta/meta-mediatek/classes/add-pulseaudio-service.bbclass
new file mode 100644
index 0000000..a61f0d2
--- /dev/null
+++ b/meta/meta-mediatek/classes/add-pulseaudio-service.bbclass
@@ -0,0 +1,6 @@
+install_pulseaudio_service_to_profile() {
+    echo "pulseaudio --start" > ${IMAGE_ROOTFS}${ROOT_HOME}/.profile
+}
+
+ROOTFS_POSTPROCESS_COMMAND += " install_pulseaudio_service_to_profile;"
+
diff --git a/meta/meta-mediatek/classes/add-recovery-rootfs-8167s.bbclass b/meta/meta-mediatek/classes/add-recovery-rootfs-8167s.bbclass
new file mode 100644
index 0000000..95ed301
--- /dev/null
+++ b/meta/meta-mediatek/classes/add-recovery-rootfs-8167s.bbclass
@@ -0,0 +1 @@
+do_rootfs[depends] += "mtk-image-aiv8167m3v4-emmc-recovery:do_mtdverity_for_rootfs"
\ No newline at end of file
diff --git a/meta/meta-mediatek/classes/add-recovery-rootfs.bbclass b/meta/meta-mediatek/classes/add-recovery-rootfs.bbclass
new file mode 100644
index 0000000..8bc0812
--- /dev/null
+++ b/meta/meta-mediatek/classes/add-recovery-rootfs.bbclass
@@ -0,0 +1 @@
+do_rootfs[depends] += "mtk-image-aud-8516-recovery:do_mtdverity_for_rootfs"
\ No newline at end of file
diff --git a/meta/meta-mediatek/classes/avb_sign_image.bbclass b/meta/meta-mediatek/classes/avb_sign_image.bbclass
new file mode 100644
index 0000000..def151c
--- /dev/null
+++ b/meta/meta-mediatek/classes/avb_sign_image.bbclass
@@ -0,0 +1,128 @@
+inherit hsm-sign-env
+
+AVBTOOL="python ${DEPLOY_DIR_IMAGE}/avbtool"
+SCATTER_FILE="${DEPLOY_DIR_IMAGE}/partition_${BOOTDEV_TYPE}.xml"
+
+IMAGE_FSTYPE="img"
+IMAGE_DIR_ROOTFS="${DEPLOY_DIR_IMAGE}"
+
+
+IMAGE_NAME_ROOTFS="system.${IMAGE_FSTYPE}"
+
+IMAGE_NAME_BOOTIMG="boot.img"
+IMAGE_DIR_BOOTIMG="${DEPLOY_DIR_IMAGE}"
+
+AVB_BLOCK_SIZE="1024"
+AVB_SYSTEM_KEY_NAME="verified_key"
+AVB_SYSTEM_KEY="${MTK_KEY_DIR}/${VERIFIED_KEY}.pem"
+
+DEPENDS += "python-pycrypto-native android-tools-avbtool scatter"
+
+exec_avbtool() {
+
+	echo "check config setting: enable=${SECURE_BOOT_ENABLE};SE_type=${SECURE_BOOT_TYPE}"
+	vb_hash_algo=`echo ${VB_HASH_ALGO}|tr 'a-z' 'A-Z'`
+	vb_rsa_algo=`echo ${VB_RSA_ALGO}|tr 'a-z' 'A-Z'`
+	if [ -n "${VB_HASH_ALGO}" ] && [ -n "${VB_RSA_ALGO}" ] ; then
+		AVB_ALGO="${vb_hash_algo}_${vb_rsa_algo}"
+	else
+		AVB_ALGO="SHA256_RSA2048"
+	fi
+	if [ "${SECURE_BOOT_ENABLE}" = "yes" ] && [ "${SECURE_BOOT_TYPE}" = "avb" ]; then
+		echo "start AVB sign ... "
+		echo "PARTITION_SIZE_BOOTIMG=${PARTITION_SIZE_BOOTIMG}; PARTITION_SIZE_ROOTFS=${PARTITION_SIZE_ROOTFS}"
+
+		PARTITION_NAME_ROOTFS="system"
+		PARTITION_NAME_BOOTIMG="boot"
+		if [ "${AVB_ANTIROLLBACK_VERSION}" = "" ]; then
+		    AVB_ANTIROLLBACK_VERSION="0"
+		fi
+
+		echo "start to erase footer: ${IMAGE_NAME_BOOTIMG}"
+		${AVBTOOL} erase_footer --image ${IMAGE_DIR_BOOTIMG}/${IMAGE_NAME_BOOTIMG} || true
+
+		echo "start to erase footer: system.${IMAGE_FSTYPE} "
+		${AVBTOOL} erase_footer --image ${IMAGE_DIR_ROOTFS}/system.${IMAGE_FSTYPE} || true
+
+		if test -e ${IMAGE_DIR_BOOTIMG}/${IMAGE_NAME_BOOTIMG}; then
+			echo "start to sign image: ${IMAGE_NAME_BOOTIMG}"
+			${HSM_ENV} ${AVBTOOL} add_hash_footer --image ${IMAGE_DIR_BOOTIMG}/${IMAGE_NAME_BOOTIMG} \
+				--partition_size ${PARTITION_SIZE_BOOTIMG} \
+				--partition_name ${PARTITION_NAME_BOOTIMG} \
+				--algorithm ${AVB_ALGO} \
+				--key ${AVB_SYSTEM_KEY} \
+				${HSM_SIGN_PARAM}
+		fi
+
+		if test -e ${IMAGE_DIR_ROOTFS}/system.${IMAGE_FSTYPE}; then
+			echo "start to sign image: system.${IMAGE_FSTYPE} "
+			${HSM_ENV} ${AVBTOOL} add_hashtree_footer --block_size ${AVB_BLOCK_SIZE} \
+				--partition_size ${PARTITION_SIZE_ROOTFS} \
+				--partition_name ${PARTITION_NAME_ROOTFS} \
+				--image ${IMAGE_DIR_ROOTFS}/system.${IMAGE_FSTYPE} \
+				--algorithm ${AVB_ALGO} \
+				--key ${AVB_SYSTEM_KEY} \
+				${HSM_SIGN_PARAM}
+
+			if test -e ${IMAGE_DIR_BOOTIMG}/${IMAGE_NAME_BOOTIMG}; then
+				echo "start to make vbmeta image"
+				${HSM_ENV} ${AVBTOOL} make_vbmeta_image --rollback_index ${AVB_ANTIROLLBACK_VERSION} \
+					--include_descriptors_from_image ${IMAGE_DIR_BOOTIMG}/${IMAGE_NAME_BOOTIMG} \
+					--include_descriptors_from_image ${IMAGE_DIR_ROOTFS}/system.${IMAGE_FSTYPE} \
+					--setup_rootfs_from_kernel ${IMAGE_DIR_ROOTFS}/system.${IMAGE_FSTYPE} \
+					--algorithm ${AVB_ALGO} \
+					--key ${AVB_SYSTEM_KEY} \
+					--output vbmeta.img \
+					${HSM_SIGN_PARAM}
+
+				if [ ${BOOTDEV_TYPE} != "nand" ]; then
+					echo "start to append vbmeta image"
+					${AVBTOOL} append_vbmeta_image --image ${IMAGE_DIR_BOOTIMG}/${IMAGE_NAME_BOOTIMG} \
+						--partition_size ${PARTITION_SIZE_BOOTIMG} \
+						--vbmeta_image vbmeta.img
+				else
+					cp vbmeta.img  ${IMAGE_DIR_BOOTIMG}/
+				fi
+			fi
+		fi
+	else
+		exit 0
+	fi
+}
+
+python do_avb_sign_img() {
+    import xml.dom.minidom
+    import math
+    secure_boot_type = d.getVar('SECURE_BOOT_TYPE', True)
+    if secure_boot_type != "avb":
+        return
+    bootdev_type = d.getVar('BOOTDEV_TYPE', True)
+
+    deploy_path = d.getVar('DEPLOY_DIR_IMAGE',True)
+    for file in os.listdir(deploy_path):
+        if os.path.splitext(file)[1] == '.xml':
+            partition_path =  os.path.join(deploy_path,file)
+            root = xml.dom.minidom.parse(partition_path)
+            for partition in root.childNodes:
+                if partition.nodeName == "partition":
+                    break
+            lbs = partition.getAttribute("lbs")
+            lbs = lbs and eval(lbs) or 512
+            for node in partition.childNodes:
+                if node.nodeName != "entry":
+                    continue
+                start = eval(node.getAttribute("start"))
+                end = eval(node.getAttribute("end"))
+                name = node.getAttribute("name")
+                size = (end-start+1)*lbs
+                #0.92=62/64 *0.95
+                if (bootdev_type == 'nand'):
+                    size = math.ceil(size*0.92/4096)*4096
+                if name == "BOOTIMG" or name.startswith("boot"):
+                    d.setVar('PARTITION_SIZE_BOOTIMG', str(size))
+                if name == "ROOTFS" or name.startswith("system"):
+                    d.setVar('PARTITION_SIZE_ROOTFS', str(size))
+    bb.build.exec_func('exec_avbtool', d)
+}
+
+addtask avb_sign_img after do_image_complete before do_build
diff --git a/meta/meta-mediatek/classes/bl33-fitimage.bbclass b/meta/meta-mediatek/classes/bl33-fitimage.bbclass
new file mode 100644
index 0000000..b76f755
--- /dev/null
+++ b/meta/meta-mediatek/classes/bl33-fitimage.bbclass
@@ -0,0 +1,150 @@
+inherit hsm-sign-env
+
+python __anonymous () {
+        depends = d.getVar("DEPENDS", True)
+        depends = "%s u-boot-mkimage-native lz4-native" % depends
+        d.setVar("DEPENDS", depends)
+}
+
+#
+# Emit the fitImage ITS header
+#
+fitimage_emit_fit_header() {
+        cat << EOF >> ${WORKDIR}/fit-image.its
+/dts-v1/;
+
+/ {
+        description = "BL33 fitImage";
+        #address-cells = <1>;
+EOF
+}
+
+#
+# Emit the fitImage section bits
+#
+# $1 ... Section bit type: imagestart - image section start
+#                          confstart  - configuration section start
+#                          sectend    - section end
+#                          fitend     - fitimage end
+#
+fitimage_emit_section_maint() {
+        case $1 in
+        imagestart)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+
+        images {
+EOF
+        ;;
+        confstart)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+
+        configurations {
+EOF
+        ;;
+        sectend)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+        };
+EOF
+        ;;
+        fitend)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+};
+EOF
+        ;;
+        esac
+}
+
+fitimage_emit_section_bl33() {
+
+        if [ -n "${IMAGE_HASH_ALGO}" ] ; then
+            bl33_csum="${IMAGE_HASH_ALGO}"
+        else
+            bl33_csum="sha256"
+        fi
+
+        cat << EOF >> ${WORKDIR}/fit-image.its
+                bl33@1 {
+                        description = "LK based BL33 Image";
+                        data = /incbin/("${1}");
+                        type = "kernel";
+                        arch = "arm";
+                        os = "linux";
+                        compression = "${2}";
+                        load = <${BL33_LOADADDRESS}>;
+                        entry = <${BL33_ENTRYPOINT}>;
+                        hash@1 {
+                                algo = "${bl33_csum}";
+                        };
+                };
+EOF
+}
+
+#
+# Emit the fitImage ITS configuration section
+#
+fitimage_emit_section_config() {
+
+        if [ -n "${VB_HASH_ALGO}" ] && [ -n "${VB_RSA_ALGO}" ] ; then
+            conf_csum="${VB_HASH_ALGO},${VB_RSA_ALGO}"
+        else
+            conf_csum="sha256,rsa2048"
+        fi
+        conf_key_name="dev"
+
+        conf_desc="${MTK_PROJECT} configuration"
+
+        cat << EOF >> ${WORKDIR}/fit-image.its
+                default = "conf@1";
+                conf@1 {
+                        description = "${conf_desc}";
+                        kernel = "bl33@1";
+                        signature@1 {
+                                algo = "${conf_csum}";
+                                key-name-hint="${conf_key_name}";
+                                sign-images = "kernel";
+                        };
+                };
+EOF
+}
+
+do_assemble_fitimage() {
+
+                rm -f ${WORKDIR}/fit-image.its
+
+                fitimage_emit_fit_header
+
+                #
+                # Step 1: Prepare a bl33 image section.
+                #
+                fitimage_emit_section_maint imagestart
+
+
+                fitimage_emit_section_bl33 ${BL33_OUT}/build-${BL33_PROJECT}/${BL33_BINARY} ${BL33_COMPRESS}
+
+                fitimage_emit_section_maint sectend
+
+                #
+                # Step 2: Prepare a configurations section
+                #
+                fitimage_emit_section_maint confstart
+
+                fitimage_emit_section_config
+
+                fitimage_emit_section_maint sectend
+
+                fitimage_emit_section_maint fitend
+
+                #
+                # Step 3: Assemble the image
+                #
+                ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -f ${WORKDIR}/fit-image.its ${WORKDIR}/${BL33_IMAGE}
+
+                if [ "${SECURE_BOOT_ENABLE}" = "yes" ]; then
+                        mkdir -p ./mykeys
+                        cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.crt ./mykeys/dev.crt
+                        cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.pem ./mykeys/dev.key
+                        ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -D "-I dts -O dtb -p 1024" -k ./mykeys -f ${WORKDIR}/fit-image.its -r ${WORKDIR}/${BL33_IMAGE}
+                fi
+}
+
+addtask assemble_fitimage before do_deploy after do_compile
diff --git a/meta/meta-mediatek/classes/boot-ubifs.bbclass b/meta/meta-mediatek/classes/boot-ubifs.bbclass
new file mode 100644
index 0000000..7508234
--- /dev/null
+++ b/meta/meta-mediatek/classes/boot-ubifs.bbclass
@@ -0,0 +1,4 @@
+add_boot_image() {

+    install -d ${IMAGE_ROOTFS}/boot/

+    install ${DEPLOY_DIR_IMAGE}/boot.img ${IMAGE_ROOTFS}/boot/

+}

diff --git a/meta/meta-mediatek/classes/core-image-tiny.bbclass b/meta/meta-mediatek/classes/core-image-tiny.bbclass
new file mode 100644
index 0000000..78f22d2
--- /dev/null
+++ b/meta/meta-mediatek/classes/core-image-tiny.bbclass
@@ -0,0 +1,67 @@
+# Common code for generating core reference images
+#
+# Copyright (C) 2007-2011 Linux Foundation
+
+LIC_FILES_CHKSUM = "file://${COREBASE}/LICENSE;md5=4d92cd373abda3937c2bc47fbc49d690 \
+                    file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"
+
+# IMAGE_FEATURES control content of the core reference images
+# 
+# By default we install packagegroup-core-boot and packagegroup-base-extended packages;
+# this gives us working (console only) rootfs.
+#
+# Available IMAGE_FEATURES:
+#
+# - x11                 - X server
+# - x11-base            - X server with minimal environment
+# - x11-sato            - OpenedHand Sato environment
+# - tools-debug         - debugging tools
+# - eclipse-debug       - Eclipse remote debugging support
+# - tools-profile       - profiling tools
+# - tools-testapps      - tools usable to make some device tests
+# - tools-sdk           - SDK (C/C++ compiler, autotools, etc.)
+# - nfs-server          - NFS server
+# - nfs-client          - NFS client
+# - ssh-server-dropbear - SSH server (dropbear)
+# - ssh-server-openssh  - SSH server (openssh)
+# - hwcodecs            - Install hardware acceleration codecs
+# - package-management  - installs package management tools and preserves the package manager database
+# - debug-tweaks        - makes an image suitable for development, e.g. allowing passwordless root logins
+# - dev-pkgs            - development packages (headers, etc.) for all installed packages in the rootfs
+# - dbg-pkgs            - debug symbol packages for all installed packages in the rootfs
+# - doc-pkgs            - documentation packages for all installed packages in the rootfs
+# - ptest-pkgs          - ptest packages for all ptest-enabled recipes
+# - read-only-rootfs    - tweaks an image to support read-only rootfs
+#
+FEATURE_PACKAGES_x11 = "packagegroup-core-x11"
+FEATURE_PACKAGES_x11-base = "packagegroup-core-x11-base"
+FEATURE_PACKAGES_x11-sato = "packagegroup-core-x11-sato"
+FEATURE_PACKAGES_tools-debug = "packagegroup-core-tools-debug"
+FEATURE_PACKAGES_eclipse-debug = "packagegroup-core-eclipse-debug"
+FEATURE_PACKAGES_tools-profile = "packagegroup-core-tools-profile"
+FEATURE_PACKAGES_tools-testapps = "packagegroup-core-tools-testapps"
+FEATURE_PACKAGES_tools-sdk = "packagegroup-core-sdk packagegroup-core-standalone-sdk-target"
+FEATURE_PACKAGES_nfs-server = "packagegroup-core-nfs-server"
+FEATURE_PACKAGES_nfs-client = "packagegroup-core-nfs-client"
+FEATURE_PACKAGES_ssh-server-dropbear = "packagegroup-core-ssh-dropbear"
+FEATURE_PACKAGES_ssh-server-openssh = "packagegroup-core-ssh-openssh"
+FEATURE_PACKAGES_hwcodecs = "${MACHINE_HWCODECS}"
+
+
+# IMAGE_FEATURES_REPLACES_foo = 'bar1 bar2'
+# Including image feature foo would replace the image features bar1 and bar2
+IMAGE_FEATURES_REPLACES_ssh-server-openssh = "ssh-server-dropbear"
+
+# IMAGE_FEATURES_CONFLICTS_foo = 'bar1 bar2'
+# An error exception would be raised if both image features foo and bar1(or bar2) are included
+
+MACHINE_HWCODECS ??= ""
+
+CORE_IMAGE_BASE_INSTALL = '\
+    '
+
+CORE_IMAGE_EXTRA_INSTALL ?= ""
+
+IMAGE_INSTALL ?= "${CORE_IMAGE_BASE_INSTALL}"
+
+inherit image
diff --git a/meta/meta-mediatek/classes/create-link.bbclass b/meta/meta-mediatek/classes/create-link.bbclass
new file mode 100644
index 0000000..42226f5
--- /dev/null
+++ b/meta/meta-mediatek/classes/create-link.bbclass
@@ -0,0 +1,5 @@
+soft_link_to_rootfs() {
+        ln -nfs ${IMAGE_NAME}.rootfs.${IMAGE_FSTYPES} ${DEPLOY_DIR_IMAGE}/system.${IMAGE_FSTYPES}
+}
+
+ROOTFS_POSTPROCESS_COMMAND += " soft_link_to_rootfs;"
diff --git a/meta/meta-mediatek/classes/create-mtdverity.bbclass b/meta/meta-mediatek/classes/create-mtdverity.bbclass
new file mode 100644
index 0000000..e4a3fdb
--- /dev/null
+++ b/meta/meta-mediatek/classes/create-mtdverity.bbclass
@@ -0,0 +1,28 @@
+MTDVERITY_TOOL_DIR="${TOPDIR}/../src/devtools/nfsb/mtd_verity"
+MTDVERITY_TOOL="${MTDVERITY_TOOL_DIR}/mtd_verity"
+MTDVERITY_WORKING_PATH="${DEPLOY_DIR_IMAGE}"
+OLD_ROOTFS_NAME="${IMAGE_NAME}.rootfs.${IMAGE_FSTYPES}"
+NEW_ROOTFS_NAME="mtdverity_system.${IMAGE_FSTYPES}"
+IMG_KEY_FILE = "${MTK_KEY_DIR}/${VERIFIED_KEY}.pem"
+
+do_mtdverity_for_rootfs() {
+
+       if [ "${SECURE_BOOT_ENABLE}" = "yes" ] && [ "${ENABLE_ROOTFS_CHECK}" = "yes" ]; then
+			if [ "${STANDALONE_SIGN_PREPARE}" = "yes" ];then
+				exit 0
+			fi
+                        if [ ! -f ${MTDVERITY_WORKING_PATH}/${OLD_ROOTFS_NAME} ]; then
+			    cp ${MTDVERITY_WORKING_PATH}/${IMAGE_BASENAME}-${MACHINE}.${IMAGE_FSTYPES} ${MTDVERITY_WORKING_PATH}/${OLD_ROOTFS_NAME}
+			fi
+                       ${MTDVERITY_TOOL} ${MTDVERITY_WORKING_PATH}/${OLD_ROOTFS_NAME} 1048576 1048576 10 ${IMG_KEY_FILE} ${MTDVERITY_WORKING_PATH}/${NEW_ROOTFS_NAME}
+                       rm -f ${MTDVERITY_WORKING_PATH}/${OLD_ROOTFS_NAME}
+                       mv ${MTDVERITY_WORKING_PATH}/${NEW_ROOTFS_NAME} ${MTDVERITY_WORKING_PATH}/${OLD_ROOTFS_NAME}
+       else
+              exit 0
+       fi
+}
+
+addtask mtdverity_for_rootfs after do_image_complete before do_packing_images_post_funcs
+do_rootfs[nostamp] = "1"
+
+#IMAGE_POSTPROCESS_COMMAND += " add_mtdverity_for_rootfs;"
diff --git a/meta/meta-mediatek/classes/create-nfsb.bbclass b/meta/meta-mediatek/classes/create-nfsb.bbclass
new file mode 100644
index 0000000..5ac50d8
--- /dev/null
+++ b/meta/meta-mediatek/classes/create-nfsb.bbclass
@@ -0,0 +1,87 @@
+NFSBVERITY="/sbin/veritysetup"
+NFSB_TOOLS_DIR="${TOPDIR}/../src/devtools/nfsb"
+MKNFSBIMG="${NFSB_TOOLS_DIR}/mknfsbimg3"
+ZERO_PADDING_TOOL="${NFSB_TOOLS_DIR}/zero_padding.sh"
+NFSB_WORKING_PATH="${IMGDEPLOYDIR}"
+NFSB_BLOCK_SIZE="1024"
+OLD_ROOTFS_NAME="${IMAGE_NAME}.rootfs.${IMAGE_FSTYPES}"
+OLD_RECOVERY_ROOTFS_NAME="recovery.${IMAGE_FSTYPES}"
+NEW_ROOTFS_NAME="nfsb_rootfs.${IMAGE_FSTYPES}"
+NEW_RECOVERY_ROOTFS_NAME = "tmp_recovery.${IMAGE_FSTYPES}"
+ZERO_PADDING_SIZE="1048576"
+KEY_FILE_MOD="${NFSB_TOOLS_DIR}/rsa.key.pub_out"
+KEY_FILE_PRI="${NFSB_TOOLS_DIR}/rsa.key.pri_out"
+DST_IMG_KEY_FILE = "${TOPDIR}/../src/devtools/nfsb/rsa.key"
+
+add_nfsb_for_rootfs() {
+
+       mod_key=""
+       pri_key=""
+       SRC_IMG_KEY_FILE=""
+       DM_VERITY_ALG=""
+
+       if [ "${STANDALONE_SIGN_PREPARE}" = "yes" ]; then
+           exit 0
+       fi
+
+       if [ "${ROOTFS_VERITY_KEY}" = "" ]; then
+              SRC_IMG_KEY_FILE="${MTK_KEY_DIR}/${VERIFIED_KEY}.pem"
+       else
+              SRC_IMG_KEY_FILE="${MTK_KEY_DIR}/${ROOTFS_VERITY_KEY}.pem"
+       fi
+
+       if [ "${DM_NFSB_HASH_ALG}" = "" ]; then
+              DM_VERITY_ALG="md5"
+       else
+              DM_VERITY_ALG="${DM_NFSB_HASH_ALG}"
+       fi
+
+       #backwards compatible for FORCE_DISABLE_DM_VERITY which only for NFSB actually
+       if [ "${SECURE_BOOT_ENABLE}" = "yes" ] && [ "${SECURE_BOOT_TYPE}" = "" ]; then
+              ENABLE_DM_NFSB="yes"
+       fi
+       if [ "${FORCE_DISABLE_DM_VERITY}" = "yes" ]; then
+              ENABLE_DM_NFSB="no"
+       fi
+
+       if [ "${SECURE_BOOT_ENABLE}" = "yes" ] && [ "${ENABLE_DM_NFSB}" == "yes" ]; then
+              if [ -e ${KEY_FILE_MOD} ]; then
+                     mod_key=${KEY_FILE_MOD}
+                     pri_key=${KEY_FILE_PRI}
+              else
+                     if [ -e ${SRC_IMG_KEY_FILE} ]; then
+                         cp ${SRC_IMG_KEY_FILE} ${DST_IMG_KEY_FILE}
+                         python ${TOPDIR}/../src/devtools/nfsb/pretreat-key.py ${TOPDIR} ${SRC_IMG_KEY_FILE}
+                         mod_key=${KEY_FILE_MOD}
+                         pri_key=${KEY_FILE_PRI}
+                     else
+                         bbfatal "${KEY_FILE_MOD} does not exist!"
+                     fi
+              fi
+       else
+              exit 0
+       fi
+
+       ${NFSBVERITY} --hash=${DM_VERITY_ALG} --no-superblock --data-block-size=${NFSB_BLOCK_SIZE} --hash-block-size=${NFSB_BLOCK_SIZE} format ${NFSB_WORKING_PATH}/${OLD_ROOTFS_NAME} ${NFSB_WORKING_PATH}/rootfs_hashes | tee ${NFSB_WORKING_PATH}/rootfs_table
+       ${MKNFSBIMG} ${NFSB_WORKING_PATH}/${OLD_ROOTFS_NAME} ${NFSB_WORKING_PATH}/rootfs_hashes ${NFSB_WORKING_PATH}/${NEW_ROOTFS_NAME} ${NFSB_WORKING_PATH}/rootfs_table ${mod_key} ${pri_key};
+       rm -f ${NFSB_WORKING_PATH}/${OLD_ROOTFS_NAME}
+       mv ${NFSB_WORKING_PATH}/${NEW_ROOTFS_NAME} ${NFSB_WORKING_PATH}/${OLD_ROOTFS_NAME}
+       ${ZERO_PADDING_TOOL} ${NFSB_WORKING_PATH}/${OLD_ROOTFS_NAME} ${ZERO_PADDING_SIZE}
+       rm -f ${NFSB_WORKING_PATH}/rootfs_hashes
+       rm -f ${NFSB_WORKING_PATH}/rootfs_table
+
+       if [ -e ${NFSB_WORKING_PATH}/${OLD_RECOVERY_ROOTFS_NAME} ]; then
+              ${NFSBVERITY} --hash=md5 --no-superblock --data-block-size=${NFSB_BLOCK_SIZE} --hash-block-size=${NFSB_BLOCK_SIZE} format ${NFSB_WORKING_PATH}/${OLD_RECOVERY_ROOTFS_NAME} ${NFSB_WORKING_PATH}/recovery_rootfs_hashes | tee ${NFSB_WORKING_PATH}/recovery_rootfs_table
+              ${MKNFSBIMG} ${NFSB_WORKING_PATH}/${OLD_RECOVERY_ROOTFS_NAME} ${NFSB_WORKING_PATH}/recovery_rootfs_hashes ${NFSB_WORKING_PATH}/${NEW_RECOVERY_ROOTFS_NAME} ${NFSB_WORKING_PATH}/recovery_rootfs_table ${mod_key} ${pri_key};
+              rm -f ${NFSB_WORKING_PATH}/${OLD_RECOVERY_ROOTFS_NAME}
+              mv ${NFSB_WORKING_PATH}/${NEW_RECOVERY_ROOTFS_NAME} ${NFSB_WORKING_PATH}/${OLD_RECOVERY_ROOTFS_NAME}
+              ${ZERO_PADDING_TOOL} ${NFSB_WORKING_PATH}/${OLD_RECOVERY_ROOTFS_NAME} ${ZERO_PADDING_SIZE}
+              rm -f ${NFSB_WORKING_PATH}/recovery_rootfs_hashes
+              rm -f ${NFSB_WORKING_PATH}/recovery_rootfs_table
+       fi
+
+       rm -f ${mod_key}
+       rm -f ${pri_key}
+}
+
+IMAGE_POSTPROCESS_COMMAND += " add_nfsb_for_rootfs;"
diff --git a/meta/meta-mediatek/classes/create-sparse-image.bbclass b/meta/meta-mediatek/classes/create-sparse-image.bbclass
new file mode 100644
index 0000000..f19feb0
--- /dev/null
+++ b/meta/meta-mediatek/classes/create-sparse-image.bbclass
@@ -0,0 +1,13 @@
+DEPENDS += "android-tools-fsutils-native"
+
+do_sparse_image() {
+# Usage: img2simg <raw_image_file> <sparse_image_file> [<block_size>]
+if test -e ${IMGDEPLOYDIR}/${IMAGE_NAME}.rootfs.${IMAGE_FSTYPES} ; then
+    img2simg ${IMGDEPLOYDIR}/${IMAGE_NAME}.rootfs.${IMAGE_FSTYPES} ${DEPLOY_DIR_IMAGE}/system.img
+    if test -e ${DEPLOY_DIR_IMAGE}/sign_rootfs ; then
+	rm -rf ${DEPLOY_DIR_IMAGE}/sign_rootfs
+    fi
+fi
+}
+
+do_image_complete[postfuncs] += "do_sparse_image"
diff --git a/meta/meta-mediatek/classes/depends-systemd.bbclass b/meta/meta-mediatek/classes/depends-systemd.bbclass
new file mode 100644
index 0000000..8738279
--- /dev/null
+++ b/meta/meta-mediatek/classes/depends-systemd.bbclass
@@ -0,0 +1,5 @@
+
+python() {
+        d.appendVarFlag('do_cleansstate', 'depends', ' systemd:do_cleansstate')
+        d.appendVarFlag('do_compile', 'depends', ' systemd:do_compile')
+}
diff --git a/meta/meta-mediatek/classes/features_check.bbclass b/meta/meta-mediatek/classes/features_check.bbclass
new file mode 100644
index 0000000..876d32e
--- /dev/null
+++ b/meta/meta-mediatek/classes/features_check.bbclass
@@ -0,0 +1,88 @@
+# Allow checking of required and conflicting DISTRO_FEATURES
+#
+# ANY_OF_DISTRO_FEATURES:     ensure at least one item on this list is included
+#                             in DISTRO_FEATURES.
+# REQUIRED_DISTRO_FEATURES:   ensure every item on this list is included
+#                             in DISTRO_FEATURES.
+# CONFLICT_DISTRO_FEATURES:   ensure no item in this list is included in
+#                             DISTRO_FEATURES.
+# ANY_OF_MACHINE_FEATURES:    ensure at least one item on this list is included
+#                             in MACHINE_FEATURES.
+# REQUIRED_MACHINE_FEATURES:  ensure every item on this list is included
+#                             in MACHINE_FEATURES.
+# CONFLICT_MACHINE_FEATURES:  ensure no item in this list is included in
+#                             MACHINE_FEATURES.
+# ANY_OF_COMBINED_FEATURES:   ensure at least one item on this list is included
+#                             in COMBINED_FEATURES.
+# REQUIRED_COMBINED_FEATURES: ensure every item on this list is included
+#                             in COMBINED_FEATURES.
+# CONFLICT_COMBINED_FEATURES: ensure no item in this list is included in
+#                             COMBINED_FEATURES.
+#
+# Copyright 2019 (C) Texas Instruments Inc.
+# Copyright 2013 (C) O.S. Systems Software LTDA.
+
+python () {
+    if d.getVar('PARSE_ALL_RECIPES', False):
+        return
+
+    # Assume at least one var is set.
+    distro_features = set((d.getVar('DISTRO_FEATURES') or '').split())
+
+    any_of_distro_features = set((d.getVar('ANY_OF_DISTRO_FEATURES') or '').split())
+    if any_of_distro_features:
+        if set.isdisjoint(any_of_distro_features, distro_features):
+            raise bb.parse.SkipRecipe("one of '%s' needs to be in DISTRO_FEATURES" % ' '.join(any_of_distro_features))
+
+    required_distro_features = set((d.getVar('REQUIRED_DISTRO_FEATURES') or '').split())
+    if required_distro_features:
+        missing = set.difference(required_distro_features, distro_features)
+        if missing:
+            raise bb.parse.SkipRecipe("missing required distro feature%s '%s' (not in DISTRO_FEATURES)" % ('s' if len(missing) > 1 else '', ' '.join(missing)))
+
+    conflict_distro_features = set((d.getVar('CONFLICT_DISTRO_FEATURES') or '').split())
+    if conflict_distro_features:
+        conflicts = set.intersection(conflict_distro_features, distro_features)
+        if conflicts:
+            raise bb.parse.SkipRecipe("conflicting distro feature%s '%s' (in DISTRO_FEATURES)" % ('s' if len(conflicts) > 1 else '', ' '.join(conflicts)))
+
+    # Assume at least one var is set.
+    machine_features = set((d.getVar('MACHINE_FEATURES') or '').split())
+
+    any_of_machine_features = set((d.getVar('ANY_OF_MACHINE_FEATURES') or '').split())
+    if any_of_machine_features:
+        if set.isdisjoint(any_of_machine_features, machine_features):
+            raise bb.parse.SkipRecipe("one of '%s' needs to be in MACHINE_FEATURES" % ' '.join(any_of_machine_features))
+
+    required_machine_features = set((d.getVar('REQUIRED_MACHINE_FEATURES') or '').split())
+    if required_machine_features:
+        missing = set.difference(required_machine_features, machine_features)
+        if missing:
+            raise bb.parse.SkipRecipe("missing required machine feature%s '%s' (not in MACHINE_FEATURES)" % ('s' if len(missing) > 1 else '', ' '.join(missing)))
+
+    conflict_machine_features = set((d.getVar('CONFLICT_MACHINE_FEATURES') or '').split())
+    if conflict_machine_features:
+        conflicts = set.intersection(conflict_machine_features, machine_features)
+        if conflicts:
+            raise bb.parse.SkipRecipe("conflicting machine feature%s '%s' (in MACHINE_FEATURES)" % ('s' if len(conflicts) > 1 else '', ' '.join(conflicts)))
+
+    # Assume at least one var is set.
+    combined_features = set((d.getVar('COMBINED_FEATURES') or '').split())
+
+    any_of_combined_features = set((d.getVar('ANY_OF_COMBINED_FEATURES') or '').split())
+    if any_of_combined_features:
+        if set.isdisjoint(any_of_combined_features, combined_features):
+            raise bb.parse.SkipRecipe("one of '%s' needs to be in COMBINED_FEATURES" % ' '.join(any_of_combined_features))
+
+    required_combined_features = set((d.getVar('REQUIRED_COMBINED_FEATURES') or '').split())
+    if required_combined_features:
+        missing = set.difference(required_combined_features, combined_features)
+        if missing:
+            raise bb.parse.SkipRecipe("missing required machine feature%s '%s' (not in COMBINED_FEATURES)" % ('s' if len(missing) > 1 else '', ' '.join(missing)))
+
+    conflict_combined_features = set((d.getVar('CONFLICT_COMBINED_FEATURES') or '').split())
+    if conflict_combined_features:
+        conflicts = set.intersection(conflict_combined_features, combined_features)
+        if conflicts:
+            raise bb.parse.SkipRecipe("conflicting machine feature%s '%s' (in COMBINED_FEATURES)" % ('s' if len(conflicts) > 1 else '', ' '.join(conflicts)))
+}
diff --git a/meta/meta-mediatek/classes/fsck-image.bbclass b/meta/meta-mediatek/classes/fsck-image.bbclass
new file mode 100644
index 0000000..79f0a60
--- /dev/null
+++ b/meta/meta-mediatek/classes/fsck-image.bbclass
@@ -0,0 +1,9 @@
+
+do_fsck_image_pre_funcs() {
+    cp ${IMGDEPLOYDIR}/${IMAGE_NAME}.rootfs.${IMAGE_FSTYPES} ${DEPLOY_DIR_IMAGE}/rootfs.${IMAGE_FSTYPES}
+    ${STAGING_DIR_NATIVE}${base_sbindir}/fsck.ext4 -f -y ${DEPLOY_DIR_IMAGE}/rootfs.${IMAGE_FSTYPES} || : 
+    ${STAGING_DIR_NATIVE}${base_sbindir}/fsck.ext4 -f -y ${DEPLOY_DIR_IMAGE}/rootfs.${IMAGE_FSTYPES} 
+}
+
+do_image_complete[prefuncs] += "do_fsck_image_pre_funcs"
+
diff --git a/meta/meta-mediatek/classes/get_toolchain_name.bbclass b/meta/meta-mediatek/classes/get_toolchain_name.bbclass
new file mode 100644
index 0000000..a31562d
--- /dev/null
+++ b/meta/meta-mediatek/classes/get_toolchain_name.bbclass
@@ -0,0 +1 @@
+TOOLCHAIN_NAME = "${@bb.utils.contains('TOOLCHAIN','clang','clang','gcc',d)}"
diff --git a/meta/meta-mediatek/classes/hsm-sign-env.bbclass b/meta/meta-mediatek/classes/hsm-sign-env.bbclass
new file mode 100644
index 0000000..4259bc1
--- /dev/null
+++ b/meta/meta-mediatek/classes/hsm-sign-env.bbclass
@@ -0,0 +1,33 @@
+python __anonymous () {
+    hsm_env_str = ""
+
+    hsm_support = d.getVar('HSM_SUPPORT', True)
+    if hsm_support != 'yes':
+        d.setVar('HSM_SIGN_TOOL','')
+        d.setVar('HSM_SIGN_PARAM','')
+        d.setVar('HSM_ENV', '')
+        return
+    hsm_env_str += "HSM_SUPPORT=yes "
+
+    top_dir = d.getVar('TOPDIR',True)
+    hsm_sign_tool_dir = top_dir+"/../src/devtools/hsmsigntool/"
+
+    hsm_sign_tool = hsm_sign_tool_dir+"hsm_sign_tool"
+    hsm_env_str += "HSM_SIGN_TOOL=\""+hsm_sign_tool+"\" "
+
+    hsm_sign_tool_conf = d.getVar('HSM_SIGN_TOOL_CONF',True)
+    if hsm_sign_tool_conf is None:
+        hsm_sign_tool_conf = hsm_sign_tool_dir+"hsm_sign_tool.conf"
+    hsm_env_str += "HSM_SIGN_TOOL_CONF=\""+hsm_sign_tool_conf+"\" "
+
+    verified_key = d.getVar('VERIFIED_KEY')
+    hsm_env_str += "VERIFIED_KEY=\""+verified_key+"\" "
+
+    softhsm2_conf = d.getVar('SOFTHSM2_CONF',True)
+    if softhsm2_conf is not None:
+        hsm_env_str += "SOFTHSM2_CONF=\""+softhsm2_conf+"\" "
+
+    d.setVar('HSM_SIGN_TOOL',hsm_sign_tool)
+    d.setVar('HSM_SIGN_PARAM',' --signing_helper '+hsm_sign_tool)
+    d.setVar('HSM_ENV', hsm_env_str)
+}
diff --git a/meta/meta-mediatek/classes/kernel-fitimage-extension.bbclass b/meta/meta-mediatek/classes/kernel-fitimage-extension.bbclass
new file mode 100644
index 0000000..95ea635
--- /dev/null
+++ b/meta/meta-mediatek/classes/kernel-fitimage-extension.bbclass
@@ -0,0 +1,275 @@
+inherit kernel-uboot-extension hsm-sign-env
+
+python __anonymous () {
+    kerneltype = d.getVar('KERNEL_IMAGETYPE', True)
+    if kerneltype == 'fitImage':
+        depends = d.getVar("DEPENDS", True)
+        depends = "%s u-boot-mkimage-native lz4-native dtc-native" % depends
+        d.setVar("DEPENDS", depends)
+
+        # Override KERNEL_IMAGETYPE_FOR_MAKE variable, which is internal
+        # to kernel.bbclass . We have to override it, since we pack zImage
+        # (at least for now) into the fitImage .
+        kernelarch = d.getVar('KERNEL_ARCH', True)
+        if kernelarch == 'arm':
+                d.setVar("KERNEL_IMAGETYPE_FOR_MAKE", "zImage")
+        elif kernelarch == 'arm64':
+                d.setVar("KERNEL_IMAGETYPE_FOR_MAKE", "Image")
+        else:
+                print("please set KERNEL_ARCH variable.")
+                sys.exit(1)
+        image = d.getVar('INITRAMFS_IMAGE', True)
+        if image:
+            d.appendVarFlag('do_assemble_fitimage', 'depends', ' ${INITRAMFS_IMAGE}:do_image_complete')
+}
+
+#
+# Emit the fitImage ITS header
+#
+fitimage_emit_fit_header() {
+        cat << EOF >> fit-image.its
+/dts-v1/;
+
+/ {
+        description = "U-Boot fitImage for ${DISTRO_NAME}/${PV}/${MACHINE}";
+        #address-cells = <1>;
+EOF
+}
+
+#
+# Emit the fitImage section bits
+#
+# $1 ... Section bit type: imagestart - image section start
+#                          confstart  - configuration section start
+#                          sectend    - section end
+#                          fitend     - fitimage end
+#
+fitimage_emit_section_maint() {
+        case $1 in
+        imagestart)
+                cat << EOF >> fit-image.its
+
+        images {
+EOF
+        ;;
+        confstart)
+                cat << EOF >> fit-image.its
+
+        configurations {
+EOF
+        ;;
+        sectend)
+                cat << EOF >> fit-image.its
+        };
+EOF
+        ;;
+        fitend)
+                cat << EOF >> fit-image.its
+};
+EOF
+        ;;
+        esac
+}
+
+#
+# Emit the fitImage ITS kernel section
+#
+# $1 ... Image counter
+# $2 ... Path to kernel image
+# $3 ... Compression type
+fitimage_emit_section_kernel() {
+
+        if [ -n "${IMAGE_HASH_ALGO}" ] ; then
+            kernel_csum="${IMAGE_HASH_ALGO}"
+        else
+            kernel_csum="sha256"
+        fi
+
+        ENTRYPOINT=${UBOOT_ENTRYPOINT}
+        if [ -n "${UBOOT_ENTRYSYMBOL}" ] ; then
+                ENTRYPOINT=`${HOST_PREFIX}nm ${S}/vmlinux | \
+                        awk '$3=="${UBOOT_ENTRYSYMBOL}" {print $1}'`
+        fi
+
+        cat << EOF >> fit-image.its
+                kernel@${1} {
+                        description = "Linux kernel";
+                        data = /incbin/("${2}");
+                        type = "kernel";
+                        arch = "${UBOOT_ARCH}";
+                        os = "linux";
+                        compression = "${3}";
+                        load = <${UBOOT_LOADADDRESS}>;
+                        entry = <${ENTRYPOINT}>;
+                        hash@1 {
+                                algo = "${kernel_csum}";
+                        };
+                };
+EOF
+}
+
+#
+# Emit the fitImage ITS DTB section
+#
+# $1 ... Image counter
+# $2 ... Path to DTB image
+fitimage_emit_section_dtb() {
+
+        if [ -n "${IMAGE_HASH_ALGO}" ] ; then
+            dtb_csum="${IMAGE_HASH_ALGO}"
+        else
+            dtb_csum="sha256"
+        fi
+
+        cat << EOF >> fit-image.its
+                fdt@${1} {
+                        description = "Flattened Device Tree blob";
+                        data = /incbin/("${2}");
+                        type = "flat_dt";
+                        arch = "${UBOOT_ARCH}";
+                        compression = "none";
+                        load = <${DTB_LOADADDRESS}>;
+                        hash@1 {
+                                algo = "${dtb_csum}";
+                        };
+                };
+EOF
+}
+
+#
+# Emit the fitImage ITS configuration section
+#
+# $1 ... Linux kernel ID
+# $2 ... DTB image ID
+fitimage_emit_section_config() {
+
+        if [ -n "${VB_HASH_ALGO}" -a -n "${VB_RSA_ALGO}" ] ; then
+            conf_csum="${VB_HASH_ALGO},${VB_RSA_ALGO}"
+        else
+            conf_csum="sha256,rsa2048"
+        fi
+        conf_key_name="dev"
+
+        # Test if we have any DTBs at all
+        if [ -z "${2}" ] ; then
+                conf_desc="Boot Linux kernel"
+                fdt_line=""
+        else
+                conf_desc="Boot Linux kernel with FDT blob"
+                fdt_line="fdt = \"fdt@${2}\";"
+        fi
+        kernel_line="kernel = \"kernel@${1}\";"
+
+        cat << EOF >> fit-image.its
+                default = "conf@1";
+                conf@1 {
+                        description = "${conf_desc}";
+                        ${kernel_line}
+                        ${fdt_line}
+                        signature@1 {
+                                algo = "${conf_csum}";
+                                key-name-hint="${conf_key_name}";
+                                sign-images="fdt","kernel";
+                        };
+                };
+EOF
+}
+
+do_assemble_fitimage() {
+        cd ${B}
+        if [ "x${KERNEL_IMAGETYPE}" = "xfitImage" ] ; then
+                kernelcount=1
+                dtbcount=""
+                rm -f fit-image.its
+
+                fitimage_emit_fit_header
+
+                #
+                # Step 1: Prepare a kernel image section.
+                #
+                fitimage_emit_section_maint imagestart
+
+                uboot_prep_kimage
+                fitimage_emit_section_kernel "${kernelcount}" linux.bin "${linux_comp}"
+
+                #
+                # Step 2: Prepare a DTB image section
+                #
+                if [ -n "${KERNEL_DEVICETREE}" ] ; then
+                        dtbcount=1
+                        for DTB in ${KERNEL_DEVICETREE}; do
+                                if echo ${DTB} | grep -q '/dts/'; then
+                                        bbwarn "${DTB} contains the full path to the the dts file, but only the dtb name should be used."
+                                        DTB=`basename ${DTB} | sed 's,\.dts$,.dtb,g'`
+                                fi
+
+                                # go through device tree blob dir for 32/64 bits kernel
+                                DTB_PATH="arch/${ARCH}/boot/dts/mediatek/${DTB}"
+                                if [ ! -e "${DTB_PATH}" ]; then
+                                        DTB_PATH="arch/${ARCH}/boot/dts/${DTB}"
+                                        if [ ! -e "${DTB_PATH}" ]; then
+                                                DTB_PATH="arch/${ARCH}/boot/${DTB}"
+                                        fi
+                                fi
+
+                                fitimage_emit_section_dtb ${dtbcount} ${DTB_PATH}
+                                dtbcount=`expr ${dtbcount} + 1`
+                        done
+                fi
+
+                fitimage_emit_section_maint sectend
+
+                # Force the first Kernel and DTB in the default config
+                kernelcount=1
+                dtbcount=1
+
+                #
+                # Step 3: Prepare a configurations section
+                #
+                fitimage_emit_section_maint confstart
+
+                fitimage_emit_section_config ${kernelcount} ${dtbcount}
+
+                fitimage_emit_section_maint sectend
+
+                fitimage_emit_section_maint fitend
+
+                #
+                # Step 4: Assemble the image
+                #
+
+                ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -f fit-image.its arch/${ARCH}/boot/fitImage
+
+                if [ "${SECURE_BOOT_ENABLE}" = "yes" -a "${STANDALONE_SIGN_PREPARE}" != "yes" ]; then
+                        mkdir -p ./mykeys
+                        cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.crt ./mykeys/dev.crt
+                        cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.pem ./mykeys/dev.key
+                        ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -D "-I dts -O dtb -p 1024" -k ./mykeys -f fit-image.its -r arch/${ARCH}/boot/fitImage
+                fi
+        fi
+}
+
+addtask assemble_fitimage before do_install after do_compile_kernelmodules
+
+kernel_do_deploy[vardepsexclude] = "DATETIME"
+kernel_do_deploy_append() {
+        # Update deploy directory
+        if [ "x${KERNEL_IMAGETYPE}" = "xfitImage" ] ; then
+                cd ${B}
+                echo "Copying fit-image.its source file..."
+                its_base_name="${KERNEL_IMAGETYPE}-its-${PV}-${PR}-${MACHINE}-${DATETIME}"
+                its_symlink_name=${KERNEL_IMAGETYPE}-its-${MACHINE}
+                install -m 0644 fit-image.its ${DEPLOYDIR}/${its_base_name}.its
+                linux_bin_base_name="${KERNEL_IMAGETYPE}-linux.bin-${PV}-${PR}-${MACHINE}-${DATETIME}"
+                linux_bin_symlink_name=${KERNEL_IMAGETYPE}-linux.bin-${MACHINE}
+                install -m 0644 linux.bin ${DEPLOYDIR}/${linux_bin_base_name}.bin
+                if [ -n "${RECOVERY_KERNEL_DEVICETREE}" ] ; then
+                        find arch/${ARCH}/boot/dts -name "${RECOVERY_KERNEL_DEVICETREE}" -exec install -m 0644 {} ${DEPLOYDIR}/${RECOVERY_KERNEL_DEVICETREE} \;
+                fi
+
+                cd ${DEPLOYDIR}
+                ln -sf ${its_base_name}.its ${its_symlink_name}.its
+                ln -sf ${linux_bin_base_name}.bin ${linux_bin_symlink_name}.bin
+                ln -nfs ${KERNEL_IMAGETYPE}-${KERNEL_IMAGE_NAME}.bin boot.img
+        fi
+}
diff --git a/meta/meta-mediatek/classes/kernel-uboot-extension.bbclass b/meta/meta-mediatek/classes/kernel-uboot-extension.bbclass
new file mode 100644
index 0000000..fc93a28
--- /dev/null
+++ b/meta/meta-mediatek/classes/kernel-uboot-extension.bbclass
@@ -0,0 +1,49 @@
+uboot_prep_kimage() {
+
+        linux_comp=${KERNEL_COMPRESS}
+
+        # uncompressed elf vmlinux
+        vmlinux_path="vmlinux"
+
+        if test "${linux_comp}" = "lz4"; then
+                linux_suffix=".lz4"
+        elif test "${linux_comp}" = "gzip"; then
+                linux_suffix=".gz"
+        else
+                # Use 32-Bit kernel's compression method since
+                # it's is a kind of self-extracting executable.
+                if test -f "arch/arm/boot/compressed/vmlinux"; then
+                        vmlinux_path="arch/arm/boot/compressed/vmlinux"
+                fi
+                linux_suffix=""
+        fi
+
+        ${OBJCOPY} -O binary -R .note -R .comment -S "${vmlinux_path}" linux.bin
+
+        if test "${linux_comp}" = "lz4"; then
+                lz4 -l -c1 linux.bin > linux.bin${linux_suffix}
+                # append uncompressed filesize info
+                dec_size=0
+                fsize=$(stat -c "%s" "linux.bin")
+                dec_size=$(expr $dec_size + $fsize)
+                printf "%08x\n" $dec_size |
+                        sed 's/\(..\)/\1 /g' | {
+                                read ch0 ch1 ch2 ch3;
+                                for ch in $ch3 $ch2 $ch1 $ch0; do
+                                        printf `printf '%s%03o' '\\' 0x$ch` >> linux.bin${linux_suffix};
+                                done;
+                        }
+        elif test "${linux_comp}" = "gzip"; then
+                gzip -9 linux.bin
+        else
+                echo "For none case or another compressing"
+        fi
+
+        if ! test "${linux_comp}" = "none"; then
+                mv -f "linux.bin${linux_suffix}" linux.bin
+        else
+                echo "No kerenl compression"
+        fi
+
+        echo "${linux_comp}"
+}
diff --git a/meta/meta-mediatek/classes/lk-image.bbclass b/meta/meta-mediatek/classes/lk-image.bbclass
new file mode 100644
index 0000000..f7e0ec6
--- /dev/null
+++ b/meta/meta-mediatek/classes/lk-image.bbclass
@@ -0,0 +1,499 @@
+inherit hsm-sign-env
+
+python __anonymous () {
+        depends = d.getVar("DEPENDS", True)
+        depends = "%s u-boot-mkimage-native dtc-native openssl-native" % depends
+        d.setVar("DEPENDS", depends)
+}
+
+# split input string to multiple quadbyte word (with 0x prefix for each word)
+# input:
+#   $1: input string, e.g., 0123456789ABCDEF...
+#   $2: "swap", to do byte swap in each quadbyte; otherwise, no swap
+# output:
+#   standard output: 0x67452301 0xEFCDAB89 ... if $2 = "swap"
+#                    0x01234567 0x89ABCDEF ... otherwise
+split_str_to_quadbytes() {
+        quadbytes=""
+
+        if [ $2 = "swap" ]; then
+                sed_cmd="sed s,\(..\)\(..\)\(..\)\(..\),\4\3\2\1,g"
+        else
+                sed_cmd="sed s,\(..\)\(..\)\(..\)\(..\),\1\2\3\4,g"
+        fi
+
+        if [ ! -z "$1" ]; then
+                for i in $(seq 1 8 ${#1}); do
+                        end_idx=`echo "${i} + 7" | bc`
+                        qb=`echo ${1} | cut -c${i}-${end_idx} | ${sed_cmd}`
+                        quadbytes="${quadbytes} 0x${qb}"
+                done
+                # trim leading space
+                awk '{$quadbytes=$quadbytes};1'
+        fi
+
+        echo $quadbytes
+}
+
+# Emit fit header
+# input param:
+#        $1: fit its
+fitimage_emit_fit_header() {
+        cat << EOF >> $1
+/dts-v1/;
+
+/ {
+        description = "bl";
+        #address-cells = <1>;
+EOF
+}
+
+# Emit the fitimage image section
+# input param:
+#        $1: fit its
+#        $2: path to padding binary
+#        $3: path to lk binary
+#        $4: lk load address
+#        $5: lk entry address
+#        $6: hash algorithm
+fitimage_emit_fit_image_section() {
+        cat << EOF >> $1
+
+        images {
+                bl@1 {
+                        description = "bl";
+                        padding = /incbin/("${2}");
+                        data = /incbin/("${3}");
+                        type = "kernel";
+                        compression = "none";
+                        load = <${4}>;
+                        entry = <${5}>;
+                        hash@1 {
+                                algo = "${6}";
+                        };
+                };
+        };
+EOF
+}
+
+# Emit fitimage configuration section
+# input param:
+#        $1: fit its
+#        $2: hash algorithm
+#        $3: rsa algorithm
+#        $4: key name hint
+#        $5: aes iv
+fitimage_emit_fit_conf_section() {
+        if [ "${ACK_EN}" = "yes" ]; then
+                # split aes iv to N 32-bit words
+                quadbytes=$(split_str_to_quadbytes ${5} noswap)
+                ack_iv_prop="ack_iv = <${quadbytes}>;"
+        else
+                ack_iv_prop=
+        fi
+
+        cat << EOF >> $1
+
+        configurations {
+                default = "conf@1";
+                conf@1 {
+                        description = "bl";
+                        kernel = "bl@1";
+                        ${ack_iv_prop}
+                        signature@1 {
+                                algo = "${2},${3}";
+                                key-name-hint = "${4}";
+                                sign-images = "kernel";
+                        };
+                };
+        };
+EOF
+}
+
+# Emit fitimage trusted-key-certificate oem section
+# input param:
+#        $1: fit its
+fitimage_emit_fit_tkc_oem_section() {
+        cat << EOF >> $1
+
+        trusted-key-certificate {
+                sign-node {
+                        device-check = "skip-device-id-check";
+                        device-id = "N0cI//dxndWXnsh11WzSKG9tPPfs";
+                        trusted-key {
+                                key-name-hint = "TierPubKey";
+                        };
+                };
+        };
+EOF
+}
+
+# Emit fitimage trusted-key-certificate tier section
+# input param:
+#        $1: fit its
+#        $2: TKC.dtsi
+fitimage_emit_fit_tkc_tier_section() {
+        cat << EOF >> $1
+
+        /include/ "$2"
+EOF
+}
+
+# Emit fitimage fit end
+# input param:
+#        $1: fit its
+fitimage_emit_fit_end() {
+        cat << EOF >> $1
+};
+EOF
+}
+
+# get_fit_data_offset: get data offset from fit image
+# input param:
+#        $1: fit image
+get_fit_data_offset() {
+        FIT_IMAGE=$1
+
+        TMPF=$(mktemp ${WORKDIR}/dump-fit-img.XXXXXX)
+
+        # dump fit image
+        fdtdump -d ${FIT_IMAGE} > ${TMPF}
+
+        # get props
+        LINE=$(grep -n '^ *data' ${TMPF} | grep -o '^[0-9]*')
+        LINE=`expr ${LINE} - 1`
+        ADDR=$(grep -n "^// [[:xdigit:]]*: value" ${TMPF} | grep "^${LINE}://" | \
+             grep -o " [[:xdigit:]]*" | grep -o "[[:xdigit:]]*")
+
+        # remove temp files
+        rm -f ${TMPF}
+
+        echo ${ADDR}
+}
+
+# check_fit_image: check fit image and also check load/entry address if 2nd
+#                  param was present
+# input param:
+#        $1: fit image
+#        $2: if present, will also check load and entry validity
+check_fit_image() {
+        FIT_IMAGE=$1
+        CHECK_OPT=$2
+
+        # check default cfg
+        CFG=$(fdtget ${FIT_IMAGE} /configurations default)
+        if [ "${CFG}" = "" ]; then
+                echo "ERROR: no default in /configurations"
+                exit 1
+        fi
+
+        # check image name
+        IMG_NAME=$(fdtget ${FIT_IMAGE} /configurations/${CFG} kernel)
+        if [ "${IMG_NAME}" = "" ]; then
+                echo "ERROR: no image name (kernel prop) in /configurations/${CFG}"
+                exit 1
+        fi
+
+        # check data
+        DATA=$(fdtget ${FIT_IMAGE} /images/${IMG_NAME} data)
+        if [ "${DATA}" = "" ]; then
+                echo "ERROR: no data in /images/${IMG_NAME}"
+                exit 1
+        fi
+
+        # check load
+        LOAD_D=$(fdtget ${FIT_IMAGE} /images/${IMG_NAME} load)
+        if [ "$LOAD_D" = "" ]; then
+                echo "ERROR: no load in /images/${IMG_NAME}"
+                exit 1
+        fi
+
+        # check entry
+        ENTRY_D=$(fdtget ${FIT_IMAGE} /images/${IMG_NAME} entry)
+        if [ "$ENTRY_D" = "" ]; then
+                echo "ERROR: no entry in /images/${IMG_NAME}"
+                exit 1
+        fi
+
+        if [ "${CHECK_OPT}" != "" ]; then
+                OFFSET=$(get_fit_data_offset ${FIT_IMAGE})
+                LOAD=$(printf "%x" ${LOAD_D})
+                if [ "`expr ${LOAD} : '.*\(....\)'`" != "${OFFSET}" ]; then
+                        echo ERROR: load ${LOAD} is not align with data offset ${OFFSET}
+                        exit 1
+                fi
+
+                LEN=$(echo ${DATA} | wc -w)
+                ENTRY=$(printf "%x" ${ENTRY_D})
+                END_D=`echo "${LOAD_D} + ${LEN} * 4" | bc`
+                END=$(printf "%x" ${END_D})
+                if [ ${ENTRY_D} -lt ${LOAD_D} -o ${END_D} -le ${ENTRY_D} ]; then
+                        echo ERROR: entry ${ENTRY} is not in data ${LOAD} - ${END}
+                        exit 1
+                fi
+        fi
+}
+
+# generate fit image: generate lk image in fit format
+# input param:
+#        $1: fit image its file
+#        $2: key dir
+#        $3: output file
+gen_fit_image() {
+        FIT_ITS=$1
+        KEYDIR=$2
+        OUT=$3
+        DTB=$(mktemp ${WORKDIR}/dtb.XXXXXX)
+        KEYDTSI=$(mktemp ${WORKDIR}/key.XXXXXX.dtsi)
+        KEYITS=$(mktemp ${WORKDIR}/key-fit-image.XXXXXX.its)
+
+        if [ "${SBC_SIGN_ALGO}" = "ecc" ]; then
+                case "${SBC_ECC_ALGO}" in
+                        nistp256)
+                                HSM_SBC_KEY=${SBC_KEY_ECC256}
+                                ;;
+                        nistp384)
+                                HSM_SBC_KEY=${SBC_KEY_ECC384}
+                                ;;
+                        nistp521)
+                                HSM_SBC_KEY=${SBC_KEY_ECC521}
+                                ;;
+                        *)
+                                echo ${SBC_ECC_ALGO} ": not supported."
+                                exit 1
+                                ;;
+                esac
+        else
+                case "${SBC_RSA_ALGO}" in
+                        rsa2048 | rsassa-pss2048)
+                                HSM_SBC_KEY=${SBC_KEY}
+                                ;;
+                        rsa3072 | rsassa-pss3072)
+                                HSM_SBC_KEY=${SBC_KEY_RSA3072}
+                                ;;
+                        rsa4096 | rsassa-pss4096)
+                                HSM_SBC_KEY=${SBC_KEY_RSA4096}
+                                ;;
+                        *)
+                                echo ${SBC_RSA_ALGO} ": not supported."
+                                exit 1
+                                ;;
+                esac
+        fi
+        echo "HSM_SBC_KEY name is ${HSM_SBC_KEY}"
+
+        echo "/dts-v1/; / {};" | dtc -O dtb > ${DTB}
+        if [ "${TKC_SUPPORT}" = "oem" ]; then
+                ${HSM_ENV} HSM_KEY_NAME=${HSM_SBC_KEY} ${FIT_IMG_TOOL} -f ${FIT_ITS} -k ${KEYDIR} -K ${DTB} -g ${TKC_PUBLIC_KEY_TIER} ${OUT}
+        elif [ "${TKC_SUPPORT}" = "tier" ]; then
+                ${HSM_ENV} HSM_KEY_NAME=${HSM_SBC_KEY} ${FIT_IMG_TOOL} -f ${FIT_ITS} -k ${KEYDIR} -K ${DTB} -u ${TKC_PUBLIC_KEY_OEM} ${OUT}
+        else
+                ${HSM_ENV} HSM_KEY_NAME=${HSM_SBC_KEY} ${FIT_IMG_TOOL} -f ${FIT_ITS} -k ${KEYDIR} -K ${DTB} ${OUT}
+        fi
+
+        dtc -I dtb ${DTB} | tail -n+2 > ${KEYDTSI}
+
+        sed "s,\/dts-v1\/;,\0\n\/include\/ \"${KEYDTSI}\"," < ${FIT_ITS} > ${KEYITS}
+        ${HSM_ENV} HSM_KEY_NAME=${HSM_SBC_KEY} ${FIT_IMG_TOOL} -f ${KEYITS} -k ${KEYDIR} ${OUT}
+
+        # remove temporary files
+        rm -f ${DTB} ${KEYDTSI} ${KEYITS}
+}
+
+# gen_sbc_key_hash
+# input param:
+#        $1: fit image
+gen_sbc_key_hash() {
+        FDT_IMG=$1
+        TMP_FILE=$(mktemp ${WORKDIR}/col_rgn.XXXXXX.bin)
+
+        DEF_CONF=`fdtget -t s ${FDT_IMG} /configurations default`
+        SIG_NODE=`fdtget -l ${FDT_IMG} /configurations/${DEF_CONF}`
+        KEY_HINT=`fdtget -t s ${FDT_IMG} /configurations/${DEF_CONF}/${SIG_NODE} key-name-hint`
+        SHAX=`fdtget -t s ${FDT_IMG} /configurations/${DEF_CONF}/${SIG_NODE} algo | cut -d, -f1`
+        ${WORKDIR}/fit-lk/extract_region ${FDT_IMG} ${TMP_FILE} /signature/key-${KEY_HINT}
+        KEY_HASH=`${SHAX}sum ${TMP_FILE} | cut -d " " -f 1`
+        echo "Hash algo: ${SHAX}"
+        echo "key_hash: ${KEY_HASH}"
+
+        key_hash_str=$(split_str_to_quadbytes ${KEY_HASH} swap)
+
+        idx=0
+        for qb in $key_hash_str; do
+                echo "keyhash_${idx}: ${qb}"
+                idx=`echo "${idx} + 1" | bc`
+        done
+
+        rm -f ${TMP_FILE}
+}
+
+# print_aes_key_iv
+#   $1: aes key
+#   $2: aes iv
+print_aes_key_iv() {
+        # print aes keys
+        echo "AES_KEY(AC_KEY)=${1}"
+        quadbytes=$(split_str_to_quadbytes ${1} swap)
+        idx=0
+        for qb in $quadbytes; do
+                echo "AC_KEY${idx}: ${qb}"
+                idx=`echo "${idx} + 1" | bc`
+        done
+
+        # print aes iv
+        echo "AES_IV=${2}"
+        quadbytes=$(split_str_to_quadbytes ${2} noswap)
+        echo "prop ack_iv=<${quadbytes}>"
+}
+
+gen_lk_fit_header() {
+        # generate temp files
+        BL_BIN=$(mktemp ${WORKDIR}/bl.XXXXXX.bin)
+        FIT_LK_IMG=${WORKDIR}/fit-lk.img
+        FIT_ITS=$(mktemp ${WORKDIR}/fit-bl-image.XXXXXX.its)
+        KEYDIR=${WORKDIR}/lk-key
+        PADDING=$(mktemp ${WORKDIR}/padding.XXXXXX.bin)
+
+        if [ "${ACK_EN}" = "yes" ]; then
+                # output AES encrypted BL image to working directory
+                openssl enc -e -aes-128-cbc -in ${LK_OUT}/build-${LK_PROJECT}/${LK_BINARY} \
+                        -out ${BL_BIN} -K ${AES_KEY} -iv ${AES_IV}
+        else
+                # copy raw lk binary to working directory
+                cp ${LK_OUT}/build-${LK_PROJECT}/${LK_BINARY} ${BL_BIN}
+        fi
+
+        # generate a zero-size padding binary
+        touch ${PADDING}
+
+        # prepare rsa key
+        mkdir -p ${KEYDIR}
+
+        if [ "${SBC_SIGN_ALGO}" = "ecc" ]; then
+                case "${SBC_ECC_ALGO}" in
+                        nistp256)
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY_ECC256}_priv.pem ${KEYDIR}/dev_priv.key
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY_ECC256}_public.pem ${KEYDIR}/dev_public.key
+                                ;;
+                        nistp384)
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY_ECC384}_priv.pem ${KEYDIR}/dev_priv.key
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY_ECC384}_public.pem ${KEYDIR}/dev_public.key
+                                ;;
+                        nistp521)
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY_ECC521}_priv.pem ${KEYDIR}/dev_priv.key
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY_ECC521}_public.pem ${KEYDIR}/dev_public.key
+                                ;;
+                        *)
+                                echo ${SBC_ECC_ALGO} ": not supported."
+                                exit 1
+                                ;;
+                esac
+        else
+                case "${SBC_RSA_ALGO}" in
+                        rsa2048 | rsassa-pss2048)
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY}.crt ${KEYDIR}/dev.crt
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY}.pem ${KEYDIR}/dev.key
+                                ;;
+                        rsa3072 | rsassa-pss3072)
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY_RSA3072}.crt ${KEYDIR}/dev.crt
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY_RSA3072}.pem ${KEYDIR}/dev.key
+                                ;;
+                        rsa4096 | rsassa-pss4096)
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY_RSA4096}.crt ${KEYDIR}/dev.crt
+                                cp -f ${MTK_KEY_DIR}/${SBC_KEY_RSA4096}.pem ${KEYDIR}/dev.key
+                                ;;
+                        *)
+                                echo ${SBC_RSA_ALGO} ": not supported."
+                                exit 1
+                                ;;
+                esac
+        fi
+
+        # key for trusted-key-certificate
+        if [ "${TKC_SUPPORT}" = "oem" ]; then
+                if [ "${SBC_SIGN_ALGO}" = "ecc" ]; then
+                        cp -f ${MTK_KEY_DIR}/${TKC_PUBLIC_KEY_TIER}.pem ${KEYDIR}/tier_public.key
+                elif [ "${SBC_SIGN_ALGO}" = "rsa" ]; then
+                        cp -f ${MTK_KEY_DIR}/${TKC_PUBLIC_KEY_TIER}.crt ${KEYDIR}/tier_public.crt
+                fi
+        elif [ "${TKC_SUPPORT}" = "tier" ]; then
+                if [ "${SBC_SIGN_ALGO}" = "ecc" ]; then
+                        cp -f ${MTK_KEY_DIR}/${TKC_PUBLIC_KEY_OEM}.pem ${KEYDIR}/oem_public.key
+                elif [ "${SBC_SIGN_ALGO}" = "rsa" ]; then
+                        cp -f ${MTK_KEY_DIR}/${TKC_PUBLIC_KEY_OEM}.crt ${KEYDIR}/oem_public.crt
+                fi
+        fi
+
+        # generate base its file
+        fitimage_emit_fit_header ${FIT_ITS}
+
+        # if TKC is supportted, place it here
+        if [ "${TKC_SUPPORT}" = "oem" ]; then
+                fitimage_emit_fit_tkc_oem_section ${FIT_ITS} ${SBC_HASH_ALGO} ${SBC_ECC_ALGO} dev
+        elif [ "${TKC_SUPPORT}" = "tier" ]; then
+                fitimage_emit_fit_tkc_tier_section ${FIT_ITS} ${MTK_KEY_DIR}/TKC.dtsi
+        fi
+
+        fitimage_emit_fit_image_section ${FIT_ITS} ${PADDING} ${BL_BIN} \
+                ${LK_LOADADDRESS} ${LK_ENTRYPOINT} ${IMAGE_HASH_ALGO}
+
+        if [ "${SBC_SIGN_ALGO}" = "ecc" ]; then
+                fitimage_emit_fit_conf_section ${FIT_ITS} ${SBC_HASH_ALGO} ${SBC_ECC_ALGO} dev ${AES_IV}
+        else
+                fitimage_emit_fit_conf_section ${FIT_ITS} ${SBC_HASH_ALGO} ${SBC_RSA_ALGO} dev ${AES_IV}
+        fi
+
+        fitimage_emit_fit_end ${FIT_ITS}
+
+        # 1st pass: generate fit-lk image to get padding size
+        gen_fit_image ${FIT_ITS} ${KEYDIR} ${FIT_LK_IMG}
+        check_fit_image ${FIT_LK_IMG}
+
+        # get data offset and calculate padding size
+        # padding size = lk load offset - data offset
+        DATA_OFFSET=$(get_fit_data_offset ${FIT_LK_IMG})
+        DATA_OFFSET_HEX=0x${DATA_OFFSET}
+        DATA_OFFSET_D=$(printf "%d" ${DATA_OFFSET_HEX})
+        LK_LOAD_OFFSET_D=$(printf "%d" ${LK_LOAD_OFFSET})
+        PADDING_SIZE=`echo "${LK_LOAD_OFFSET_D} - ${DATA_OFFSET_D}" | bc`
+
+        rm -f ${PADDING}
+        dd if=/dev/zero of=${PADDING} bs=1 count=${PADDING_SIZE}
+
+        # 2nd pass: generate final fit-lk image
+        gen_fit_image ${FIT_ITS} ${KEYDIR} ${FIT_LK_IMG}
+        check_fit_image ${FIT_LK_IMG} all
+
+        cp ${FIT_LK_IMG} ${WORKDIR}/${LK_IMAGE}
+
+        # gen key hash for convenience
+        gen_sbc_key_hash ${FIT_LK_IMG}
+
+        # output aes key and iv for reference
+        if [ "${ACK_EN}" = "yes" ]; then
+                print_aes_key_iv ${AES_KEY} ${AES_IV}
+        fi
+
+        # remove temp files
+        rm -f ${BL_BIN} ${FIT_ITS} ${PADDING}
+        rm -rf ${KEYDIR}
+}
+
+gen_lk_gfh_header() {
+        cp ${LK_OUT}/build-${LK_PROJECT}/${LK_BINARY} ${WORKDIR}/temp_gfh
+
+        if [ "${SECURE_BOOT_ENABLE}" = "yes" ]; then
+                cp ${MTK_KEY_DIR}/${SBC_KEY}.pem ${KEY_DIR}/root_prvk.pem
+        fi
+
+        python ${PBP_DIR}/pbp.py -g ${GFH_DIR}/${TARGET_PLATFORM}/gfh_conf.ini \
+               -i ${KEY_DIR}/lk_key.ini -func sign \
+               -o ${WORKDIR}/temp_gfh ${WORKDIR}/temp_gfh
+
+        if [ "${BOOTDEV_TYPE}" != "nand" ]; then
+                python ${DEV_INFO_HDR_TOOL} \
+                       ${BOOTDEV_TYPE} ${WORKDIR}/temp_gfh ${WORKDIR}/${LK_IMAGE}
+        else
+                cp ${WORKDIR}/temp_gfh ${WORKDIR}/${LK_IMAGE}
+        fi
+}
diff --git a/meta/meta-mediatek/classes/make_ota_full-package.bbclass b/meta/meta-mediatek/classes/make_ota_full-package.bbclass
new file mode 100644
index 0000000..d1e64e8
--- /dev/null
+++ b/meta/meta-mediatek/classes/make_ota_full-package.bbclass
@@ -0,0 +1,66 @@
+DEPENDS += "android-tools-fsutils-native abtools-native"
+HOSTTOOLS += "zip unzip"
+PATH_prepend = "/usr/local/jdk1.8.0_161/bin:${STAGING_DIR_NATIVE}${datadir}/abtools/scripts:"
+
+AFTER_CMD = "${@bb.utils.contains("BOARD_AVB_ENABLE","true", "do_avb_sign_img","do_image_complete",d)}"
+
+do_make_otafull_package() {
+	if [ "${AB_OTA_UPDATER}" = "yes" ]; then
+		export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${STAGING_DIR_NATIVE}/usr/lib
+		rm -rf ${DEPLOY_DIR_IMAGE}/target-files
+		mkdir ${DEPLOY_DIR_IMAGE}/target-files
+		mkdir ${DEPLOY_DIR_IMAGE}/target-files/IMAGES
+		mkdir ${DEPLOY_DIR_IMAGE}/target-files/SYSTEM
+		mkdir ${DEPLOY_DIR_IMAGE}/target-files/META
+		cp ${STAGING_DIR_NATIVE}/../rootfs/etc/update_engine/build.prop ${DEPLOY_DIR_IMAGE}/target-files/SYSTEM/
+		cp ${STAGING_DIR_NATIVE}/../rootfs/etc/update_engine/update_engine.conf ${DEPLOY_DIR_IMAGE}/target-files/META/update_engine_config.txt
+
+		if test -e ${DEPLOY_DIR_IMAGE}/target-files/META/misc_info.txt; then
+			rm ${DEPLOY_DIR_IMAGE}/target-files/META/misc_info.txt
+		fi
+		echo "recovery_api_version=3" >> ${DEPLOY_DIR_IMAGE}/target-files/META/misc_info.txt
+		echo "fstab_version=2" >> ${DEPLOY_DIR_IMAGE}/target-files/META/misc_info.txt
+		echo "ab_update=true" >> ${DEPLOY_DIR_IMAGE}/target-files/META/misc_info.txt
+
+		if [ ! -z "${AB_OTA_PARTITIONS}" ]; then
+			if test -e ${DEPLOY_DIR_IMAGE}/target-files/META/ab_partitions.txt; then
+				rm ${DEPLOY_DIR_IMAGE}/target-files/META/ab_partitions.txt
+			fi
+			tmp="${AB_OTA_PARTITIONS}"
+			for entry in $tmp ; do
+				echo $entry >> ${DEPLOY_DIR_IMAGE}/target-files/META/ab_partitions.txt
+				if [ ! -f ${DEPLOY_DIR_IMAGE}/$entry.img ]; then
+					if [ ! -n "${BUILD_ID}" ]; then
+						exit 0
+					fi
+				fi
+				cp  ${DEPLOY_DIR_IMAGE}/$entry.img  ${DEPLOY_DIR_IMAGE}/target-files/IMAGES/
+			done
+		fi
+		if test -e ${DEPLOY_DIR_IMAGE}/system.ext4 ; then
+			e2fsdroid ${DEPLOY_DIR_IMAGE}/system.ext4 -e  -B ${DEPLOY_DIR_IMAGE}/target-files/IMAGES/system.map
+		fi
+
+		if test "x${BOARD_AVB_ENABLE}" = "xtrue" ; then
+			echo "avb_enable=true" >> ${DEPLOY_DIR_IMAGE}/target-files/META/misc_info.txt
+			echo "avb_system_hashtree_enable=true" >> ${DEPLOY_DIR_IMAGE}/target-files/META/misc_info.txt
+			add_care_map_to_target_files.py ${DEPLOY_DIR_IMAGE}/target-files
+		fi
+
+		cd ${DEPLOY_DIR_IMAGE}/target-files && zip -r -q ../target-files.zip IMAGES META SYSTEM && cd -
+		ota_from_target_files.py -p ${STAGING_DIR_NATIVE} --signapk_shared_library_path=usr/lib --signapk_path=usr/bin/signapk.jar -k ${STAGING_DATADIR_NATIVE}/abtools/security/testkey ${DEPLOY_DIR_IMAGE}/target-files.zip ${DEPLOY_DIR_IMAGE}/ota_full.zip
+	else
+		exit 0
+	fi
+}
+
+create_misc_folder() {
+	if [ "${AB_OTA_UPDATER}" = "yes" ]; then
+		install -d ${IMAGE_ROOTFS}/misc
+	fi
+}
+
+ROOTFS_PREPROCESS_COMMAND += " create_misc_folder;"
+
+
+addtask do_make_otafull_package after ${AFTER_CMD} before do_build
diff --git a/meta/meta-mediatek/classes/mkchrome.bbclass b/meta/meta-mediatek/classes/mkchrome.bbclass
new file mode 100644
index 0000000..bd18dde
--- /dev/null
+++ b/meta/meta-mediatek/classes/mkchrome.bbclass
@@ -0,0 +1,52 @@
+CHROME_DIR_IMAGE_SIZE ?= "${MKUBIFS_CHROME_IMAGE_SZ}"
+CHROME_EXT4_IMAGE_SIZE ?= "${CHROME_IMAGE_SZ}"
+CHROME_DIR_IMAGE_PATH = "${DEPLOY_DIR_IMAGE}/chrome"
+CHROME_DIR_CONTENT = "${IMAGE_ROOTFS}/../chrome"
+
+IMAGE_FSTYPES_NO_WHITESPACE="$(echo "${IMAGE_FSTYPES}" | tr -d '[:space:]')"
+CHROME_FS_PARTITION = "chrome_fs.ubi"
+CHROME_PARTITION = "chrome.ubi"
+CHROME_PARTITION_EXT4 = "chrome.ext4"
+
+mk_chrome_image() {
+
+	mkdir -p ${CHROME_DIR_CONTENT}/tmp
+	mkdir -p ${CHROME_DIR_CONTENT}/etc
+	mkdir -p ${CHROME_DIR_CONTENT}/var
+	
+	install -d ${IMAGE_ROOTFS}/chrome
+	for i in ${CHROME_DIR_CONTENT}; do
+        CHROME_DIR_FILE_PATH=${CHROME_DIR_IMAGE_PATH}/${i##${CHROME_DIR_CONTENT}}
+        install -d ${CHROME_DIR_FILE_PATH}
+        if [ "$(ls -A ${i})" ]; then
+                cp -a ${i}/* ${CHROME_DIR_FILE_PATH}
+        else
+                echo "${i} is empty"
+        fi
+    done
+	
+    if test "${IMAGE_FSTYPES_NO_WHITESPACE}" = "ubi"; then
+	echo \[ubifs\] > ubinize.cfg
+	echo mode=ubi >> ubinize.cfg
+	echo image=${CHROME_FS_PARTITION} >> ubinize.cfg
+	echo vol_id=0 >> ubinize.cfg
+	echo vol_size=${MKUBIFS_CHROME_VOL_SZ}
+	echo vol_type=dynamic >> ubinize.cfg
+	echo vol_name=chrome >> ubinize.cfg
+	echo vol_flags=autoresize >> ubinize.cfg
+	dd if=/dev/zero of=${DEPLOY_DIR_IMAGE}/${CHROME_FS_PARTITION} seek=${CHROME_DIR_IMAGE_SIZE} count=0 bs=1k
+	mkfs.ubifs -r ${CHROME_DIR_FILE_PATH} ${MKUBIFS_CHROME_ARGS} -o ${CHROME_FS_PARTITION}
+	#ubinize -o ${CHROME_PARTITION} -m 2048 -p 128KiB -s 2048 ubinize.cfg
+	ubinize -o ${CHROME_PARTITION} ${UBINIZE_ARGS} ubinize.cfg
+	cp ${CHROME_PARTITION} ${DEPLOY_DIR_IMAGE}/${CHROME_PARTITION}
+    elif test "${IMAGE_FSTYPES_NO_WHITESPACE}" = "ext4"; then
+	dd if=/dev/zero of=${DEPLOY_DIR_IMAGE}/${CHROME_PARTITION_EXT4} seek=${CHROME_EXT4_IMAGE_SIZE} count=${CHROME_IMAGE_CNT} bs=1k
+	mkfs.ext4 -F -i 4096 ${DEPLOY_DIR_IMAGE}/${CHROME_PARTITION_EXT4} -d ${CHROME_DIR_IMAGE_PATH}
+    else
+	echo "No method to make ${IMAGE_FSTYPES_NO_WHITESPACE} type state image"
+    fi
+}
+
+ROOTFS_POSTPROCESS_COMMAND += " mk_chrome_image;"
+
+
diff --git a/meta/meta-mediatek/classes/mkstateimage.bbclass b/meta/meta-mediatek/classes/mkstateimage.bbclass
new file mode 100644
index 0000000..56535a3
--- /dev/null
+++ b/meta/meta-mediatek/classes/mkstateimage.bbclass
@@ -0,0 +1,50 @@
+STATE_DIR_IMAGE_SIZE ?= "131072"
+STATE_DIR_IMAGE_PATH = "${DEPLOY_DIR_IMAGE}/state"
+STATE_DIR_CONTENT ?= "${IMAGE_ROOTFS}/home ${IMAGE_ROOTFS}/var ${IMAGE_ROOTFS}/usr/lib/tmpfiles.d ${STATE_DIR_IMAGE_PATH}/usr/local ${STATE_DIR_IMAGE_PATH}/srv"
+IMAGE_FSTYPES_NO_WHITESPACE="$(echo "${IMAGE_FSTYPES}" | tr -d '[:space:]')"
+DEPENDS += "mtd-utils-native"
+
+mk_state_image() {
+    rm -rf ${STATE_DIR_IMAGE_PATH}
+    install -d ${STATE_DIR_CONTENT}
+    for i in ${STATE_DIR_CONTENT}; do
+        STATE_DIR_FILE_PATH=${STATE_DIR_IMAGE_PATH}/${i##${IMAGE_ROOTFS}}
+        install -d ${STATE_DIR_FILE_PATH}
+        cp -a ${i}/. ${STATE_DIR_FILE_PATH}
+    done
+
+    if test "${IMAGE_FSTYPES_NO_WHITESPACE}" = "ubi"; then
+        STATE_PARTITION="userdata.ubifs"
+        STATE_UBI="userdata.ubi"
+        STATE_UBINIZE_CFG="ubinize-state.cfg"
+        dd if=/dev/zero of=${DEPLOY_DIR_IMAGE}/${STATE_PARTITION} seek=${STATE_DIR_IMAGE_SIZE} count=0 bs=1k
+        cat << EOF > ${STATE_UBINIZE_CFG}
+[ubifs]
+mode=ubi
+image=${DEPLOY_DIR_IMAGE}/${STATE_PARTITION}
+vol_id=0
+vol_type=dynamic
+vol_name=state
+vol_flags=autoresize
+EOF
+        mkfs.ubifs -r ${STATE_DIR_IMAGE_PATH} -o ${DEPLOY_DIR_IMAGE}/${STATE_PARTITION} ${MKUBIFS_ARGS}
+        ubinize -o ${DEPLOY_DIR_IMAGE}/${STATE_UBI} ${UBINIZE_ARGS} ${STATE_UBINIZE_CFG}
+    elif test "${IMAGE_FSTYPES_NO_WHITESPACE}" = "ext4"; then
+        STATE_PARTITION="userdata.ext4"
+        dd if=/dev/zero of=${DEPLOY_DIR_IMAGE}/${STATE_PARTITION} seek=${STATE_DIR_IMAGE_SIZE} count=0 bs=1k
+        mkfs.ext4 -F -i 4096 ${DEPLOY_DIR_IMAGE}/${STATE_PARTITION} -d ${STATE_DIR_IMAGE_PATH}
+    else
+        echo "No method to make ${IMAGE_FSTYPES_NO_WHITESPACE} type state image"
+    fi
+}
+
+ROOTFS_POSTPROCESS_COMMAND += " mk_state_image;"
+
+mk_rootfs_folder() {
+    install -d ${IMAGE_ROOTFS}/mnt/userdata ${IMAGE_ROOTFS}/srv
+    if test "${DISTRO}" != "poky-agl"; then
+        install -d ${IMAGE_ROOTFS}/usr/local
+    fi
+}
+
+ROOTFS_PREPROCESS_COMMAND += " mk_rootfs_folder;"
diff --git a/meta/meta-mediatek/classes/mktinyrootfs.bbclass b/meta/meta-mediatek/classes/mktinyrootfs.bbclass
new file mode 100644
index 0000000..f387eda
--- /dev/null
+++ b/meta/meta-mediatek/classes/mktinyrootfs.bbclass
@@ -0,0 +1,28 @@
+STATE_DIR_CONTENT = "${IMAGE_ROOTFS}/../usrdata"
+
+mk_tinyrootfs_image() {
+	mkdir -p ${STATE_DIR_CONTENT}/tmp
+	mkdir -p ${STATE_DIR_CONTENT}/etc
+	mkdir -p ${STATE_DIR_CONTENT}/var
+	mkdir -p ${STATE_DIR_CONTENT}/usr
+	mkdir -p ${STATE_DIR_CONTENT}/usr/bin
+	mkdir -p ${STATE_DIR_CONTENT}/usr/sbin
+	mkdir -p ${STATE_DIR_CONTENT}/config
+
+	install -d ${STATE_DIR_CONTENT}
+	rm -fr ${IMAGE_ROOTFS}/usr/share/X11/xkb/rules/evdev.xml
+	rm -fr ${IMAGE_ROOTFS}/usr/share/X11/xkb/rules/base.xml
+	rm -fr ${IMAGE_ROOTFS}/usr/share/X11/xkb/symbols/nokia_vndr/rx-51
+	
+	rm -fr ${IMAGE_ROOTFS}/usr/lib/libQt5Test.so.5.8.0
+	rm -fr ${IMAGE_ROOTFS}/usr/lib/libQt5QuickTest.so.5.8.0
+	
+	rm -fr ${IMAGE_ROOTFS}/usr/lib/libmdp_prot.mt2701.so
+	rm -fr ${IMAGE_ROOTFS}/usr/lib/libmdp_prot.mt2712.so
+	rm -fr ${IMAGE_ROOTFS}/usr/lib/libmdp_prot.mt8173.so
+	rm -fr ${IMAGE_ROOTFS}/usr/share/weston/rawdata.rgb565
+}
+
+ROOTFS_POSTPROCESS_COMMAND += " mk_tinyrootfs_image;"
+
+
diff --git a/meta/meta-mediatek/classes/mkusrdata.bbclass b/meta/meta-mediatek/classes/mkusrdata.bbclass
new file mode 100644
index 0000000..657bc92
--- /dev/null
+++ b/meta/meta-mediatek/classes/mkusrdata.bbclass
@@ -0,0 +1,70 @@
+STATE_DIR_IMAGE_SIZE ?= "${MKUBIFS_USRDATA_IMAGE_SZ}"
+STATE_DIR_IMAGE_PATH = "${DEPLOY_DIR_IMAGE}/userdata"
+STATE_DIR_CONTENT = "${IMAGE_ROOTFS}/../usrdata"
+IMAGE_FSTYPES_NO_WHITESPACE="$(echo "${IMAGE_FSTYPES}" | tr -d '[:space:]')"
+USERDATA_FS_PARTITION = "userdata_fs.ubi"
+USERDATA_PARTITION = "userdata.ubi"
+CRYPT_HOST_TOOL = "${TOPDIR}/../src/devtools/nfsb/crypt_tool/crypt_host_tool"
+DEPENDS += "mtd-utils-native"
+mk_userdata_image() {
+	mkdir -p ${STATE_DIR_CONTENT}/tmp
+	mkdir -p ${STATE_DIR_CONTENT}/etc
+	mkdir -p ${STATE_DIR_CONTENT}/var
+	mkdir -p ${STATE_DIR_CONTENT}/usr
+	mkdir -p ${STATE_DIR_CONTENT}/usr/bin
+	mkdir -p ${STATE_DIR_CONTENT}/usr/sbin
+	mkdir -p ${STATE_DIR_CONTENT}/config
+
+	if [ -d ${IMAGE_ROOTFS}/data ]; then
+	  cp -a ${IMAGE_ROOTFS}/data/* ${STATE_DIR_CONTENT}
+	  rm -rf ${IMAGE_ROOTFS}/data/*
+	fi
+	if test "${CONFIG_ICU_SUPPORT}" = "no"; then
+		rm -fr ${IMAGE_ROOTFS}/usr/lib/libicudata.so.59.1
+		rm -fr ${IMAGE_ROOTFS}/usr/lib/libicui18n.so.59.1
+		rm -fr ${IMAGE_ROOTFS}/usr/lib/libicuuc.so.59.1
+	fi
+
+	rm -rf ${STATE_DIR_IMAGE_PATH}
+
+	install -d ${STATE_DIR_CONTENT}
+
+  for i in ${STATE_DIR_CONTENT}; do
+    STATE_DIR_FILE_PATH=${STATE_DIR_IMAGE_PATH}/${i##${STATE_DIR_CONTENT}}
+    install -d ${STATE_DIR_FILE_PATH}
+    if [ "$(ls -A ${i})" ]; then
+	cp -a ${i}/* ${STATE_DIR_FILE_PATH}
+    else
+	echo "${i} is empty"
+    fi
+  done
+
+  if test "${IMAGE_FSTYPES_NO_WHITESPACE}" = "ubi"; then
+	echo \[ubifs\] > ubinize.cfg
+	echo mode=ubi >> ubinize.cfg
+	echo image=${USERDATA_FS_PARTITION} >> ubinize.cfg
+	echo vol_id=0 >> ubinize.cfg
+	echo vol_size=${MKUBIFS_USRDATA_VOL_SZ}
+	echo vol_type=dynamic >> ubinize.cfg
+	echo vol_name=useradata >> ubinize.cfg
+	echo vol_flags=autoresize >> ubinize.cfg
+	dd if=/dev/zero of=${DEPLOY_DIR_IMAGE}/${USERDATA_FS_PARTITION} seek=${STATE_DIR_IMAGE_SIZE} count=0 bs=1k
+	mkfs.ubifs -r ${STATE_DIR_FILE_PATH} ${MKUBIFS_USRDATA_ARGS} -o ${USERDATA_FS_PARTITION}
+	ubinize -o ${USERDATA_PARTITION} ${UBINIZE_ARGS} ubinize.cfg
+	cp ${USERDATA_PARTITION} ${DEPLOY_DIR_IMAGE}/${USERDATA_PARTITION}
+  elif test "${IMAGE_FSTYPES_NO_WHITESPACE}" = "ext4"; then
+	STATE_PARTITION="userdata.ext4"
+	dd if=/dev/zero of=${DEPLOY_DIR_IMAGE}/${STATE_PARTITION} seek=${STATE_DIR_IMAGE_SIZE} count=${MKEXT4_USRDATA_CNT} bs=1k
+	mkfs.ext4 -F -i 4096 ${DEPLOY_DIR_IMAGE}/${STATE_PARTITION} -d ${STATE_DIR_IMAGE_PATH}
+	if test "${ENABLE_USRDATA_DM_CRYPT}" = "yes"; then
+		mv ${DEPLOY_DIR_IMAGE}/${STATE_PARTITION} ${DEPLOY_DIR_IMAGE}/plain_${STATE_PARTITION}
+		${CRYPT_HOST_TOOL} ${DM_CRYPT_ALG} `cat ${MTK_KEY_DIR}/${DM_CRYPT_KEY}` 0 0 ${DEPLOY_DIR_IMAGE}/plain_${STATE_PARTITION} ${DEPLOY_DIR_IMAGE}/${STATE_PARTITION} usrdata `cat ${MTK_KEY_DIR}/${DM_PROTECT_KEY}`
+	fi
+  else
+	echo "No method to make ${IMAGE_FSTYPES_NO_WHITESPACE} type state image"
+  fi
+}
+
+ROOTFS_POSTPROCESS_COMMAND += " mk_userdata_image;"
+
+
diff --git a/meta/meta-mediatek/classes/monitor-rootfs.bbclass b/meta/meta-mediatek/classes/monitor-rootfs.bbclass
new file mode 100644
index 0000000..a81daa2
--- /dev/null
+++ b/meta/meta-mediatek/classes/monitor-rootfs.bbclass
@@ -0,0 +1,16 @@
+inherit deploy

+

+rootfs_monitor() {

+    find ${IMAGE_ROOTFS} -type f -size +50k -print0 | xargs -0 du -h | sort -nr > ${IMAGE_ROOTFS}/rootfs_monitor.txt

+}

+

+do_deploy () {

+    install -d ${DEPLOYDIR}

+    cp ${IMAGE_ROOTFS}/rootfs_monitor.txt  ${DEPLOYDIR}

+}

+

+addtask deploy before do_mtdverity_for_rootfs after do_image_complete

+

+ROOTFS_POSTPROCESS_COMMAND += " rootfs_monitor;"

+

+

diff --git a/meta/meta-mediatek/classes/optee-build.bbclass b/meta/meta-mediatek/classes/optee-build.bbclass
new file mode 100644
index 0000000..ee6d1a5
--- /dev/null
+++ b/meta/meta-mediatek/classes/optee-build.bbclass
@@ -0,0 +1,4 @@
+TA_DEV_KIT_DIR ?= "${WORKDIR}/lib64-recipe-sysroot${includedir}/optee/export-user_ta"

+OPTEE_LIB64 ?= "${BASE_WORKDIR}/x86_64-linux/lib64-gcc-cross-aarch64/8.2.0-r0/recipe-sysroot-native/usr/lib/"

+OPTEE_BULID_SA ?= "${BASE_WORKDIR}/aarch64-pokymllib64-linux/lib64-optee-os/3.2.0-r0/recipe-sysroot-native/usr/libexec/aarch64-pokymllib64-linux/gcc/aarch64-pokymllib64-linux/8.2.0/"

+TEE_TOOLCHAIN ?= "${OPTEE_BULID_SA}aarch64-pokymllib64-linux-"
\ No newline at end of file
diff --git a/meta/meta-mediatek/classes/pack-abupdate-zip.bbclass b/meta/meta-mediatek/classes/pack-abupdate-zip.bbclass
new file mode 100644
index 0000000..63ce430
--- /dev/null
+++ b/meta/meta-mediatek/classes/pack-abupdate-zip.bbclass
@@ -0,0 +1,11 @@
+IMAGE_PATH = "${DEPLOY_DIR_IMAGE}"
+IMAGE_LIST = "${IMAGE_PATH}/boot.img \
+              ${IMAGE_PATH}/system.img "
+DEPENDS += "zip-native"
+
+do_packing_images_post_funcs() {
+    zip -j ${IMAGE_PATH}/abupdate.zip ${IMAGE_LIST}
+}
+
+addtask packing_images_post_funcs after do_avb_sign_img before do_build
+
diff --git a/meta/meta-mediatek/classes/pack-update-zip-mt8183.bbclass b/meta/meta-mediatek/classes/pack-update-zip-mt8183.bbclass
new file mode 100644
index 0000000..e7f4880
--- /dev/null
+++ b/meta/meta-mediatek/classes/pack-update-zip-mt8183.bbclass
@@ -0,0 +1,15 @@
+IMAGE_PATH = "${DEPLOY_DIR_IMAGE}"
+IMAGE_LIST = "${IMAGE_PATH}/tee.img  \
+              ${IMAGE_PATH}/boot.img  \
+              ${IMAGE_PATH}/system.ext4 \
+              ${IMAGE_PATH}/system.ubi \
+              ${IMAGE_PATH}/recovery.ext4 \
+              ${IMAGE_PATH}/recovery.ubi "
+DEPENDS += "zip-native"
+
+do_packing_images_post_funcs() {
+        zip -j ${IMAGE_PATH}/update.zip ${IMAGE_LIST}
+}
+
+addtask packing_images_post_funcs after do_image_complete before do_build
+
diff --git a/meta/meta-mediatek/classes/pack-update-zip.bbclass b/meta/meta-mediatek/classes/pack-update-zip.bbclass
new file mode 100755
index 0000000..87beac9
--- /dev/null
+++ b/meta/meta-mediatek/classes/pack-update-zip.bbclass
@@ -0,0 +1,17 @@
+IMAGE_PATH = "${DEPLOY_DIR_IMAGE}"
+IMAGE_LIST = "${IMAGE_PATH}/tee.img  \
+              ${IMAGE_PATH}/boot.img  \
+              ${IMAGE_PATH}/system.ext4 \
+              ${IMAGE_PATH}/system.ubi \
+              ${IMAGE_PATH}/recovery.ext4 \
+              ${IMAGE_PATH}/recovery.ubi \
+              ${IMAGE_PATH}/chrome.ext4 \
+              ${IMAGE_PATH}/chrome.ubi "
+DEPENDS += "zip-native"
+
+do_packing_images_post_funcs() {
+        zip -j ${IMAGE_PATH}/update.zip ${IMAGE_LIST}
+}
+
+addtask packing_images_post_funcs after do_image_qa before do_build
+
diff --git a/meta/meta-mediatek/classes/packagebbclassappend.bbclass b/meta/meta-mediatek/classes/packagebbclassappend.bbclass
new file mode 100644
index 0000000..2d3bb85
--- /dev/null
+++ b/meta/meta-mediatek/classes/packagebbclassappend.bbclass
@@ -0,0 +1,577 @@
+inherit package
+
+def splitdebuginfo(file, dvar, debugdir, debuglibdir, debugappend, debugsrcdir, sourcefile, d):
+    # Function to split a single file into two components, one is the stripped
+    # target system binary, the other contains any debugging information. The
+    # two files are linked to reference each other.
+    #
+    # sourcefile is also generated containing a list of debugsources
+
+    import stat
+    import subprocess
+
+    src = file[len(dvar):]
+    dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
+    debugfile = dvar + dest
+    # Split the file...
+    bb.utils.mkdirhier(os.path.dirname(debugfile))
+    #bb.note("Split %s -> %s" % (file, debugfile))
+    # Only store off the hard link reference if we successfully split!
+
+    dvar = d.getVar('PKGD')
+    objcopy = d.getVar("OBJCOPY")
+
+    # We ignore kernel modules, we don't generate debug info files.
+    if file.find("/lib/modules/") != -1 and file.endswith(".ko"):
+        return 1
+
+    newmode = None
+    if os.path.exists(file):
+        if not os.access(file, os.W_OK) or os.access(file, os.R_OK):
+            origmode = os.stat(file)[stat.ST_MODE]
+            newmode = origmode | stat.S_IWRITE | stat.S_IREAD
+            os.chmod(file, newmode)
+
+        # We need to extract the debug src information here...
+        if debugsrcdir:
+            append_source_info(file, sourcefile, d)
+
+        bb.utils.mkdirhier(os.path.dirname(debugfile))
+
+        if os.path.basename(src) != "udevd" and os.path.basename(src) != "init":
+            subprocess.check_output([objcopy, file, debugfile], stderr=subprocess.STDOUT)
+
+        # Set the debuglink to have the view of the file path on the target
+        if not cpath.islink(file):
+            subprocess.check_output([objcopy, '--add-gnu-debuglink', debugfile, file], stderr=subprocess.STDOUT)
+
+        if newmode:
+            os.chmod(file, origmode)
+
+    return 0
+
+python split_and_strip_files () {
+    import stat, errno
+    import subprocess
+
+    dvar = d.getVar('PKGD')
+    pn = d.getVar('PN')
+    targetos = d.getVar('TARGET_OS')
+
+    oldcwd = os.getcwd()
+    os.chdir(dvar)
+
+    # We default to '.debug' style
+    if d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-file-directory':
+        # Single debug-file-directory style debug info
+        debugappend = ".debug"
+        debugdir = ""
+        debuglibdir = "/usr/lib/debug"
+        debugsrcdir = "/usr/src/debug"
+    elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-without-src':
+        # Original OE-core, a.k.a. ".debug", style debug info, but without sources in /usr/src/debug
+        debugappend = ""
+        debugdir = "/.debug"
+        debuglibdir = ""
+        debugsrcdir = ""
+    elif d.getVar('PACKAGE_DEBUG_SPLIT_STYLE') == 'debug-with-srcpkg':
+        debugappend = ""
+        debugdir = "/.debug"
+        debuglibdir = ""
+        debugsrcdir = "/usr/src/debug"
+    else:
+        # Original OE-core, a.k.a. ".debug", style debug info
+        debugappend = ""
+        debugdir = "/.debug"
+        debuglibdir = ""
+        debugsrcdir = "/usr/src/debug"
+
+    sourcefile = d.expand("${WORKDIR}/debugsources.list")
+    bb.utils.remove(sourcefile)
+
+    #
+    # First lets figure out all of the files we may have to process ... do this only once!
+    #
+    elffiles = {}
+    symlinks = {}
+    kernmods = []
+    staticlibs = []
+    inodes = {}
+    libdir = os.path.abspath(dvar + os.sep + d.getVar("libdir"))
+    baselibdir = os.path.abspath(dvar + os.sep + d.getVar("base_libdir"))
+    skipfiles = (d.getVar("INHIBIT_PACKAGE_STRIP_FILES") or "").split()
+    if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1' or \
+            d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'):
+        checkelf = {}
+        checkelflinks = {}
+        for root, dirs, files in cpath.walk(dvar):
+            for f in files:
+                file = os.path.join(root, f)
+                if file.endswith(".ko") and file.find("/lib/modules/") != -1:
+                    kernmods.append(file)
+                    continue
+                if oe.package.is_static_lib(file):
+                    staticlibs.append(file)
+                    continue
+
+                # Skip debug files
+                if debugappend and file.endswith(debugappend):
+                    continue
+                if debugdir and debugdir in os.path.dirname(file[len(dvar):]):
+                    continue
+
+                if file in skipfiles:
+                    continue
+
+                try:
+                    ltarget = cpath.realpath(file, dvar, False)
+                    s = cpath.lstat(ltarget)
+                except OSError as e:
+                    (err, strerror) = e.args
+                    if err != errno.ENOENT:
+                        raise
+                    # Skip broken symlinks
+                    continue
+                if not s:
+                    continue
+                # Check its an executable
+                if (s[stat.ST_MODE] & stat.S_IXUSR) or (s[stat.ST_MODE] & stat.S_IXGRP) or (s[stat.ST_MODE] & stat.S_IXOTH) \
+                        or ((file.startswith(libdir) or file.startswith(baselibdir)) and (".so" in f or ".node" in f)):
+
+                    if cpath.islink(file):
+                        checkelflinks[file] = ltarget
+                        continue
+                    # Use a reference of device ID and inode number to identify files
+                    file_reference = "%d_%d" % (s.st_dev, s.st_ino)
+                    checkelf[file] = (file, file_reference)
+
+        results = oe.utils.multiprocess_launch(oe.package.is_elf, checkelflinks.values(), d)
+        results_map = {}
+        for (ltarget, elf_file) in results:
+            results_map[ltarget] = elf_file
+        for file in checkelflinks:
+            ltarget = checkelflinks[file]
+            # If it's a symlink, and points to an ELF file, we capture the readlink target
+            if results_map[ltarget]:
+                target = os.readlink(file)
+                #bb.note("Sym: %s (%d)" % (ltarget, results_map[ltarget]))
+                symlinks[file] = target
+
+        results = oe.utils.multiprocess_launch(oe.package.is_elf, checkelf.keys(), d)
+        for (file, elf_file) in results:
+            # It's a file (or hardlink), not a link
+            # ...but is it ELF, and is it already stripped?
+            if elf_file & 1:
+                if elf_file & 2:
+                    if 'already-stripped' in (d.getVar('INSANE_SKIP_' + pn) or "").split():
+                        bb.note("Skipping file %s from %s for already-stripped QA test" % (file[len(dvar):], pn))
+                    else:
+                        msg = "File '%s' from %s was already stripped, this will prevent future debugging!" % (file[len(dvar):], pn)
+                        package_qa_handle_error("already-stripped", msg, d)
+                    continue
+
+                # At this point we have an unstripped elf file. We need to:
+                #  a) Make sure any file we strip is not hardlinked to anything else outside this tree
+                #  b) Only strip any hardlinked file once (no races)
+                #  c) Track any hardlinks between files so that we can reconstruct matching debug file hardlinks
+
+                # Use a reference of device ID and inode number to identify files
+                file_reference = checkelf[file][1]
+                if file_reference in inodes:
+                    os.unlink(file)
+                    os.link(inodes[file_reference][0], file)
+                    inodes[file_reference].append(file)
+                else:
+                    inodes[file_reference] = [file]
+                    # break hardlink
+                    bb.utils.break_hardlinks(file)
+                    elffiles[file] = elf_file
+                # Modified the file so clear the cache
+                cpath.updatecache(file)
+
+    #
+    # First lets process debug splitting
+    #
+    if (d.getVar('INHIBIT_PACKAGE_DEBUG_SPLIT') != '1'):
+        oe.utils.multiprocess_launch(splitdebuginfo, list(elffiles), d, extraargs=(dvar, debugdir, debuglibdir, debugappend, debugsrcdir, sourcefile, d))
+
+        # Add this line to keep link so(like libc.so.6) in dbg-rpm dir.
+        oe.utils.multiprocess_launch(splitdebuginfo, list(symlinks), d, extraargs=(dvar, debugdir, debuglibdir, debugappend, debugsrcdir, sourcefile, d))
+
+        if debugsrcdir and not targetos.startswith("mingw"):
+            for file in staticlibs:
+                append_source_info(file, sourcefile, d, fatal=False)
+
+        # Hardlink our debug symbols to the other hardlink copies
+        for ref in inodes:
+            if len(inodes[ref]) == 1:
+                continue
+
+            target = inodes[ref][0][len(dvar):]
+            for file in inodes[ref][1:]:
+                src = file[len(dvar):]
+                dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(target) + debugappend
+                fpath = dvar + dest
+                ftarget = dvar + debuglibdir + os.path.dirname(target) + debugdir + "/" + os.path.basename(target) + debugappend
+                bb.utils.mkdirhier(os.path.dirname(fpath))
+                # Only one hardlink of separated debug info file in each directory
+                if not os.access(fpath, os.R_OK):
+                    #bb.note("Link %s -> %s" % (fpath, ftarget))
+                    os.link(ftarget, fpath)
+
+        # Create symlinks for all cases we were able to split symbols
+        for file in symlinks:
+            src = file[len(dvar):]
+            dest = debuglibdir + os.path.dirname(src) + debugdir + "/" + os.path.basename(src) + debugappend
+            fpath = dvar + dest
+            # Skip it if the target doesn't exist
+            try:
+                s = os.stat(fpath)
+            except OSError as e:
+                (err, strerror) = e.args
+                if err != errno.ENOENT:
+                    raise
+                continue
+
+            ltarget = symlinks[file]
+            lpath = os.path.dirname(ltarget)
+            lbase = os.path.basename(ltarget)
+            ftarget = ""
+            if lpath and lpath != ".":
+                ftarget += lpath + debugdir + "/"
+            ftarget += lbase + debugappend
+            if lpath.startswith(".."):
+                ftarget = os.path.join("..", ftarget)
+            bb.utils.mkdirhier(os.path.dirname(fpath))
+            #bb.note("Symlink %s -> %s" % (fpath, ftarget))
+            if not os.path.exists(fpath):
+                os.symlink(ftarget, fpath)
+
+        # Process the debugsrcdir if requested...
+        # This copies and places the referenced sources for later debugging...
+        copydebugsources(debugsrcdir, d)
+    #
+    # End of debug splitting
+    #
+
+    #
+    # Now lets go back over things and strip them
+    #
+    if (d.getVar('INHIBIT_PACKAGE_STRIP') != '1'):
+        strip = d.getVar("STRIP")
+        sfiles = []
+        for file in elffiles:
+            elf_file = int(elffiles[file])
+            #bb.note("Strip %s" % file)
+            sfiles.append((file, elf_file, strip))
+        for f in kernmods:
+            sfiles.append((f, 16, strip))
+
+        oe.utils.multiprocess_launch(oe.package.runstrip, sfiles, d)
+
+    #
+    # End of strip
+    #
+    os.chdir(oldcwd)
+}
+
+python package_do_shlibs() {
+    import re, pipes
+    import subprocess
+
+    exclude_shlibs = d.getVar('EXCLUDE_FROM_SHLIBS', False)
+    if exclude_shlibs:
+        bb.note("not generating shlibs")
+        return
+
+    lib_re = re.compile("^.*\.so")
+    libdir_re = re.compile(".*/%s$" % d.getVar('baselib'))
+
+    packages = d.getVar('PACKAGES')
+
+    shlib_pkgs = []
+    exclusion_list = d.getVar("EXCLUDE_PACKAGES_FROM_SHLIBS")
+    if exclusion_list:
+        for pkg in packages.split():
+            if pkg not in exclusion_list.split():
+                shlib_pkgs.append(pkg)
+            else:
+                bb.note("not generating shlibs for %s" % pkg)
+    else:
+        shlib_pkgs = packages.split()
+
+    targetos = d.getVar('TARGET_OS')
+
+    workdir = d.getVar('WORKDIR')
+
+    ver = d.getVar('PKGV')
+    if not ver:
+        msg = "PKGV not defined"
+        package_qa_handle_error("pkgv-undefined", msg, d)
+        return
+
+    pkgdest = d.getVar('PKGDEST')
+
+    shlibswork_dir = d.getVar('SHLIBSWORKDIR')
+
+    def linux_so(file, pkg, pkgver, d):
+        needs_ldconfig = False
+        needed = set()
+        sonames = set()
+        renames = []
+        if "-dbg" in pkg:
+            return (needs_ldconfig, needed, sonames, renames)
+
+        ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
+        cmd = d.getVar('OBJDUMP') + " -p " + pipes.quote(file) + " 2>/dev/null"
+        fd = os.popen(cmd)
+        lines = fd.readlines()
+        fd.close()
+        rpath = tuple()
+        for l in lines:
+            m = re.match("\s+RPATH\s+([^\s]*)", l)
+            if m:
+                rpaths = m.group(1).replace("$ORIGIN", ldir).split(":")
+                rpath = tuple(map(os.path.normpath, rpaths))
+        for l in lines:
+            m = re.match("\s+NEEDED\s+([^\s]*)", l)
+            if m:
+                dep = m.group(1)
+                if dep not in needed:
+                    needed.add((dep, file, rpath))
+            m = re.match("\s+SONAME\s+([^\s]*)", l)
+            if m:
+                this_soname = m.group(1)
+                prov = (this_soname, ldir, pkgver)
+                if not prov in sonames:
+                    # if library is private (only used by package) then do not build shlib for it
+                    if not private_libs or this_soname not in private_libs:
+                        sonames.add(prov)
+                if libdir_re.match(os.path.dirname(file)):
+                    needs_ldconfig = True
+                if snap_symlinks and (os.path.basename(file) != this_soname):
+                    renames.append((file, os.path.join(os.path.dirname(file), this_soname)))
+        return (needs_ldconfig, needed, sonames, renames)
+
+    def darwin_so(file, needed, sonames, renames, pkgver):
+        if not os.path.exists(file):
+            return
+        ldir = os.path.dirname(file).replace(pkgdest + "/" + pkg, '')
+
+        def get_combinations(base):
+            #
+            # Given a base library name, find all combinations of this split by "." and "-"
+            #
+            combos = []
+            options = base.split(".")
+            for i in range(1, len(options) + 1):
+                combos.append(".".join(options[0:i]))
+            options = base.split("-")
+            for i in range(1, len(options) + 1):
+                combos.append("-".join(options[0:i]))
+            return combos
+
+        if (file.endswith('.dylib') or file.endswith('.so')) and not pkg.endswith('-dev') and not pkg.endswith('-dbg') and not pkg.endswith('-src'):
+            # Drop suffix
+            name = os.path.basename(file).rsplit(".",1)[0]
+            # Find all combinations
+            combos = get_combinations(name)
+            for combo in combos:
+                if not combo in sonames:
+                    prov = (combo, ldir, pkgver)
+                    sonames.add(prov)
+        if file.endswith('.dylib') or file.endswith('.so'):
+            rpath = []
+            p = subprocess.Popen([d.expand("${HOST_PREFIX}otool"), '-l', file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+            out, err = p.communicate()
+            # If returned successfully, process stdout for results
+            if p.returncode == 0:
+                for l in out.split("\n"):
+                    l = l.strip()
+                    if l.startswith('path '):
+                        rpath.append(l.split()[1])
+
+        p = subprocess.Popen([d.expand("${HOST_PREFIX}otool"), '-L', file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        out, err = p.communicate()
+        # If returned successfully, process stdout for results
+        if p.returncode == 0:
+            for l in out.split("\n"):
+                l = l.strip()
+                if not l or l.endswith(":"):
+                    continue
+                if "is not an object file" in l:
+                    continue
+                name = os.path.basename(l.split()[0]).rsplit(".", 1)[0]
+                if name and name not in needed[pkg]:
+                     needed[pkg].add((name, file, tuple()))
+
+    def mingw_dll(file, needed, sonames, renames, pkgver):
+        if not os.path.exists(file):
+            return
+
+        if file.endswith(".dll"):
+            # assume all dlls are shared objects provided by the package
+            sonames.add((os.path.basename(file), os.path.dirname(file).replace(pkgdest + "/" + pkg, ''), pkgver))
+
+        if (file.endswith(".dll") or file.endswith(".exe")):
+            # use objdump to search for "DLL Name: .*\.dll"
+            p = subprocess.Popen([d.expand("${HOST_PREFIX}objdump"), "-p", file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+            out, err = p.communicate()
+            # process the output, grabbing all .dll names
+            if p.returncode == 0:
+                for m in re.finditer("DLL Name: (.*?\.dll)$", out.decode(), re.MULTILINE | re.IGNORECASE):
+                    dllname = m.group(1)
+                    if dllname:
+                        needed[pkg].add((dllname, file, tuple()))
+
+    if d.getVar('PACKAGE_SNAP_LIB_SYMLINKS') == "1":
+        snap_symlinks = True
+    else:
+        snap_symlinks = False
+
+    use_ldconfig = bb.utils.contains('DISTRO_FEATURES', 'ldconfig', True, False, d)
+
+    needed = {}
+
+    # Take shared lock since we're only reading, not writing
+    lf = bb.utils.lockfile(d.expand("${PACKAGELOCK}"), True)
+    shlib_provider = oe.package.read_shlib_providers(d)
+    bb.utils.unlockfile(lf)
+
+    for pkg in shlib_pkgs:
+        private_libs = d.getVar('PRIVATE_LIBS_' + pkg) or d.getVar('PRIVATE_LIBS') or ""
+        private_libs = private_libs.split()
+        needs_ldconfig = False
+        bb.debug(2, "calculating shlib provides for %s" % pkg)
+
+        pkgver = d.getVar('PKGV_' + pkg)
+        if not pkgver:
+            pkgver = d.getVar('PV_' + pkg)
+        if not pkgver:
+            pkgver = ver
+
+        needed[pkg] = set()
+        sonames = set()
+        renames = []
+        linuxlist = []
+        for file in pkgfiles[pkg]:
+                soname = None
+                if cpath.islink(file):
+                    continue
+                if targetos == "darwin" or targetos == "darwin8":
+                    darwin_so(file, needed, sonames, renames, pkgver)
+                elif targetos.startswith("mingw"):
+                    mingw_dll(file, needed, sonames, renames, pkgver)
+                elif os.access(file, os.X_OK) or lib_re.match(file):
+                    linuxlist.append(file)
+
+        if linuxlist:
+            results = oe.utils.multiprocess_launch(linux_so, linuxlist, d, extraargs=(pkg, pkgver, d))
+            for r in results:
+                ldconfig = r[0]
+                needed[pkg] |= r[1]
+                sonames |= r[2]
+                renames.extend(r[3])
+                needs_ldconfig = needs_ldconfig or ldconfig
+
+        for (old, new) in renames:
+            bb.note("Renaming %s to %s" % (old, new))
+            os.rename(old, new)
+            pkgfiles[pkg].remove(old)
+
+        shlibs_file = os.path.join(shlibswork_dir, pkg + ".list")
+        if len(sonames):
+            fd = open(shlibs_file, 'w')
+            for s in sonames:
+                if s[0] in shlib_provider and s[1] in shlib_provider[s[0]]:
+                    (old_pkg, old_pkgver) = shlib_provider[s[0]][s[1]]
+                    if old_pkg != pkg:
+                        bb.warn('%s-%s was registered as shlib provider for %s, changing it to %s-%s because it was built later' % (old_pkg, old_pkgver, s[0], pkg, pkgver))
+                bb.debug(1, 'registering %s-%s as shlib provider for %s' % (pkg, pkgver, s[0]))
+                fd.write(s[0] + ':' + s[1] + ':' + s[2] + '\n')
+                if s[0] not in shlib_provider:
+                    shlib_provider[s[0]] = {}
+                shlib_provider[s[0]][s[1]] = (pkg, pkgver)
+            fd.close()
+        if needs_ldconfig and use_ldconfig:
+            bb.debug(1, 'adding ldconfig call to postinst for %s' % pkg)
+            postinst = d.getVar('pkg_postinst_%s' % pkg)
+            if not postinst:
+                postinst = '#!/bin/sh\n'
+            postinst += d.getVar('ldconfig_postinst_fragment')
+            d.setVar('pkg_postinst_%s' % pkg, postinst)
+        bb.debug(1, 'LIBNAMES: pkg %s sonames %s' % (pkg, sonames))
+
+    assumed_libs = d.getVar('ASSUME_SHLIBS')
+    if assumed_libs:
+        libdir = d.getVar("libdir")
+        for e in assumed_libs.split():
+            l, dep_pkg = e.split(":")
+            lib_ver = None
+            dep_pkg = dep_pkg.rsplit("_", 1)
+            if len(dep_pkg) == 2:
+                lib_ver = dep_pkg[1]
+            dep_pkg = dep_pkg[0]
+            if l not in shlib_provider:
+                shlib_provider[l] = {}
+            shlib_provider[l][libdir] = (dep_pkg, lib_ver)
+
+    libsearchpath = [d.getVar('libdir'), d.getVar('base_libdir')]
+
+    for pkg in shlib_pkgs:
+        bb.debug(2, "calculating shlib requirements for %s" % pkg)
+
+        private_libs = d.getVar('PRIVATE_LIBS_' + pkg) or d.getVar('PRIVATE_LIBS') or ""
+        private_libs = private_libs.split()
+
+        deps = list()
+        for n in needed[pkg]:
+            # if n is in private libraries, don't try to search provider for it
+            # this could cause problem in case some abc.bb provides private
+            # /opt/abc/lib/libfoo.so.1 and contains /usr/bin/abc depending on system library libfoo.so.1
+            # but skipping it is still better alternative than providing own
+            # version and then adding runtime dependency for the same system library
+            if private_libs and n[0] in private_libs:
+                bb.debug(2, '%s: Dependency %s covered by PRIVATE_LIBS' % (pkg, n[0]))
+                continue
+            if n[0] in shlib_provider.keys():
+                shlib_provider_path = []
+                for k in shlib_provider[n[0]].keys():
+                    shlib_provider_path.append(k)
+                match = None
+                for p in list(n[2]) + shlib_provider_path + libsearchpath:
+                    if p in shlib_provider[n[0]]:
+                        match = p
+                        break
+                if match:
+                    (dep_pkg, ver_needed) = shlib_provider[n[0]][match]
+
+                    bb.debug(2, '%s: Dependency %s requires package %s (used by files: %s)' % (pkg, n[0], dep_pkg, n[1]))
+
+                    if dep_pkg == pkg:
+                        continue
+
+                    if ver_needed:
+                        dep = "%s (>= %s)" % (dep_pkg, ver_needed)
+                    else:
+                        dep = dep_pkg
+                    if not dep in deps:
+                        deps.append(dep)
+                    continue
+            bb.note("Couldn't find shared library provider for %s, used by files: %s" % (n[0], n[1]))
+
+        deps_file = os.path.join(pkgdest, pkg + ".shlibdeps")
+        if os.path.exists(deps_file):
+            os.remove(deps_file)
+        if len(deps):
+            fd = open(deps_file, 'w')
+            for dep in deps:
+                fd.write(dep + '\n')
+            fd.close()
+}
+PACKAGEBUILDPKGD := " \
+                perform_packagecopy \
+                ${PACKAGE_PREPROCESS_FUNCS} \
+                split_and_strip_files \
+                fixup_perms \
+                "
diff --git a/meta/meta-mediatek/classes/ramdisk-fitimage-extension.bbclass b/meta/meta-mediatek/classes/ramdisk-fitimage-extension.bbclass
new file mode 100644
index 0000000..ed7e413
--- /dev/null
+++ b/meta/meta-mediatek/classes/ramdisk-fitimage-extension.bbclass
@@ -0,0 +1,344 @@
+inherit kernel-uboot-extension
+
+python __anonymous () {
+    kerneltype = d.getVar('KERNEL_IMAGETYPE', True)
+    if kerneltype == 'fitImage':
+        depends = d.getVar("DEPENDS", True)
+        depends = "%s u-boot-mkimage-native lz4-native dtc-native" % depends
+        d.setVar("DEPENDS", depends)
+
+        # Override KERNEL_IMAGETYPE_FOR_MAKE variable, which is internal
+        # to kernel.bbclass . We have to override it, since we pack zImage
+        # (at least for now) into the fitImage .
+        kernelarch = d.getVar('KERNEL_ARCH', True)
+        if kernelarch == 'arm':
+                d.setVar("KERNEL_IMAGETYPE_FOR_MAKE", "zImage")
+        elif kernelarch == 'arm64':
+                d.setVar("KERNEL_IMAGETYPE_FOR_MAKE", "Image")
+        else:
+                print("please set KERNEL_ARCH variable.")
+                sys.exit(1)
+
+        image = d.getVar('INITRAMFS_IMAGE', True)
+        if image:
+            d.appendVarFlag('do_assemble_fitimage', 'depends', ' ${INITRAMFS_IMAGE}:do_image_complete')
+        d.appendVarFlag('do_assemble_fitimage_ramdisk', 'depends', ' ${INITRAMFS_IMAGE}:do_image_complete')
+}
+
+#
+# Emit the fitImage ITS header
+#
+fitimage_emit_fit_header() {
+        cat << EOF >> fit-image.its
+/dts-v1/;
+
+/ {
+        description = "U-Boot fitImage for ${DISTRO_NAME}/${PV}/${MACHINE}";
+        #address-cells = <1>;
+EOF
+}
+
+#
+# Emit the fitImage section bits
+#
+# $1 ... Section bit type: imagestart - image section start
+#                          confstart  - configuration section start
+#                          sectend    - section end
+#                          fitend     - fitimage end
+#
+fitimage_emit_section_maint() {
+        case $1 in
+        imagestart)
+                cat << EOF >> fit-image.its
+
+        images {
+EOF
+        ;;
+        confstart)
+                cat << EOF >> fit-image.its
+
+        configurations {
+EOF
+        ;;
+        sectend)
+                cat << EOF >> fit-image.its
+        };
+EOF
+        ;;
+        fitend)
+                cat << EOF >> fit-image.its
+};
+EOF
+        ;;
+        esac
+}
+
+#
+# Emit the fitImage ITS kernel section
+#
+# $1 ... Image counter
+# $2 ... Path to kernel image
+# $3 ... Compression type
+fitimage_emit_section_kernel() {
+
+        if [ -n "${IMAGE_HASH_ALGO}" ] ; then
+            kernel_csum="${IMAGE_HASH_ALGO}"
+        else
+            kernel_csum="sha256"
+        fi
+
+        ENTRYPOINT=${UBOOT_ENTRYPOINT}
+        if [ -n "${UBOOT_ENTRYSYMBOL}" ] ; then
+                ENTRYPOINT=`${HOST_PREFIX}nm ${S}/vmlinux | \
+                        awk '$3=="${UBOOT_ENTRYSYMBOL}" {print $1}'`
+        fi
+
+        cat << EOF >> fit-image.its
+                kernel@${1} {
+                        description = "Linux kernel";
+                        data = /incbin/("${2}");
+                        type = "kernel";
+                        arch = "${UBOOT_ARCH}";
+                        os = "linux";
+                        compression = "${3}";
+                        load = <${UBOOT_LOADADDRESS}>;
+                        entry = <${ENTRYPOINT}>;
+                        hash@1 {
+                                algo = "${kernel_csum}";
+                        };
+                };
+EOF
+}
+
+#
+# Emit the fitImage ITS ramdisk section
+#
+# $1 ... Image counter
+# $2 ... Path to ramdifk image
+fitimage_emit_section_ramdisk() {
+
+        if [ -n "${IMAGE_HASH_ALGO}" ] ; then
+            ramdisk_csum="${IMAGE_HASH_ALGO}"
+        else
+            ramdisk_csum="sha256"
+        fi
+
+        cat << EOF >> fit-image.its
+                ramdisk@${1} {
+                        description = "Ramdisk Image";
+                        data = /incbin/("${2}");
+                        type = "ramdisk";
+                        arch = "${UBOOT_ARCH}";
+                        os = "linux";
+                        compression = "none";
+                        load = <${RAMDISK_LOADADDRESS}>;
+                        entry = <${RAMDISK_LOADADDRESS}>;
+                        hash@1 {
+                                algo = "${ramdisk_csum}";
+                        };
+                };
+EOF
+}
+
+#
+# Emit the fitImage ITS DTB section
+#
+# $1 ... Image counter
+# $2 ... Path to DTB image
+fitimage_emit_section_dtb() {
+
+        if [ -n "${IMAGE_HASH_ALGO}" ] ; then
+            dtb_csum="${IMAGE_HASH_ALGO}"
+        else
+            dtb_csum="sha256"
+        fi
+
+        cat << EOF >> fit-image.its
+                fdt@${1} {
+                        description = "Flattened Device Tree blob";
+                        data = /incbin/("${2}");
+                        type = "flat_dt";
+                        arch = "${UBOOT_ARCH}";
+                        compression = "none";
+                        load = <${DTB_LOADADDRESS}>;
+                        hash@1 {
+                                algo = "${dtb_csum}";
+                        };
+                };
+EOF
+}
+
+#
+# Emit the fitImage ITS configuration section
+#
+# $1 ... Linux kernel ID
+# $2 ... DTB image ID
+# $3 ... Ramdisk ID
+fitimage_emit_section_config() {
+
+        if [ -n "${VB_HASH_ALGO}" -a -n "${VB_RSA_ALGO}" ] ; then
+            conf_csum="${VB_HASH_ALGO},${VB_RSA_ALGO}"
+        else
+            conf_csum="sha256,rsa2048"
+        fi
+        conf_key_name="dev"
+
+        # Test if we have any DTBs at all
+        if [ -z "${2}" ] ; then
+                conf_desc="Boot Linux kernel"
+                fdt_line=""
+        else
+                conf_desc="Boot Linux kernel with FDT blob"
+                fdt_line="fdt = \"fdt@${2}\";"
+        fi
+        kernel_line="kernel = \"kernel@${1}\";"
+
+        # Test if we have ramdisk image
+        if [ -z "${3}" ] ; then
+                ramdisk_line=""
+        else
+                ramdisk_line="ramdisk = \"ramdisk@${3}\";"
+        fi
+
+        cat << EOF >> fit-image.its
+                default = "conf@1";
+                conf@1 {
+                        description = "${conf_desc}";
+                        ${kernel_line}
+                        ${ramdisk_line}
+                        ${fdt_line}
+                        signature@1 {
+                                algo = "${conf_csum}";
+                                key-name-hint="${conf_key_name}";
+                                sign-images="fdt","kernel";
+                        };
+                };
+EOF
+}
+
+#
+# Assemble the ITS format
+#
+# $1 ... Ramdisk ID
+do_assemble_fitimage() {
+        cd ${B}
+        if [ "x${KERNEL_IMAGETYPE}" = "xfitImage" ] ; then
+                kernelcount=1
+                dtbcount=""
+                ramdiskcount="${1}"
+                rm -f fit-image.its
+
+                fitimage_emit_fit_header
+
+                #
+                # Step 1: Prepare a kernel image section.
+                #
+                fitimage_emit_section_maint imagestart
+
+                uboot_prep_kimage
+                fitimage_emit_section_kernel "${kernelcount}" linux.bin "${linux_comp}"
+
+                # Step 1.5: Prepare a ramdisk image section.
+                #
+                if [ "x${ramdiskcount}" = "x1" ] ; then
+                        fitimage_emit_section_ramdisk ${ramdiskcount} ${RAMDISK_PATH}
+                fi
+
+                #
+                # Step 2: Prepare a DTB image section
+                #
+                if [ -n "${KERNEL_DEVICETREE}" ] ; then
+                        dtbcount=1
+                        for DTB in ${KERNEL_DEVICETREE}; do
+                                if echo ${DTB} | grep -q '/dts/'; then
+                                        bbwarn "${DTB} contains the full path to the the dts file, but only the dtb name should be used."
+                                        DTB=`basename ${DTB} | sed 's,\.dts$,.dtb,g'`
+                                fi
+
+                                # go through device tree blob dir for 32/64 bits kernel
+                                DTB_PATH="arch/${ARCH}/boot/dts/mediatek/${DTB}"
+                                if [ ! -e "${DTB_PATH}" ]; then
+                                        DTB_PATH="arch/${ARCH}/boot/dts/${DTB}"
+                                        if [ ! -e "${DTB_PATH}" ]; then
+                                                DTB_PATH="arch/${ARCH}/boot/${DTB}"
+                                        fi
+                                fi
+
+                                fitimage_emit_section_dtb ${dtbcount} ${DTB_PATH}
+                                dtbcount=`expr ${dtbcount} + 1`
+                        done
+                fi
+
+                fitimage_emit_section_maint sectend
+
+                # Force the first Kernel and DTB in the default config
+                kernelcount=1
+                dtbcount=1
+
+                #
+                # Step 3: Prepare a configurations section
+                #
+                fitimage_emit_section_maint confstart
+
+                fitimage_emit_section_config ${kernelcount} ${dtbcount} ${ramdiskcount}
+
+                fitimage_emit_section_maint sectend
+
+                fitimage_emit_section_maint fitend
+
+                #
+                # Step 4: Assemble the image
+                #
+
+                uboot-mkimage -f fit-image.its arch/${ARCH}/boot/fitImage
+
+                if [ "${SECURE_BOOT_ENABLE}" = "yes" ]; then
+                        mkdir -p ./mykeys
+                        cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.crt ./mykeys/dev.crt
+                        cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.pem ./mykeys/dev.key
+                        uboot-mkimage -D "-I dts -O dtb -p 1024" -k ./mykeys -f fit-image.its -r arch/${ARCH}/boot/fitImage
+                fi
+        fi
+}
+
+do_assemble_fitimage_kernel() {
+        if [ "x${KERNEL_IMAGETYPE}" = "xfitImage" ] ; then
+                do_assemble_fitimage
+        fi
+}
+
+do_assemble_fitimage_ramdisk() {
+        if [ "x${KERNEL_IMAGETYPE}" = "xfitImage" -a -n "${INITRAMFS_IMAGE}" ] ; then
+                do_assemble_fitimage 1
+        fi
+}
+
+addtask assemble_fitimage_kernel before do_install after do_compile
+addtask assemble_fitimage_ramdisk before do_deploy after do_install
+
+kernel_do_deploy[vardepsexclude] = "DATETIME"
+kernel_do_deploy_append() {
+        # Update deploy directory
+        if [ "x${KERNEL_IMAGETYPE}" = "xfitImage" ] ; then
+                cd ${B}
+                echo "Copying fit-image.its source file..."
+                its_base_name="${KERNEL_IMAGETYPE}-its-${PV}-${PR}-${MACHINE}-${DATETIME}"
+                its_symlink_name=${KERNEL_IMAGETYPE}-its-${MACHINE}
+                install -m 0644 fit-image.its ${DEPLOYDIR}/${its_base_name}.its
+                linux_bin_base_name="${KERNEL_IMAGETYPE}-linux.bin-${PV}-${PR}-${MACHINE}-${DATETIME}"
+                linux_bin_symlink_name=${KERNEL_IMAGETYPE}-linux.bin-${MACHINE}
+                install -m 0644 linux.bin ${DEPLOYDIR}/${linux_bin_base_name}.bin
+                if [ -n "${RECOVERY_KERNEL_DEVICETREE}" ] ; then
+                        find arch/${ARCH}/boot/dts -name "${RECOVERY_KERNEL_DEVICETREE}" -exec install -m 0644 {} ${DEPLOYDIR}/${RECOVERY_KERNEL_DEVICETREE} \;
+                fi
+
+                cd ${DEPLOYDIR}
+                ln -sf ${its_base_name}.its ${its_symlink_name}.its
+                ln -sf ${linux_bin_base_name}.bin ${linux_bin_symlink_name}.bin
+                ln -nfs ${KERNEL_IMAGETYPE}-${KERNEL_IMAGE_NAME}.bin boot.img
+        fi
+}
+
+do_bundle_initramfs() {
+        :
+}
diff --git a/meta/meta-mediatek/classes/recovery-kernel-fitimage.bbclass b/meta/meta-mediatek/classes/recovery-kernel-fitimage.bbclass
new file mode 100644
index 0000000..d9992aa
--- /dev/null
+++ b/meta/meta-mediatek/classes/recovery-kernel-fitimage.bbclass
@@ -0,0 +1,255 @@
+inherit kernel-uboot-extension
+
+python __anonymous () {
+    kerneltype = d.getVar('KERNEL_IMAGETYPE', True)
+    recoverykerneldevicetree = d.getVar('RECOVERY_KERNEL_DEVICETREE', True)
+    if kerneltype == 'fitImage' and recoverykerneldevicetree != '' :
+        depends = d.getVar("DEPENDS", True)
+        depends = "%s u-boot-mkimage-native lz4-native dtc-native" % depends
+        d.setVar("DEPENDS", depends)
+
+        # Override KERNEL_IMAGETYPE_FOR_MAKE variable, which is internal
+        # to kernel.bbclass . We have to override it, since we pack zImage
+        # (at least for now) into the fitImage .
+        kernelarch = d.getVar('KERNEL_ARCH', True)
+        if kernelarch == 'arm':
+                d.setVar("KERNEL_IMAGETYPE_FOR_MAKE", "zImage")
+        elif kernelarch == 'arm64':
+                d.setVar("KERNEL_IMAGETYPE_FOR_MAKE", "Image")
+        else:
+                print("please set KERNEL_ARCH variable.")
+                sys.exit(1)
+}
+
+#
+# Emit the fitImage ITS header
+#
+fit_recovery_image_emit_fit_header() {
+        cat << EOF >> fit-recovery-image.its
+/dts-v1/;
+
+/ {
+        description = "U-Boot fitImage for ${DISTRO_NAME}/${PV}/${MACHINE}";
+        #address-cells = <1>;
+EOF
+}
+
+#
+# Emit the fitImage section bits
+#
+# $1 ... Section bit type: imagestart - image section start
+#                          confstart  - configuration section start
+#                          sectend    - section end
+#                          fitend     - fitimage end
+#
+fit_recovery_image_emit_section_maint() {
+        case $1 in
+        imagestart)
+                cat << EOF >> fit-recovery-image.its
+
+        images {
+EOF
+        ;;
+        confstart)
+                cat << EOF >> fit-recovery-image.its
+
+        configurations {
+EOF
+        ;;
+        sectend)
+                cat << EOF >> fit-recovery-image.its
+        };
+EOF
+        ;;
+        fitend)
+                cat << EOF >> fit-recovery-image.its
+};
+EOF
+        ;;
+        esac
+}
+
+#
+# Emit the fitImage ITS kernel section
+#
+# $1 ... Image counter
+# $2 ... Path to kernel image
+# $3 ... Compression type
+fit_recovery_image_emit_section_kernel() {
+
+        if [ -n "${IMAGE_HASH_ALGO}" ] ; then
+            kernel_csum="${IMAGE_HASH_ALGO}"
+        else
+            kernel_csum="sha256"
+        fi
+
+        ENTRYPOINT=${UBOOT_ENTRYPOINT}
+        if [ -n "${UBOOT_ENTRYSYMBOL}" ] ; then
+                ENTRYPOINT=`${HOST_PREFIX}nm ${S}/vmlinux | \
+                        awk '$3=="${UBOOT_ENTRYSYMBOL}" {print $1}'`
+        fi
+
+        cat << EOF >> fit-recovery-image.its
+                kernel@${1} {
+                        description = "Linux kernel";
+                        data = /incbin/("${2}");
+                        type = "kernel";
+                        arch = "${UBOOT_ARCH}";
+                        os = "linux";
+                        compression = "${3}";
+                        load = <${UBOOT_LOADADDRESS}>;
+                        entry = <${ENTRYPOINT}>;
+                        hash@1 {
+                                algo = "${kernel_csum}";
+                        };
+                };
+EOF
+}
+
+#
+# Emit the fitImage ITS DTB section
+#
+# $1 ... Image counter
+# $2 ... Path to DTB image
+fit_recovery_image_emit_section_dtb() {
+
+        if [ -n "${IMAGE_HASH_ALGO}" ] ; then
+            dtb_csum="${IMAGE_HASH_ALGO}"
+        else
+            dtb_csum="sha256"
+        fi
+
+        cat << EOF >> fit-recovery-image.its
+                fdt@${1} {
+                        description = "Flattened Device Tree blob";
+                        data = /incbin/("${2}");
+                        type = "flat_dt";
+                        arch = "${UBOOT_ARCH}";
+                        compression = "none";
+                        load = <${DTB_LOADADDRESS}>;
+                        hash@1 {
+                                algo = "${dtb_csum}";
+                        };
+                };
+EOF
+}
+
+#
+# Emit the fitImage ITS configuration section
+#
+# $1 ... Linux kernel ID
+# $2 ... DTB image ID
+fit_recovery_image_emit_section_config() {
+
+        if [ -n "${VB_HASH_ALGO}" -a -n "${VB_RSA_ALGO}" ] ; then
+            conf_csum="${VB_HASH_ALGO},${VB_RSA_ALGO}"
+        else
+            conf_csum="sha256,rsa2048"
+        fi
+        conf_key_name="dev"
+
+        # Test if we have any DTBs at all
+        if [ -z "${2}" ] ; then
+                conf_desc="Boot Linux kernel"
+                fdt_line=""
+        else
+                conf_desc="Boot Linux kernel with FDT blob"
+                fdt_line="fdt = \"fdt@${2}\";"
+        fi
+        kernel_line="kernel = \"kernel@${1}\";"
+
+        cat << EOF >> fit-recovery-image.its
+                default = "conf@1";
+                conf@1 {
+                        description = "${conf_desc}";
+                        ${kernel_line}
+                        ${fdt_line}
+                        signature@1 {
+                            algo = "${conf_csum}";
+                            key-name-hint="${conf_key_name}";
+                            sign-images="fdt","kernel";
+                        };
+                };
+EOF
+}
+
+do_assemble_recovery_fitimage() {
+        cd ${B}
+        if [ "x${KERNEL_IMAGETYPE}" = "xfitImage" -a -n "${RECOVERY_KERNEL_DEVICETREE}" ] ; then
+                kernelcount=1
+                dtbcount=""
+                rm -f fit-recovery-image.its
+
+                fit_recovery_image_emit_fit_header
+
+                #
+                # Step 1: Prepare a kernel image section.
+                #
+                fit_recovery_image_emit_section_maint imagestart
+
+                uboot_prep_kimage
+                fit_recovery_image_emit_section_kernel "${kernelcount}" linux.bin "${linux_comp}"
+
+                #
+                # Step 2: Prepare a DTB image section
+                #
+                dtbcount=1
+                for DTB in ${RECOVERY_KERNEL_DEVICETREE}; do
+                        if echo ${DTB} | grep -q '/dts/'; then
+                                bbwarn "${DTB} contains the full path to the the dts file, but only the dtb name should be used."
+                                DTB=`basename ${DTB} | sed 's,\.dts$,.dtb,g'`
+                        fi
+
+                        # go through device tree blob dir for 32/64 bits kernel
+                        DTB_PATH="arch/${ARCH}/boot/dts/mediatek/${DTB}"
+                        if [ ! -e "${DTB_PATH}" ]; then
+                                DTB_PATH="arch/${ARCH}/boot/dts/${DTB}"
+                                if [ ! -e "${DTB_PATH}" ]; then
+                                        DTB_PATH="arch/${ARCH}/boot/${DTB}"
+                                fi
+                        fi
+
+                        fit_recovery_image_emit_section_dtb ${dtbcount} ${DTB_PATH}
+                        dtbcount=`expr ${dtbcount} + 1`
+                done
+
+                fit_recovery_image_emit_section_maint sectend
+                # Force the first Kernel and DTB in the default config
+                kernelcount=1
+                dtbcount=1
+
+                #
+                # Step 3: Prepare a configurations section
+                #
+                fit_recovery_image_emit_section_maint confstart
+
+                fit_recovery_image_emit_section_config ${kernelcount} ${dtbcount}
+
+                fit_recovery_image_emit_section_maint sectend
+
+                fit_recovery_image_emit_section_maint fitend
+
+                #
+                # Step 4: Assemble the image
+                #
+                uboot-mkimage -f fit-recovery-image.its arch/${ARCH}/boot/fitRecoveryImage
+
+                if [ "${SECURE_BOOT_ENABLE}" = "yes" ]; then
+                        mkdir -p ./mykeys
+                        cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.crt ./mykeys/dev.crt
+                        cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.pem ./mykeys/dev.key
+                        uboot-mkimage -D "-I dts -O dtb -p 1024" -k ./mykeys -f fit-recovery-image.its -r arch/${ARCH}/boot/fitRecoveryImage
+                fi
+        fi
+}
+
+addtask assemble_recovery_fitimage before do_install after do_compile_kernelmodules
+
+kernel_do_deploy_append() {
+        # Update deploy directory
+        if [ "x${KERNEL_IMAGETYPE}" = "xfitImage" -a -n "${RECOVERY_KERNEL_DEVICETREE}" ] ; then
+                cd ${B}
+                install -m 0644 fit-recovery-image.its ${DEPLOYDIR}/fit-recovery-image.its
+                install -m 0644 arch/${ARCH}/boot/fitRecoveryImage ${DEPLOYDIR}/recovery.img
+        fi
+}
diff --git a/meta/meta-mediatek/classes/recovery-ramdisk-kernel-fitimage.bbclass b/meta/meta-mediatek/classes/recovery-ramdisk-kernel-fitimage.bbclass
new file mode 100755
index 0000000..ff61d4c
--- /dev/null
+++ b/meta/meta-mediatek/classes/recovery-ramdisk-kernel-fitimage.bbclass
@@ -0,0 +1,260 @@
+inherit kernel-arch
+inherit kernel-uboot-extension
+
+python __anonymous () {
+    kerneltype = d.getVar('KERNEL_IMAGETYPE', True)
+    recoverykerneldevicetree = d.getVar('RECOVERY_KERNEL_DEVICETREE', True)
+    if kerneltype == 'fitImage' and recoverykerneldevicetree != '' :
+        depends = d.getVar("DEPENDS", True)
+        depends = "%s u-boot-mkimage-native lz4-native dtc-native" % depends
+        d.setVar("DEPENDS", depends)
+}
+
+do_image_complete[postfuncs] += "do_assemble_recovery_ramdisk_fitimage"
+
+#
+# Emit the fitImage ITS header
+#
+fit_recovery_ramdisk_image_emit_fit_header() {
+        cat << EOF >> fit-recovery-ramdisk-image.its
+/dts-v1/;
+
+/ {
+        description = "U-Boot fitImage for ${DISTRO_NAME}/${PV}/${MACHINE}";
+        #address-cells = <1>;
+EOF
+}
+
+#
+# Emit the fitImage section bits
+#
+# $1 ... Section bit type: imagestart - image section start
+#                          confstart  - configuration section start
+#                          sectend    - section end
+#                          fitend     - fitimage end
+#
+fit_recovery_ramdisk_image_emit_section_maint() {
+        case $1 in
+        imagestart)
+                cat << EOF >> fit-recovery-ramdisk-image.its
+
+        images {
+EOF
+        ;;
+        confstart)
+                cat << EOF >> fit-recovery-ramdisk-image.its
+
+        configurations {
+EOF
+        ;;
+        sectend)
+                cat << EOF >> fit-recovery-ramdisk-image.its
+        };
+EOF
+        ;;
+        fitend)
+                cat << EOF >> fit-recovery-ramdisk-image.its
+};
+EOF
+        ;;
+        esac
+}
+
+#
+# Emit the fitImage ITS kernel section
+#
+# $1 ... Image counter
+# $2 ... Path to kernel image
+# $3 ... Compression type
+fit_recovery_ramdisk_image_emit_section_kernel() {
+
+        if [ -n "${IMAGE_HASH_ALGO}" ] ; then
+            kernel_csum="${IMAGE_HASH_ALGO}"
+        else
+            kernel_csum="sha256"
+        fi
+
+        cat << EOF >> fit-recovery-ramdisk-image.its
+                kernel@${1} {
+                        description = "Linux kernel";
+                        data = /incbin/("${2}");
+                        type = "kernel";
+                        arch = "${ARCH}";
+                        os = "linux";
+                        compression = "${3}";
+                        load = <${UBOOT_LOADADDRESS}>;
+                        entry = <${UBOOT_ENTRYPOINT}>;
+                        hash@1 {
+                                algo = "${kernel_csum}";
+                        };
+                };
+EOF
+}
+
+#
+# Emit the fitImage ITS recovery ramdisk section
+#
+# $1 ... Image counter
+# $2 ... Path to ramdifk image
+fitimage_emit_section_recovery_ramdisk() {
+
+        if [ -n "${IMAGE_HASH_ALGO}" ] ; then
+            ramdisk_csum="${IMAGE_HASH_ALGO}"
+        else
+            ramdisk_csum="sha256"
+        fi
+
+        cat << EOF >> fit-recovery-ramdisk-image.its
+                ramdisk@${1} {
+                        description = "Ramdisk Image";
+                        data = /incbin/("${2}");
+                        type = "ramdisk";
+                        arch = "${ARCH}";
+                        os = "linux";
+                        compression = "none";
+                        load = <${RECOVERY_RAMDISK_LOADADDRESS}>;
+                        entry = <${RECOVERY_RAMDISK_LOADADDRESS}>;
+                        hash@1 {
+                                algo = "${ramdisk_csum}";
+                        };
+                };
+EOF
+}
+
+#
+# Emit the fitImage ITS DTB section
+#
+# $1 ... Image counter
+# $2 ... Path to DTB image
+fit_recovery_ramdisk_image_emit_section_dtb() {
+
+        if [ -n "${IMAGE_HASH_ALGO}" ] ; then
+            dtb_csum="${IMAGE_HASH_ALGO}"
+        else
+            dtb_csum="sha256"
+        fi
+
+        cat << EOF >> fit-recovery-ramdisk-image.its
+                fdt@${1} {
+                        description = "Flattened Device Tree blob";
+                        data = /incbin/("${2}");
+                        type = "flat_dt";
+                        arch = "${ARCH}";
+                        compression = "none";
+                        load = <${DTB_LOADADDRESS}>;
+                        hash@1 {
+                                algo = "${dtb_csum}";
+                        };
+                };
+EOF
+}
+
+#
+# Emit the fitImage ITS configuration section
+#
+# $1 ... Linux kernel ID
+# $2 ... DTB image ID
+# $3 ... Ramdisk ID
+fit_recovery_ramdisk_image_emit_section_config() {
+
+        if [ -n "${VB_HASH_ALGO}" -a -n "${VB_RSA_ALGO}" ] ; then
+            conf_csum="${VB_HASH_ALGO},${VB_RSA_ALGO}"
+        else
+            conf_csum="sha256,rsa2048"
+        fi
+        conf_key_name="dev"
+
+        # Test if we have any DTBs at all
+        if [ -z "${2}" ] ; then
+                conf_desc="Boot Linux kernel"
+                fdt_line=""
+        else
+                conf_desc="Boot Linux kernel with FDT blob"
+                fdt_line="fdt = \"fdt@${2}\";"
+        fi
+        kernel_line="kernel = \"kernel@${1}\";"
+
+        # Test if we have ramdisk image
+        if [ -z "${3}" ] ; then
+                ramdisk_line=""
+        else
+                ramdisk_line="ramdisk = \"ramdisk@${3}\";"
+        fi
+
+        cat << EOF >> fit-recovery-ramdisk-image.its
+                default = "conf@1";
+                conf@1 {
+                        description = "${conf_desc}";
+                        ${kernel_line}
+                        ${ramdisk_line}
+                        ${fdt_line}
+                        signature@1 {
+                            algo = "${conf_csum}";
+                            key-name-hint="${conf_key_name}";
+                            sign-images="fdt","kernel";
+                        };
+                };
+EOF
+}
+
+do_assemble_recovery_ramdisk_fitimage() {
+        cd ${B}
+        if [ "x${KERNEL_IMAGETYPE}" = "xfitImage" -a -n "${RECOVERY_KERNEL_DEVICETREE}" ] ; then
+                kernelcount=1
+                dtbcount=1
+                ramdiskcount=1
+                rm -f fit-recovery-ramdisk-image.its
+
+                fit_recovery_ramdisk_image_emit_fit_header
+
+                #
+                # Step 1: Prepare a kernel image section.
+                #
+                fit_recovery_ramdisk_image_emit_section_maint imagestart
+
+                fit_recovery_ramdisk_image_emit_section_kernel ${kernelcount} ${DEPLOY_DIR_IMAGE}/${KERNEL_IMAGETYPE}-linux.bin-${MACHINE}.bin ${KERNEL_COMPRESS}
+
+                # Step 1.5: Prepare a ramdisk image section.
+                #
+                fitimage_emit_section_recovery_ramdisk ${ramdiskcount} ${IMGDEPLOYDIR}/${IMAGE_BASENAME}-${MACHINE}.${IMAGE_FSTYPES}
+
+                #
+                # Step 2: Prepare a DTB image section
+                #
+                if [ -n "${RECOVERY_KERNEL_DEVICETREE}" ] ; then
+                        fit_recovery_ramdisk_image_emit_section_dtb ${dtbcount} ${DEPLOY_DIR_IMAGE}/${RECOVERY_KERNEL_DEVICETREE}
+                fi
+
+                fit_recovery_ramdisk_image_emit_section_maint sectend
+
+                #
+                # Step 3: Prepare a configurations section
+                #
+                fit_recovery_ramdisk_image_emit_section_maint confstart
+
+                fit_recovery_ramdisk_image_emit_section_config ${kernelcount} ${dtbcount} ${ramdiskcount}
+
+                fit_recovery_ramdisk_image_emit_section_maint sectend
+
+                fit_recovery_ramdisk_image_emit_section_maint fitend
+
+                #
+                # Step 4: Assemble the image
+                #
+                uboot-mkimage -f fit-recovery-ramdisk-image.its recovery.ramdisk.img
+
+                if [ "${SECURE_BOOT_ENABLE}" = "yes" ]; then
+                        mkdir -p ./mykeys
+                        cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.crt ./mykeys/dev.crt
+                        cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.pem ./mykeys/dev.key
+                        uboot-mkimage -D "-I dts -O dtb -p 1024" -k ./mykeys -f fit-recovery-ramdisk-image.its -r recovery.ramdisk.img
+                fi
+
+                #
+                # Step 5: Install the recovery.ramdisk.img and recovery fit to DEPLOY_DIR_IMAGE folder
+                #
+                install -d ${DEPLOY_DIR_IMAGE}
+                install -m 0644 fit-recovery-ramdisk-image.its recovery.ramdisk.img -t ${DEPLOY_DIR_IMAGE}
+
+        fi
+}
diff --git a/meta/meta-mediatek/classes/scpsys-fitimage.bbclass b/meta/meta-mediatek/classes/scpsys-fitimage.bbclass
new file mode 100644
index 0000000..9b3c8b0
--- /dev/null
+++ b/meta/meta-mediatek/classes/scpsys-fitimage.bbclass
@@ -0,0 +1,277 @@
+inherit hsm-sign-env
+
+python __anonymous () {
+        depends = d.getVar("DEPENDS", True)
+        depends = "%s u-boot-mkimage-native lz4-native dtc-native" % depends
+        d.setVar("DEPENDS", depends)
+}
+
+# $1 ... Set compress bin name
+tinysys_prep_image() {
+
+        tinysys_comp=${TINYSYS_COMPRESS}
+
+        if test "${tinysys_comp}" = "lz4"; then
+                tinysys_suffix=".lz4"
+        elif test "${tinysys_comp}" = "gzip"; then
+                tinysys_suffix=".gz"
+        else
+                tinysys_suffix=""
+        fi
+
+        if test "${tinysys_comp}" = "lz4"; then
+                lz4 -l -c1 ${1} > ${1}${tinysys_suffix}
+                # append uncompressed filesize info
+                dec_size=0
+                fsize=$(stat -c "%s" "${1}")
+                dec_size=$(expr $dec_size + $fsize)
+                printf "%08x\n" $dec_size |
+                        sed 's/\(..\)/\1 /g' | {
+                                read ch0 ch1 ch2 ch3;
+                                for ch in $ch3 $ch2 $ch1 $ch0; do
+                                        printf `printf '%s%03o' '\\' 0x$ch` >> ${1}${tinysys_suffix};
+                                done;
+                        }
+        elif test "${tinysys_comp}" = "gzip"; then
+                gzip -9 ${1}
+        else
+                echo "For none case or another compressing"
+        fi
+
+        if ! test "${tinysys_comp}" = "none"; then
+                mv -f "${1}${tinysys_suffix}" ${1}
+        else
+                echo "No tinysys compression"
+        fi
+
+        echo "${tinysys_comp}"
+}
+
+
+#
+# Emit the fitImage ITS header
+#
+fitimage_emit_fit_header() {
+        cat << EOF >> ${WORKDIR}/fit-image.its
+/dts-v1/;
+
+/ {
+        description = "scpsys fitImage for fusa";
+        #address-cells = <2>;
+EOF
+}
+
+#
+fitimage_emit_scpdata_fit_header() {
+        cat << EOF >> ${WORKDIR}/fit-image.its
+/dts-v1/;
+
+/ {
+        description = "scpdata fitImage for fusa";
+        #address-cells = <2>;
+EOF
+}
+
+#
+# Emit the fitImage section bits
+#
+# $1 ... Section bit type: imagestart - image section start
+#                          confstart  - configuration section start
+#                          sectend    - section end
+#                          fitend     - fitimage end
+#
+fitimage_emit_section_maint() {
+        case $1 in
+        imagestart)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+
+        images {
+EOF
+        ;;
+        confstart)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+
+        configurations {
+EOF
+        ;;
+        sectend)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+        };
+EOF
+        ;;
+        fitend)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+};
+EOF
+        ;;
+        esac
+}
+
+fitimage_emit_section_scpsys() {
+
+        if [ -n "${IMAGE_HASH_ALGO}" ] ; then
+            tinysys_csum="${IMAGE_HASH_ALGO}"
+        else
+            tinysys_csum="sha256"
+        fi
+
+        cat << EOF >> ${WORKDIR}/fit-image.its
+                ${3}@1 {
+                        description = "${4}";
+                        data = /incbin/("${1}");
+                        type = "${7}";
+                        compression = "${2}";
+                        load = <${5} ${6}>;
+                        hash@1 {
+                                algo = "sha256";
+                        };
+                };
+EOF
+}
+
+fitimage_emit_section_scpdata() {
+
+        if [ -n "${IMAGE_HASH_ALGO}" ] ; then
+            tinysys_csum="${IMAGE_HASH_ALGO}"
+        else
+            tinysys_csum="sha256"
+        fi
+
+        cat << EOF >> ${WORKDIR}/fit-image.its
+                ${3}@1 {
+                        description = "${3}";
+                        data = /incbin/("${1}");
+                        type = "loadable";
+                        compression = "${2}";
+                        load = <${4} ${5}>;
+                        hash@1 {
+                                algo = "sha256";
+                        };
+                };
+EOF
+}
+
+#
+# Emit the fitImage ITS configuration section
+#
+fitimage_emit_section_config() {
+
+        if [ -n "${VB_HASH_ALGO}" ] && [ -n "${VB_RSA_ALGO}" ] ; then
+            conf_csum="${VB_HASH_ALGO},${VB_RSA_ALGO}"
+        else
+            conf_csum="sha256,rsa2048"
+        fi
+        conf_key_name="dev"
+
+        conf_desc="${MTK_PROJECT} configuration"
+
+        if [ ! -n "${FUSA_EATURE_ENABLE}" ]; then
+           dram_node="firmware = \"scp_dram@1\";"
+           dram_img_type=",\"firmware\";"
+        else
+           dram_img_type=";"
+        fi
+
+        cat << EOF >> ${WORKDIR}/fit-image.its
+                default = "conf@1";
+                conf@1 {
+                        description = "${conf_desc}";
+                        kernel = "scpsys@1";
+                        ${dram_node}
+                        signature@1 {
+                                algo = "${conf_csum}";
+                                key-name-hint="${conf_key_name}";
+                                sign-images = "kernel"${dram_img_type}
+                        };
+                };
+EOF
+}
+
+do_assemble_fitimage() {
+
+        rm -f ${WORKDIR}/fit-image.its
+
+        fitimage_emit_fit_header
+
+        #
+        # Step 1: Prepare a tinysys image section.
+        #
+        fitimage_emit_section_maint imagestart
+
+        # compress scp dram image using lz4
+        ${S}build/lz4_compress.sh ${S}tinysys-scp_out/freertos/source/${TINYSYS_DRAM_BIN} ${TINYSYS_COMPRESS}
+
+        fitimage_emit_section_scpsys ${S}tinysys-scp_out/freertos/source/${TINYSYS_BIN} \
+        none scpsys ${SCP_SRAM_DESCRIPTION} 0 ${SCP_SRAM_LOAD_ADDR} ${SCP_SRAM_TYPE}
+
+        # to decide if dram image need to be load or not
+        if [ ! -n "${FUSA_EATURE_ENABLE}" ]; then
+           if [ -n "${4GB_DRAM_PROJECT}" ]; then
+              fitimage_emit_section_scpsys ${S}tinysys-scp_out/freertos/source/${TINYSYS_DRAM_BIN}.${TINYSYS_COMPRESS} \
+              lz4 scp_dram ${SCP_DRAM_DESCRIPTION} ${SCP_4GB_DRAM_LOAD_ADDR_UPPER_BITS} ${SCP_4GB_DRAM_LOAD_ADDR_LOWER_BITS} ${SCP_DRAM_TYPE}
+           else
+              fitimage_emit_section_scpsys ${S}tinysys-scp_out/freertos/source/${TINYSYS_DRAM_BIN}.${TINYSYS_COMPRESS} \
+              lz4 scp_dram ${SCP_DRAM_DESCRIPTION} ${SCP_NON_4GB_DRAM_LOAD_ADDR_UPPER_BITS} ${SCP_NON_4GB_DRAM_LOAD_ADDR_LOWER_BITS} ${SCP_DRAM_TYPE}
+           fi
+        fi
+
+
+        fitimage_emit_section_maint sectend
+
+        #
+        # Step 2: Prepare a configurations section
+        #
+        fitimage_emit_section_maint confstart
+
+        fitimage_emit_section_config
+
+        fitimage_emit_section_maint sectend
+
+        fitimage_emit_section_maint fitend
+
+        #
+        # Step 3: Assemble the image
+        #
+        mkdir -p ./mykeys
+        cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.crt ./mykeys/dev.crt
+        cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.pem ./mykeys/dev.key
+        uboot-mkimage -k ./mykeys -f ${WORKDIR}/fit-image.its -r ${WORKDIR}/${TINYSYS_IMAGE}
+	cp ${WORKDIR}/fit-image.its ${WORKDIR}/scpsys-fit-image.its
+
+        # scp_data image
+        if [ ! -n "${FUSA_EATURE_ENABLE}" ]; then
+           rm -f ${WORKDIR}/fit-image.its
+
+           fitimage_emit_scpdata_fit_header
+
+           #
+           # Step 1: Prepare a tinysys image section.
+           #
+           fitimage_emit_section_maint imagestart
+
+           cp -f ${SCP_LOGO_IMAGE} ${S}tinysys-scp_out/scp-logo
+           cp -f ${SCP_WARNING_IMAGE} ${S}tinysys-scp_out/scp-warning
+           cp -f ${SCP_CVBS_IMAGE} ${S}tinysys-scp_out/scp-cvbs
+           cp -f ${SCP_GUIDELING} ${S}tinysys-scp_out/scp-guideline
+           tinysys_prep_image ${S}tinysys-scp_out/scp-logo
+           tinysys_prep_image ${S}tinysys-scp_out/scp-warning
+           tinysys_prep_image ${S}tinysys-scp_out/scp-cvbs
+           tinysys_prep_image ${S}tinysys-scp_out/scp-guideline
+           fitimage_emit_section_scpdata ${S}tinysys-scp_out/scp-logo ${TINYSYS_COMPRESS} logo 0 ${SCP_LOGO_LOAD_ADDRESS}
+           fitimage_emit_section_scpdata ${S}tinysys-scp_out/scp-warning ${TINYSYS_COMPRESS} warnmsg 0 ${SCP_WARNMSG_LOAD_ADDRESS}
+           fitimage_emit_section_scpdata ${S}tinysys-scp_out/scp-cvbs ${TINYSYS_COMPRESS} cvbsimg 0 ${SCP_CVBSIMG_LOAD_ADDRESS}
+           fitimage_emit_section_scpdata ${S}tinysys-scp_out/scp-guideline ${TINYSYS_COMPRESS} guideline 0 ${SCP_GUILDLINE_LOAD_ADDRESS}
+
+           fitimage_emit_section_maint sectend
+
+           fitimage_emit_section_maint fitend
+
+           #
+           # Step 3: Assemble the image
+           #
+           uboot-mkimage -f ${WORKDIR}/fit-image.its -r ${WORKDIR}/${TINYDATA_IMAGE}
+           cp ${WORKDIR}/fit-image.its ${WORKDIR}/scpdata-fit-image.its
+        fi
+}
+
+addtask assemble_fitimage before do_package after do_install
diff --git a/meta/meta-mediatek/classes/showinfo.bbclass b/meta/meta-mediatek/classes/showinfo.bbclass
new file mode 100644
index 0000000..ee415f3
--- /dev/null
+++ b/meta/meta-mediatek/classes/showinfo.bbclass
@@ -0,0 +1,56 @@
+
+python() {
+  bb.warn("====Start")
+  bb.warn("B=%s" % d.getVar('B', True))
+  bb.warn("S=%s" % d.getVar('S', True))
+  bb.warn("D=%s" % d.getVar('D', True))
+  bb.warn("CC=%s" % d.getVar('CC', True))
+
+  bb.warn("bindir=%s" % d.getVar('bindir', True))
+  bb.warn("libdir=%s" % d.getVar('libdir', True))
+  bb.warn("sbindir=%s" % d.getVar('sbindir', True))
+  bb.warn("includedir=%s" % d.getVar('includedir', True))
+  bb.warn("sysconfdir=%s " % d.getVar('sysconfdir', True))
+  bb.warn("datadir=%s " % d.getVar('datadir', True))
+  bb.warn("base_bindir=%s" % d.getVar('base_bindir', True))
+  bb.warn("base_libdir=%s " % d.getVar('base_libdir', True))
+  bb.warn("base_sbindir=%s " % d.getVar('base_sbindir', True))
+  bb.warn("base_includedir=%s " % d.getVar('base_includedir', True))
+  bb.warn("systemd_unitdir=%s " % d.getVar('systemd_unitdir', True))
+
+
+  bb.warn("STAGING_INCDIR=%s" % d.getVar('STAGING_INCDIR', True))
+  bb.warn("STAGING_LIBDIR=%s" % d.getVar('STAGING_LIBDIR', True))
+  bb.warn("STAGING_DIR=%s " % d.getVar('STAGING_DIR', True))
+  bb.warn("STAGING_DIR_HOST=%s " % d.getVar('STAGING_DIR_HOST', True) )
+
+  bb.warn("WORKDIR=%s" % d.getVar('WORKDIR', True))
+  bb.warn("WORKSPACE=%s " % d.getVar('WORKSPACE', True))
+  bb.warn("TOPDIR=%s " % d.getVar('TOPDIR', True))
+  bb.warn("MTK_SRC=%s " % d.getVar('MTK_SRC', True))
+
+  bb.warn("COMMON_LICENSE_DIR=%s" % d.getVar('COMMON_LICENSE_DIR', True))
+  bb.warn("TARGET_PREFIX=%s " % d.getVar('TARGET_PREFIX', True))
+  bb.warn("DISTRO_FEATURES=%s " % d.getVar('DISTRO_FEATURES', True))
+  bb.warn("BPN=%s " % d.getVar('BPN', True))
+  bb.warn("PN=%s " % d.getVar('PN', True))
+  bb.warn("FILE=%s " % d.getVar('FILE', d))
+  bb.warn("PACKAGES=%s " % d.getVar('PACKAGES', d))
+  bb.warn("FILES_PN=%s " % d.getVar('FILES_${PN}', d))
+
+  bb.warn("ARMPKGARCH=%s" % d.getVar('ARMPKGARCH', True))
+  bb.warn("TUNE_FEATURES=%s" % d.getVar('TUNE_FEATURES', True))
+  bb.warn("PACKAGE_EXTRA_ARCHS =%s" % d.getVar('PACKAGE_EXTRA_ARCHS', True))
+  bb.warn("TUNE_PKGARCH=%s" % d.getVar('TUNE_PKGARCH', True))
+  bb.warn("PACKAGE_ARCHS=%s" % d.getVar('PACKAGE_ARCHS', True))
+  bb.warn("PACKAGE_ARCH=%s" % d.getVar('PACKAGE_ARCH', True))
+  bb.warn("TUNEABI=%s" % d.getVar('TUNEABI', True))
+  bb.warn("TARGET_FPU=%s" % d.getVar('TARGET_FPU', True))
+  bb.warn("TARGET_ARCH=%s" % d.getVar('TARGET_ARCH', True))
+  bb.warn("TARGET_CC_ARCH=%s" % d.getVar('TARGET_CC_ARCH', True))
+  bb.warn("TARGET_CC_KERNEL_ARCH=%s" % d.getVar('TARGET_CC_KERNEL_ARCH', True))
+  bb.warn("MACHINE=%s" % d.getVar('MACHINE', True))
+  bb.warn("MACHINE_ARCH=%s" % d.getVar('MACHINE_ARCH', True))
+
+  bb.warn("====End")
+}
diff --git a/meta/meta-mediatek/classes/slimko.bbclass b/meta/meta-mediatek/classes/slimko.bbclass
new file mode 100644
index 0000000..94502f9
--- /dev/null
+++ b/meta/meta-mediatek/classes/slimko.bbclass
@@ -0,0 +1,12 @@
+#./slimko -i input.ko -o output.ko -c cross-compile-prefix
+
+SLIMKOTOOL="${TOPDIR}/../prebuilt/devtools/slimko/slimko"
+slim_kernel_module() {
+    install -d ${IMAGE_ROOTFS}/lib/modules
+    KERNEL_MODULES=$(find ${IMAGE_ROOTFS}/lib/modules -name "*.ko")
+    for i in ${KERNEL_MODULES}; do
+        ${SLIMKOTOOL} -i ${i} -o ${i} -c ${TARGET_PREFIX}
+    done
+}
+
+ROOTFS_POSTPROCESS_COMMAND += " slim_kernel_module;"
diff --git a/meta/meta-mediatek/classes/spmfw-fitimage.bbclass b/meta/meta-mediatek/classes/spmfw-fitimage.bbclass
new file mode 100644
index 0000000..54df817
--- /dev/null
+++ b/meta/meta-mediatek/classes/spmfw-fitimage.bbclass
@@ -0,0 +1,161 @@
+inherit hsm-sign-env
+
+python __anonymous () {
+    spmfwtype = d.getVar('SPMFW_IMAGETYPE', True)
+    if spmfwtype == 'fitImage':
+        depends = d.getVar("DEPENDS", True)
+        depends = "%s u-boot-mkimage-native lz4-native dtc-native " % depends
+        d.setVar("DEPENDS", depends)
+}
+
+#
+# Emit the fitImage ITS header
+#
+fitimage_emit_fit_header() {
+        cat << EOF >> ${WORKDIR}/fit-image.its
+/dts-v1/;
+
+/ {
+        description = "U-Boot fitImage for ${DISTRO_NAME}/${PV}/${MACHINE}";
+        #address-cells = <1>;
+EOF
+}
+
+#
+# Emit the fitImage section bits
+#
+# $1 ... Section bit type: imagestart - image section start
+#                          confstart  - configuration section start
+#                          sectend    - section end
+#                          fitend     - fitimage end
+#
+fitimage_emit_section_maint() {
+        case $1 in
+        imagestart)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+
+        images {
+EOF
+        ;;
+        confstart)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+
+        configurations {
+EOF
+        ;;
+        sectend)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+        };
+EOF
+        ;;
+        fitend)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+};
+EOF
+        ;;
+        esac
+}
+
+#
+# Emit the fitImage ITS spm section
+#
+# $1 ... Path to spmfw image
+# $2 ... Compression type
+fitimage_emit_section_spmfw() {
+
+        if [ -n "${IMAGE_HASH_ALGO}" ] ; then
+            spmfw_csum="${IMAGE_HASH_ALGO}"
+        else
+            spmfw_csum="sha256"
+        fi
+
+        cat << EOF >> ${WORKDIR}/fit-image.its
+                spmfw@1 {
+                        description = "SPM firmware";
+                        data = /incbin/("${1}");
+                        type = "kernel";
+                        arch = "arm";
+                        os = "linux";
+                        compression = "${2}";
+                        load = <${SPMFW_LOADADDRESS}>;
+                        entry = <${SPMFW_ENTRYPOINT}>;
+                        hash@1 {
+                                algo = "${spmfw_csum}";
+                        };
+                };
+EOF
+}
+
+#
+# Emit the fitImage ITS configuration section
+#
+# $1 ... spmfw image ID
+fitimage_emit_section_config() {
+
+        if [ -n "${VB_HASH_ALGO}" -a -n "${VB_RSA_ALGO}" ] ; then
+            conf_csum="${VB_HASH_ALGO},${VB_RSA_ALGO}"
+        else
+            conf_csum="sha256,rsa2048"
+        fi
+        conf_key_name="dev"
+        conf_desc="spmfw configuration"
+
+        spmfw_line="kernel = \"spmfw@1\";"
+        sign_images_line="sign-images = \"kernel\";"
+
+        cat << EOF >> ${WORKDIR}/fit-image.its
+                default = "conf@1";
+                conf@1 {
+                        description = "${conf_desc}";
+                        ${spmfw_line}
+                        signature@1 {
+                                algo = "${conf_csum}";
+                                key-name-hint="${conf_key_name}";
+                                ${sign_images_line}
+                        };
+                };
+EOF
+}
+
+do_assemble_fitimage() {
+                rm -f ${WORKDIR}/fit-image.its
+
+                fitimage_emit_fit_header
+
+                #
+                # Step 1: Prepare a spmfw image section.
+                #
+                fitimage_emit_section_maint imagestart
+
+                fitimage_emit_section_spmfw ${SPMFW_OUT}/${SPMFW_BINARY_SELECT} ${SPMFW_COMPRESS}
+
+                fitimage_emit_section_maint sectend
+
+                #
+                # Step 2: Prepare a configurations section
+                #
+                fitimage_emit_section_maint confstart
+
+                fitimage_emit_section_config
+
+                fitimage_emit_section_maint sectend
+
+                fitimage_emit_section_maint fitend
+
+                #
+                # Step 3: Assemble the image
+                #
+                ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -f ${WORKDIR}/fit-image.its ${SPMFW_OUT}/${SPMFW_BINARY}
+
+                if [ "${SECURE_BOOT_ENABLE}" = "yes" ]; then
+			if [ "${STANDALONE_SIGN_PREPARE}" = "yes" ];then
+				exit 0
+			fi
+                        mkdir -p ./mykeys
+                        cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.crt ./mykeys/dev.crt
+                        cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.pem ./mykeys/dev.key
+                        ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -D "-I dts -O dtb -p 1024" -k ./mykeys -f ${WORKDIR}/fit-image.its -r ${SPMFW_OUT}/${SPMFW_BINARY}
+                fi
+}
+
+addtask assemble_fitimage before do_install after do_compile
diff --git a/meta/meta-mediatek/classes/srcprebuilt.bbclass b/meta/meta-mediatek/classes/srcprebuilt.bbclass
new file mode 100644
index 0000000..945179b
--- /dev/null
+++ b/meta/meta-mediatek/classes/srcprebuilt.bbclass
@@ -0,0 +1,20 @@
+python () {
+
+    import os.path
+
+    srcpath = d.getVar('MTK_SRC', True)
+    prebuiltpath = srcpath.replace("build/../src/", "build/../prebuilt/")
+    if os.path.exists(srcpath+'/.git'):
+        d.setVar('MTK_SRC', srcpath)
+    elif os.path.exists(prebuiltpath+'/.git'):
+        d.setVar('MTK_SRC', prebuiltpath)
+    else:
+        bb.warn("Both %s and %s aren't existed" % (srcpath, prebuiltpath) )
+
+    d.setVar('B', d.getVar('MTK_SRC', True) )
+    d.setVar('S', d.getVar('MTK_SRC', True) )
+#    bb.warn("MTK_SRC           = %s" % d.getVar('MTK_SRC', True) )
+#    bb.warn("EXTERNALSRC       = %s" % d.getVar('EXTERNALSRC', True))
+#    bb.warn("EXTERNALSRC_BUILD = %s" %  d.getVar('EXTERNALSRC_BUILD', True) )
+
+}
diff --git a/meta/meta-mediatek/classes/sspm-fitimage.bbclass b/meta/meta-mediatek/classes/sspm-fitimage.bbclass
new file mode 100644
index 0000000..75fca59
--- /dev/null
+++ b/meta/meta-mediatek/classes/sspm-fitimage.bbclass
@@ -0,0 +1,161 @@
+inherit hsm-sign-env

+

+python __anonymous () {

+        depends = d.getVar("DEPENDS", True)

+        depends = "%s u-boot-mkimage-native dtc-native" % depends

+        d.setVar("DEPENDS", depends)

+}

+

+#

+# Emit the fitImage ITS header

+#

+fitimage_emit_fit_header() {

+        cat << EOF >> ${WORKDIR}/fit-image.its

+/dts-v1/;

+

+/ {

+        description = "SSPM fitImage";

+        #address-cells = <1>;

+EOF

+}

+

+#

+# Emit the fitImage section bits

+#

+# $1 ... Section bit type: imagestart - image section start

+#                          confstart  - configuration section start

+#                          sectend    - section end

+#                          fitend     - fitimage end

+#

+fitimage_emit_section_maint() {

+        case $1 in

+        imagestart)

+                cat << EOF >> ${WORKDIR}/fit-image.its

+

+        images {

+EOF

+        ;;

+        confstart)

+                cat << EOF >> ${WORKDIR}/fit-image.its

+

+        configurations {

+EOF

+        ;;

+        sectend)

+                cat << EOF >> ${WORKDIR}/fit-image.its

+        };

+EOF

+        ;;

+        fitend)

+                cat << EOF >> ${WORKDIR}/fit-image.its

+};

+EOF

+        ;;

+        esac

+}

+

+#

+# Emit the fitImage ITS sspm section

+#

+# $1 ... Path to sspm image

+# $2 ... Compression type

+fitimage_emit_section_sspm() {

+

+        if [ -n "${IMAGE_HASH_ALGO}" ] ; then

+            sspm_csum="${IMAGE_HASH_ALGO}"

+        else

+            sspm_csum="sha256"

+        fi

+

+        cat << EOF >> ${WORKDIR}/fit-image.its

+                sspm@1 {

+                        description = "SSPM firmware";

+                        data = /incbin/("${1}");

+                        type = "kernel";

+                        arch = "arm";

+                        os = "linux";

+                        compression = "${2}";

+                        load = <${SSPM_LOADADDRESS}>;

+                        entry = <${SSPM_ENTRYPOINT}>;

+                        hash@1 {

+                                algo = "${sspm_csum}";

+                        };

+                };

+EOF

+}

+

+#

+# Emit the fitImage ITS configuration section

+#

+# $1 ... sspm image ID

+fitimage_emit_section_config() {

+

+        if [ -n "${VB_HASH_ALGO}" -a -n "${VB_RSA_ALGO}" ] ; then

+            conf_csum="${VB_HASH_ALGO},${VB_RSA_ALGO}"

+        else

+            conf_csum="sha256,rsa2048"

+        fi

+        conf_key_name="dev"

+        conf_desc="sspm configuration"

+

+        sspm_line="kernel = \"sspm@1\";"

+        sign_images_line="sign-images = \"kernel\";"

+

+        cat << EOF >> ${WORKDIR}/fit-image.its

+                default = "conf@1";

+                conf@1 {

+                        description = "${conf_desc}";

+                        ${sspm_line}

+                        signature@1 {

+                                algo = "${conf_csum}";

+                                key-name-hint="${conf_key_name}";

+                                ${sign_images_line}

+                        };

+                };

+EOF

+}

+

+do_assemble_fitimage() {

+

+                rm -f ${WORKDIR}/fit-image.its

+

+                fitimage_emit_fit_header

+

+                #

+                # Step 1: Prepare a sspm image section.

+                #

+                fitimage_emit_section_maint imagestart

+

+                fitimage_emit_section_sspm ${SSPM_OUT}/${SSPM_BINARY} ${SSPM_COMPRESS}

+

+                fitimage_emit_section_maint sectend

+

+                #

+                # Step 2: Prepare a configurations section

+                #

+                fitimage_emit_section_maint confstart

+

+                fitimage_emit_section_config

+

+                fitimage_emit_section_maint sectend

+

+                fitimage_emit_section_maint fitend

+

+                #

+                # Step 3: Assemble the image

+                #

+                ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -f ${WORKDIR}/fit-image.its ${WORKDIR}/${SSPM_IMAGE}

+

+                if [ "${SECURE_BOOT_ENABLE}" = "yes" ]; then

+			if [ "${STANDALONE_SIGN_PREPARE}" = "yes" ];then

+				exit 0

+			fi

+                        mkdir -p ./mykeys

+                        cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.crt ./mykeys/dev.crt

+                        cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.pem ./mykeys/dev.key

+                        ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -D "-I dts -O dtb -p 1024" -k ./mykeys -f ${WORKDIR}/fit-image.its -r ${WORKDIR}/${SSPM_IMAGE}

+                fi

+}

+

+addtask assemble_fitimage before do_deploy after do_install

+

diff --git a/meta/meta-mediatek/classes/staging-copyfile.bbclass b/meta/meta-mediatek/classes/staging-copyfile.bbclass
new file mode 100644
index 0000000..9e37983
--- /dev/null
+++ b/meta/meta-mediatek/classes/staging-copyfile.bbclass
@@ -0,0 +1,29 @@
+# need to inherit this bbclass after core-image
+def staging_copyfile(c, target, dest, postinsts, seendirs):
+    import errno
+
+    destdir = os.path.dirname(dest)
+    if destdir not in seendirs:
+        bb.utils.mkdirhier(destdir)
+        seendirs.add(destdir)
+    if "/usr/bin/postinst-" in c:
+        postinsts.append(dest)
+    if os.path.islink(c):
+        linkto = os.readlink(c)
+        if os.path.lexists(dest):
+            if not os.path.islink(dest):
+                raise OSError(errno.EEXIST, "Link %s already exists as a file" % dest, dest)
+            if os.readlink(dest) == linkto:
+                return dest
+            raise OSError(errno.EEXIST, "Link %s already exists to a different location? (%s vs %s)" % (dest, os.readlink(dest), linkto), dest)
+        os.symlink(linkto, dest)
+        #bb.warn(c)
+    else:
+        try:
+            os.link(c, dest)
+        except OSError as err:
+            if err.errno == errno.EXDEV or err.errno == errno.EEXIST:
+                bb.utils.copyfile(c, dest)
+            else:
+                raise
+    return dest
diff --git a/meta/meta-mediatek/classes/tinysys-fitimage.bbclass b/meta/meta-mediatek/classes/tinysys-fitimage.bbclass
new file mode 100644
index 0000000..f348265
--- /dev/null
+++ b/meta/meta-mediatek/classes/tinysys-fitimage.bbclass
@@ -0,0 +1,150 @@
+inherit hsm-sign-env
+
+python __anonymous () {
+        depends = d.getVar("DEPENDS", True)
+        depends = "%s u-boot-mkimage-native lz4-native dtc-native" % depends
+        d.setVar("DEPENDS", depends)
+}
+
+#
+# Emit the fitImage ITS header
+#
+fitimage_emit_fit_header() {
+        cat << EOF >> ${WORKDIR}/fit-image.its
+/dts-v1/;
+
+/ {
+        description = "TINYSYS fitImage";
+        #address-cells = <1>;
+EOF
+}
+
+#
+# Emit the fitImage section bits
+#
+# $1 ... Section bit type: imagestart - image section start
+#                          confstart  - configuration section start
+#                          sectend    - section end
+#                          fitend     - fitimage end
+#
+fitimage_emit_section_maint() {
+        case $1 in
+        imagestart)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+
+        images {
+EOF
+        ;;
+        confstart)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+
+        configurations {
+EOF
+        ;;
+        sectend)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+        };
+EOF
+        ;;
+        fitend)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+};
+EOF
+        ;;
+        esac
+}
+
+fitimage_emit_section_tinysys() {
+
+        if [ -n "${IMAGE_HASH_ALGO}" ] ; then
+            tinysys_csum="${IMAGE_HASH_ALGO}"
+        else
+            tinysys_csum="sha256"
+        fi
+
+        cat << EOF >> ${WORKDIR}/fit-image.its
+                tinysys@1 {
+                        description = "TINYSYS Image";
+                        data = /incbin/("${1}");
+                        type = "kernel";
+                        arch = "arm";
+                        os = "FreeRTOS";
+                        compression = "${2}";
+                        load = <${TINYSYS_LOADADDRESS}>;
+                        entry = <${TINYSYS_ENTRYPOINT}>;
+                        hash@1 {
+                                algo = "${tinysys_csum}";
+                        };
+                };
+EOF
+}
+
+#
+# Emit the fitImage ITS configuration section
+#
+fitimage_emit_section_config() {
+
+        if [ -n "${VB_HASH_ALGO}" ] && [ -n "${VB_RSA_ALGO}" ] ; then
+            conf_csum="${VB_HASH_ALGO},${VB_RSA_ALGO}"
+        else
+            conf_csum="sha256,rsa2048"
+        fi
+        conf_key_name="dev"
+
+        conf_desc="${MTK_PROJECT} configuration"
+
+        cat << EOF >> ${WORKDIR}/fit-image.its
+                default = "conf@1";
+                conf@1 {
+                        description = "${conf_desc}";
+                        kernel = "tinysys@1";
+                        signature@1 {
+                                algo = "${conf_csum}";
+                                key-name-hint="${conf_key_name}";
+                                sign-images = "kernel";
+                        };
+                };
+EOF
+}
+
+do_assemble_fitimage() {
+
+                rm -f ${WORKDIR}/fit-image.its
+
+                fitimage_emit_fit_header
+
+                #
+                # Step 1: Prepare a tinysys image section.
+                #
+                fitimage_emit_section_maint imagestart
+
+
+                fitimage_emit_section_tinysys ${TINYSYS_OUT}/${TINYSYS_BIN}.bin ${TINYSYS_COMPRESS}
+
+                fitimage_emit_section_maint sectend
+
+                #
+                # Step 2: Prepare a configurations section
+                #
+                fitimage_emit_section_maint confstart
+
+                fitimage_emit_section_config
+
+                fitimage_emit_section_maint sectend
+
+                fitimage_emit_section_maint fitend
+
+                #
+                # Step 3: Assemble the image
+                #
+                ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -f ${WORKDIR}/fit-image.its ${WORKDIR}/${TINYSYS_IMAGE}
+
+                if [ "${SECURE_BOOT_ENABLE}" = "yes" ]; then
+                        mkdir -p ./mykeys
+                        cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.crt ./mykeys/dev.crt
+                        cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.pem ./mykeys/dev.key
+                        ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -D "-I dts -O dtb -p 1024" -k ./mykeys -f ${WORKDIR}/fit-image.its -r ${WORKDIR}/${TINYSYS_IMAGE}
+                fi
+}
+
+addtask assemble_fitimage before do_package after do_install
diff --git a/meta/meta-mediatek/classes/trustzone-build.bbclass b/meta/meta-mediatek/classes/trustzone-build.bbclass
new file mode 100644
index 0000000..5ef0c63
--- /dev/null
+++ b/meta/meta-mediatek/classes/trustzone-build.bbclass
@@ -0,0 +1,122 @@
+TZ_BINARY = "tee.img"
+ATF_RAW_BINARY="atf_raw.img"
+ATF_SIGNED_BINARY="atf_signed.img"
+
+TZ_RAW_BINARY= "tz.raw.img"
+TZ_SIGNED_BINARY = "tz_signed.img"
+
+TZ_TMP_SIGNED_BINARY = "tz_tmp_signed.img"
+TZ_TMP_RAW_BINARY = "tz_tmp_raw.img"
+TZ_TMP_BINARY = "tz_tmp.img"
+
+TRUSTEDOS_RAW_BINARY = "trusedos.img"
+TRUSTEDOS_SIGNED_BINARY = "trusedos_signed.img"
+
+TZ_ASSEMBLE_OUT = "${DEPLOY_DIR}/images/${MACHINE}/trustzone"
+TL_ALIGN_SIZE = "0xb000"
+
+TRUSTZONE_VERSION = "20200422"
+
+do_mkdir_assemble () {
+        mkdir -p ${TZ_ASSEMBLE_OUT}
+}
+addtask mkdir_assemble before do_compile after do_configure
+
+python __anonymous () {
+        tee_loadaddress = d.getVar('TRUSTZONE_LOADADDRESS', True)
+        tee_entrypoint = d.getVar('TRUSTZONE_ENTRYPOINT', True)
+        if tee_loadaddress is None or tee_entrypoint is None:
+                return
+        else:
+                tee_loadaddress = int(tee_loadaddress, 16)
+                tee_entrypoint = int(tee_entrypoint, 16)
+
+        tl_align_size = int(d.getVar('TL_ALIGN_SIZE', True), 16)
+        tee_loadaddress = tee_loadaddress - tl_align_size
+        tee_loadaddress_str = hex(tee_loadaddress).replace('L', '')
+        d.setVar('TEE_LOADADDRESS', tee_loadaddress_str)
+
+        tee_entrypoint = tee_entrypoint - tl_align_size
+        tee_entrypoint_str = hex(tee_entrypoint).replace('L', '')
+        d.setVar('TEE_ENTRYPOINT', tee_entrypoint_str)
+
+        image_desc = d.getVar('DESCRIPTION', True)
+        if image_desc == 'ARM trusted firmware':
+                atf_src = d.getVar('MTK_SRC', True)
+                mach_type = d.getVar('MTK_MACH_TYPE', True)
+                tee_support = d.getVar('TEE_SUPPORT', True)
+                atf_ver = d.getVar('ATF_VER', True)
+
+                if os.path.exists(atf_src+'/.git'):
+                        bb.warn('please change your atf folder to new layout')
+                        # backward to old atf layout
+                        # change the mt8516 to v1.21 folder
+                        # others remain the original path
+                        if mach_type == "mt8516":
+                                d.setVar('ATF_VER','1.21')
+                else:
+                        # new atf layout, change to use folder atf_tbase
+                        # if tee_support is tbase and atf version is 1.0
+                        if tee_support == 'tbase' and atf_ver == '1.0':
+                                d.setVar('B',atf_src+'_'+tee_support)
+                        else:
+                                # change folder to CHIP_TYPE {mt2xxx/mt8xxx}
+                                tgtplt = d.getVar('TARGET_PLATFORM', True)
+                                if tgtplt[0:3] == "mt2":
+                                    d.setVar('CHIP_TYPE', tgtplt[0:3]+'xxx')
+                                else:
+                                    atf_path = os.path.join(atf_src,"v"+atf_ver,tgtplt)
+                                    if os.path.exists(atf_path+'/.git'):
+                                        d.setVar('CHIP_TYPE', tgtplt)
+                                    else:
+                                        d.setVar('CHIP_TYPE', 'mt8xxx')
+
+        if image_desc == 'TrustZone Image':
+                multilibs = d.getVar('MULTILIBS', True)
+                if multilibs == 'multilib:lib64':
+                        d.appendVarFlag('do_cleansstate', 'depends', ' lib64-teeloader:do_cleansstate')
+                        d.appendVarFlag('do_compile', 'depends', ' lib64-teeloader:do_deploy')
+                else:
+                        d.appendVarFlag('do_cleansstate', 'depends', ' teeloader:do_cleansstate')
+                        d.appendVarFlag('do_compile', 'depends', ' teeloader:do_deploy')
+
+                atfsupport = d.getVar('ATF_SUPPORT', True)
+                if atfsupport == 'yes':
+                        if multilibs == 'multilib:lib64':
+                                d.appendVarFlag('do_cleansstate', 'depends', ' lib64-atf:do_cleansstate')
+                                d.appendVarFlag('do_compile', 'depends', ' lib64-atf:do_deploy')
+                        else:
+                                d.appendVarFlag('do_cleansstate', 'depends', ' atf:do_cleansstate')
+                                d.appendVarFlag('do_compile', 'depends', ' atf:do_deploy')
+
+                tee_support = d.getVar('TEE_SUPPORT', True)
+                if tee_support is None:
+                        tee_support = "mtee"
+                        d.appendVarFlag('do_cleansstate', 'depends', ' tee-'+tee_support+':do_cleansstate')
+                        d.appendVarFlag('do_compile', 'depends', ' tee-'+tee_support+':do_deploy')
+                if tee_support == 'optee':
+                        if multilibs == 'multilib:lib64':
+                                d.appendVarFlag('do_cleansstate', 'depends', ' lib64-optee-os:do_cleansstate')
+                                d.appendVarFlag('do_compile', 'depends', ' lib64-optee-os:do_deploy')
+                        else:
+                                d.appendVarFlag('do_cleansstate', 'depends', ' optee-os:do_cleansstate')
+                                d.appendVarFlag('do_compile', 'depends', ' optee-os:do_deploy')
+                elif tee_support != 'none':
+                        if multilibs == 'multilib:lib64':
+                                d.appendVarFlag('do_cleansstate', 'depends', ' lib64-tee-'+tee_support+':do_cleansstate')
+                                d.appendVarFlag('do_compile', 'depends', ' lib64-tee-'+tee_support+':do_deploy')
+                        else:
+                                d.appendVarFlag('do_cleansstate', 'depends', ' tee-'+tee_support+':do_cleansstate')
+                                d.appendVarFlag('do_compile', 'depends', ' tee-'+tee_support+':do_deploy')
+
+        secure_boot_enable = d.getVar('SECURE_BOOT_ENABLE', True)
+        force_disable_tee_encryption = d.getVar('FORCE_DISABLE_TEE_ENCRYPTION', True)
+        if  secure_boot_enable == 'yes' and force_disable_tee_encryption != 'yes' :
+                d.setVar("ATF_BINARY_SELECT", '${ATF_SIGNED_BINARY}')
+                d.setVar("TZ_BINARY_SELECT", '${TZ_SIGNED_BINARY}')
+                d.setVar("TRUSTEDOS_BINARY_SELECT", '${TRUSTEDOS_SIGNED_BINARY}')
+        else:
+                d.setVar("ATF_BINARY_SELECT", '${ATF_RAW_BINARY}')
+                d.setVar("TZ_BINARY_SELECT", '${TZ_RAW_BINARY}')
+                d.setVar("TRUSTEDOS_BINARY_SELECT", '${TRUSTEDOS_RAW_BINARY}')
+}
diff --git a/meta/meta-mediatek/classes/trustzone-fitimage.bbclass b/meta/meta-mediatek/classes/trustzone-fitimage.bbclass
new file mode 100644
index 0000000..0572ee4
--- /dev/null
+++ b/meta/meta-mediatek/classes/trustzone-fitimage.bbclass
@@ -0,0 +1,223 @@
+inherit hsm-sign-env
+
+python __anonymous () {
+        depends = d.getVar("DEPENDS", True)
+        depends = "%s u-boot-mkimage-native lz4-native" % depends
+        d.setVar("DEPENDS", depends)
+}
+
+#
+# Emit the fitImage ITS header
+#
+fitimage_emit_fit_header() {
+        cat << EOF >> ${WORKDIR}/fit-image.its
+/dts-v1/;
+
+/ {
+        description = "Trustzone fitimage for ${DISTRO_NAME}/${PV}/${MACHINE} ver:${TRUSTZONE_VERSION}";
+        #address-cells = <1>;
+EOF
+}
+
+#
+# Emit the fitImage section bits
+#
+# $1 ... Section bit type: imagestart - image section start
+#                          confstart  - configuration section start
+#                          sectend    - section end
+#                          fitend     - fitimage end
+#
+fitimage_emit_section_maint() {
+        case $1 in
+        imagestart)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+
+        images {
+EOF
+        ;;
+        confstart)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+
+        configurations {
+EOF
+        ;;
+        sectend)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+        };
+EOF
+        ;;
+        fitend)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+};
+EOF
+        ;;
+        esac
+}
+
+fitimage_emit_section_trustedos() {
+
+        if [ -n "${IMAGE_HASH_ALGO}" ] ; then
+            trustedos_csum="${IMAGE_HASH_ALGO}"
+        else
+            trustedos_csum="sha256"
+        fi
+
+        cat << EOF >> ${WORKDIR}/fit-image.its
+                trustedos@1 {
+                        description = "Trusted OS Image";
+                        data = /incbin/("${1}");
+                        type = "tee";
+                        arch = "arm";
+                        os = "linux";
+                        compression = "${2}";
+                        load = <${TRUSTEDOS_LOADADDRESS}>;
+                        entry = <${TRUSTEDOS_ENTRYPOINT}>;
+                        hash@1 {
+                                algo = "${trustedos_csum}";
+                        };
+                };
+EOF
+}
+
+#
+# Emit the fitImage ITS trustzone section
+#
+# $1 ... Path to trustzone image
+# $2 ... Compression type
+fitimage_emit_section_trustzone() {
+
+        if [ -n "${IMAGE_HASH_ALGO}" ] ; then
+            trustzone_csum="${IMAGE_HASH_ALGO}"
+        else
+            trustzone_csum="sha256"
+        fi
+
+if [ -d ${TL_SRC} ]; then
+        cat << EOF >> ${WORKDIR}/fit-image.its
+                tee@1 {
+                        description = "Tee Image";
+                        data = /incbin/("${1}");
+                        type = "kernel";
+                        arch = "arm";
+                        os = "linux";
+                        compression = "${2}";
+                        load = <${TEE_LOADADDRESS}>;
+                        entry = <${TEE_ENTRYPOINT}>;
+                        hash@1 {
+                                algo = "${trustzone_csum}";
+                        };
+                };
+EOF
+else
+        cat << EOF >> ${WORKDIR}/fit-image.its
+                tee@1 {
+                        description = "Tee Image";
+                        data = /incbin/("${1}");
+                        type = "kernel";
+                        arch = "arm";
+                        os = "linux";
+                        compression = "${2}";
+                        load = <${TRUSTZONE_LOADADDRESS}>;
+                        entry = <${TRUSTZONE_ENTRYPOINT}>;
+                        hash@1 {
+                                algo = "${trustzone_csum}";
+                        };
+                };
+EOF
+fi
+}
+
+#
+# Emit the fitImage ITS configuration section
+#
+# $1 ... trustzone image ID
+fitimage_emit_section_config() {
+
+        if [ -n "${VB_HASH_ALGO}" ] && [ -n "${VB_RSA_ALGO}" ] ; then
+            conf_csum="${VB_HASH_ALGO},${VB_RSA_ALGO}"
+        else
+            conf_csum="sha256,rsa2048"
+        fi
+        conf_key_name="dev"
+
+        conf_desc="${MTK_PROJECT} configuration"
+
+        trustzone_line="kernel = \"tee@1\";"
+         if [ -n "${TRUSTEDOS_ENTRYPOINT}" ] && [ -n "${TRUSTEDOS_LOADADDRESS}" ] ; then
+            trustedos_line="tee = \"trustedos@1\";"
+            sign_images_line="sign-images = \"kernel\", \"tee\";"
+        else
+            trustedos_line=""
+            sign_images_line="sign-images = \"kernel\";"
+        fi
+
+        cat << EOF >> ${WORKDIR}/fit-image.its
+                default = "conf@1";
+                conf@1 {
+                        description = "${conf_desc}";
+                        ${trustzone_line}
+                        ${trustedos_line}
+                        signature@1 {
+                                algo = "${conf_csum}";
+                                key-name-hint="${conf_key_name}";
+                                ${sign_images_line}
+                        };
+                };
+EOF
+}
+
+do_assemble_fitimage() {
+
+                rm -f ${WORKDIR}/fit-image.its
+
+                fitimage_emit_fit_header
+
+                #
+                # Step 1: Prepare a trustzone image section.
+                #
+                fitimage_emit_section_maint imagestart
+
+                #uboot_prep_kimage
+                if [ -d ${TL_SRC} ]; then
+                        if [ "${SECURE_BOOT_ENABLE}" = "yes" ] && [ "${FORCE_DISABLE_TEE_ENCRYPTION}" != "yes" ]; then
+                                fitimage_emit_section_trustzone ${TZ_ASSEMBLE_OUT}/${TZ_TMP_SIGNED_BINARY} ${TRUSTZONE_COMPRESS}
+                                if [ -n "${TRUSTEDOS_ENTRYPOINT}" ] && [ -n "${TRUSTEDOS_LOADADDRESS}" ] ; then
+                                    fitimage_emit_section_trustedos ${TZ_ASSEMBLE_OUT}/${TRUSTEDOS_SIGNED_BINARY} ${TRUSTZONE_COMPRESS}
+                                fi
+                        else
+                                fitimage_emit_section_trustzone ${TZ_ASSEMBLE_OUT}/${TZ_TMP_RAW_BINARY} ${TRUSTZONE_COMPRESS}
+                                 if [ -n "${TRUSTEDOS_ENTRYPOINT}" ] && [ -n "${TRUSTEDOS_LOADADDRESS}" ] ; then
+                                    fitimage_emit_section_trustedos ${TZ_ASSEMBLE_OUT}/${TRUSTEDOS_RAW_BINARY} ${TRUSTZONE_COMPRESS}
+                                fi
+                        fi
+                else
+                        fitimage_emit_section_trustzone ${TZ_ASSEMBLE_OUT}/${TZ_RAW_BINARY} ${TRUSTZONE_COMPRESS}
+                fi
+
+                fitimage_emit_section_maint sectend
+
+                #
+                # Step 2: Prepare a configurations section
+                #
+                fitimage_emit_section_maint confstart
+
+                fitimage_emit_section_config
+
+                fitimage_emit_section_maint sectend
+
+                fitimage_emit_section_maint fitend
+
+                #
+                # Step 3: Assemble the image
+                #
+                ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -f ${WORKDIR}/fit-image.its ${TZ_ASSEMBLE_OUT}/${TZ_BINARY}
+
+                if [ "${SECURE_BOOT_ENABLE}" = "yes" ] && [ "${STANDALONE_SIGN_PREPARE}" != "yes" ]; then
+                        mkdir -p ./mykeys
+                        cp -f ${MTK_KEY_DIR}/${VERIFIED_KEY}.crt ./mykeys/dev.crt
+                        cp -f ${MTK_KEY_DIR}/${VERIFIED_KEY}.pem ./mykeys/dev.key
+                        ${HSM_ENV} HSM_KEY_NAME=${VERIFIED_KEY} uboot-mkimage -D "-I dts -O dtb -p 1024" -k ./mykeys -f ${WORKDIR}/fit-image.its -r ${TZ_ASSEMBLE_OUT}/${TZ_BINARY}
+                fi
+}
+
+addtask assemble_fitimage before do_install after do_compile
diff --git a/meta/meta-mediatek/classes/u-boot-fitimage.bbclass b/meta/meta-mediatek/classes/u-boot-fitimage.bbclass
new file mode 100644
index 0000000..ffdc171
--- /dev/null
+++ b/meta/meta-mediatek/classes/u-boot-fitimage.bbclass
@@ -0,0 +1,202 @@
+
+python __anonymous () {
+        depends = d.getVar("DEPENDS", True)
+        depends = "%s u-boot-mkimage-native" % depends
+        d.setVar("DEPENDS", depends)
+}
+
+#
+# Emit the fitImage ITS header
+#
+fitimage_emit_fit_header() {
+        cat << EOF >> ${WORKDIR}/fit-image.its
+/dts-v1/;
+
+/ {
+        description = "U-Boot fitImage for ${DISTRO_NAME}/${PV}/${MACHINE}";
+        #address-cells = <1>;
+EOF
+}
+
+#
+# Emit the fitImage section bits
+#
+# $1 ... Section bit type: imagestart - image section start
+#                          confstart  - configuration section start
+#                          sectend    - section end
+#                          fitend     - fitimage end
+#
+fitimage_emit_section_maint() {
+        case $1 in
+        imagestart)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+
+        images {
+EOF
+        ;;
+        confstart)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+
+        configurations {
+EOF
+        ;;
+        sectend)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+        };
+EOF
+        ;;
+        fitend)
+                cat << EOF >> ${WORKDIR}/fit-image.its
+};
+EOF
+        ;;
+        esac
+}
+
+#
+# Emit the fitImage ITS u-boot section
+#
+# $1 ... Path to u-boot image
+# $2 ... Compression type
+fitimage_emit_section_uboot() {
+
+        if [ -n "${IMAGE_HASH_ALGO}" ] ; then
+            uboot_csum="${IMAGE_HASH_ALGO}"
+        else
+            uboot_csum="sha256"
+        fi
+
+        cat << EOF >> ${WORKDIR}/fit-image.its
+                kernel@1 {
+                        description = "U-Boot";
+                        data = /incbin/("${1}");
+                        type = "kernel";
+                        arch = "arm";
+                        os = "linux";
+                        compression = "${2}";
+                        load = <${UBOOT_FIT_LOADADDRESS}>;
+                        entry = <${UBOOT_FIT_ENTRYPOINT}>;
+                        hash@1 {
+                                algo = "${uboot_csum}";
+                        };
+                };
+EOF
+}
+
+#
+# Emit the fitImage ITS DTB section
+#
+# $1 ... Image counter
+# $2 ... Path to DTB image
+fitimage_emit_section_dtb() {
+
+        if [ -n "${IMAGE_HASH_ALGO}" ] ; then
+            dtb_csum="${IMAGE_HASH_ALGO}"
+        else
+            dtb_csum="sha256"
+        fi
+
+        cat << EOF >> ${WORKDIR}/fit-image.its
+		        fdt@1 {
+		                description = "sig blob for u-boot verified boot";
+		                data = /incbin/("${1}");
+		                type = "kernel";
+		                arch = "arm";
+		                os = "linux";
+		                compression = "${2}";
+		                load = <${UBOOT_DTB_LOADADDRESS}>;
+		                entry = <${UBOOT_DTB_LOADADDRESS}>;
+		                hash@1 {
+		                        algo = "${dtb_csum}";
+		                };
+		        };
+EOF
+}
+
+#
+# Emit the fitImage ITS configuration section
+#
+# $1 ... u-boot image ID
+fitimage_emit_section_config() {
+
+        if [ -n "${VB_HASH_ALGO}" -a -n "${VB_RSA_ALGO}" ] ; then
+            conf_csum="${VB_HASH_ALGO},${VB_RSA_ALGO}"
+        else
+            conf_csum="sha256,rsa2048"
+        fi
+        conf_key_name="dev"
+
+        conf_desc="${MTK_PROJECT} configuration"
+
+        uboot_line="kernel = \"kernel@1\";"
+        if [ "${SECURE_BOOT_ENABLE}" = "yes" ]; then
+            fdt_line="fdt = \"fdt@1\";"
+        else
+            fdt_line=""
+        fi
+
+        cat << EOF >> ${WORKDIR}/fit-image.its
+                default = "conf@1";
+                conf@1 {
+                        description = "${conf_desc}";
+                        ${uboot_line}
+                        ${fdt_line}
+                        signature@1 {
+                                algo = "${conf_csum}";
+                                key-name-hint="${conf_key_name}";
+                                sign-images="fdt","kernel";
+                        };
+                };
+EOF
+}
+
+do_assemble_fitimage() {
+
+                rm -f ${WORKDIR}/fit-image.its
+
+                fitimage_emit_fit_header
+
+                #
+                # Step 1: Prepare a u-boot image section.
+                #
+                fitimage_emit_section_maint imagestart
+
+                fitimage_emit_section_uboot ${UBOOT_OUT}/${UBOOT_BINARY} ${UBOOT_COMPRESS}
+                
+                if [ "${SECURE_BOOT_ENABLE}" = "yes" ]; then
+                    fitimage_emit_section_dtb ${UBOOT_OUT}/sig_blob.dtb none
+                fi
+
+                fitimage_emit_section_maint sectend
+
+                #
+                # Step 2: Prepare a configurations section
+                #
+                fitimage_emit_section_maint confstart
+
+                fitimage_emit_section_config
+
+                fitimage_emit_section_maint sectend
+
+                fitimage_emit_section_maint fitend
+
+                #
+                # Step 3: Assemble the image
+                #
+                dtc -p 0x3ff ${WORKDIR}/u-boot.dts -O dtb -o ${UBOOT_OUT}/sig_blob.dtb
+                uboot-mkimage -f ${WORKDIR}/fit-image.its ${UBOOT_OUT}/${UBOOT_FIT_IMAGE}
+
+                if [ "${SECURE_BOOT_ENABLE}" = "yes" ]; then
+			if [ "${STANDALONE_SIGN_PREPARE}" = "yes" ]; then
+				exit 0
+			fi
+                        mkdir -p ./mykeys
+                        cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.crt ./mykeys/dev.crt
+                        cp ${MTK_KEY_DIR}/${VERIFIED_KEY}.pem ./mykeys/dev.key
+                        ${UBOOT_OUT}/tools/mkimage -D "-I dts -O dtb -p 1024" -k ./mykeys -f ${WORKDIR}/fit-image.its -K ${UBOOT_OUT}/sig_blob.dtb -r ${UBOOT_OUT}/${UBOOT_FIT_IMAGE}
+                        uboot-mkimage -D "-I dts -O dtb -p 1024" -k ./mykeys -f ${WORKDIR}/fit-image.its -r ${UBOOT_OUT}/${UBOOT_FIT_IMAGE}
+                fi
+}
+
+addtask assemble_fitimage before do_install after do_compile
+
diff --git a/meta/meta-mediatek/classes/workonsrc.bbclass b/meta/meta-mediatek/classes/workonsrc.bbclass
new file mode 100644
index 0000000..1137e98
--- /dev/null
+++ b/meta/meta-mediatek/classes/workonsrc.bbclass
@@ -0,0 +1,301 @@
+# Copyright (C) 2017 Mediatek
+# Author: Richard Sun
+# Some code and influence taken from externalsrc.bbclass:
+# Copyright (C) 2012 Linux Foundation
+# Author: Richard Purdie
+# Some code and influence taken from srctree.bbclass:
+# Copyright (C) 2009 Chris Larson <clarson@kergoth.com>
+# Released under the MIT license (see COPYING.MIT for the terms)
+#
+# workonsrc.bbclass enables use of an existing source tree, usually workon to 
+# the build system to build a piece of software rather than the usual fetch/unpack/patch
+# process.
+#
+# To use, add workonsrc to the global inherit and set WORKONSRC to point at the
+# directory you want to use containing the sources e.g. from local.conf for a recipe
+# called "myrecipe" you would do:
+#
+# INHERIT += "workonsrc"
+# WORKONSRC_pn-myrecipe = "/path/to/my/source/tree"
+#
+# In order to make this class work for both target and native versions (or with
+# multilibs/cross or other BBCLASSEXTEND variants), B is set to point to a separate
+# directory under the work directory (split source and build directories). This is
+# the default, but the build directory can be set to the source directory if
+# circumstances dictate by setting WORKONSRC_BUILD to the same value, e.g.:
+#
+# WORKONSRC_BUILD_pn-myrecipe = "/path/to/my/source/tree"
+#
+
+SRCTREECOVEREDTASKS ?= "do_patch do_unpack do_fetch"
+EXTERNALSRC_SYMLINKS ?= "oe-workdir:${WORKDIR} oe-logs:${T}"
+
+python () {
+    import subprocess, os.path
+
+    depends = d.getVar("DEPENDS")
+    depends = "%s rsync-native" % depends
+    d.setVar("DEPENDS", depends)
+
+    pn = d.getVar('PN')
+    d.appendVarFlag('do_populate_lic', 'depends', ' %s:do_configure' % pn)
+    workonsrc = d.getVar('WORKONSRC')
+    workonsrcbuild = d.getVar('WORKONSRC_BUILD')
+    if workonsrc and not workonsrc.startswith("/"):
+        bb.error("WORKONSRC must be an absolute path")
+    if workonsrcbuild and not workonsrcbuild.startswith("/"):
+        bb.error("WORKONSRC_BUILD must be an absolute path")
+
+    workonprebuilt = workonsrc.replace("build/../src/", "build/../prebuilt/")
+    if not os.path.exists(workonsrc):
+        if os.path.exists(workonprebuilt):
+            workonsrc = workonprebuilt
+        else:
+            bb.warn("Both %s and %s aren't existed" % (workonsrc, workonprebuilt) )
+
+    # If this is the base recipe and WORKONSRC is set for it or any of its
+    # derivatives, then enable BB_DONT_CACHE to force the recipe to always be
+    # re-parsed so that the file-checksums function for do_compile is run every
+    # time.
+    bpn = d.getVar('BPN')
+    classextend = (d.getVar('BBCLASSEXTEND') or '').split()
+    if bpn == d.getVar('PN') or not classextend:
+        if (workonsrc or
+                ('native' in classextend and
+                 d.getVar('WORKONSRC_pn-%s-native' % bpn)) or
+                ('nativesdk' in classextend and
+                 d.getVar('WORKONSRC_pn-nativesdk-%s' % bpn)) or
+                ('cross' in classextend and
+                 d.getVar('WORKONSRC_pn-%s-cross' % bpn))):
+            d.setVar('BB_DONT_CACHE', '1')
+
+    if workonsrc:
+        import oe.recipeutils
+        import oe.path
+
+        d.setVar('S', workonsrc)
+        if workonsrcbuild:
+            d.setVar('B', workonsrcbuild)
+        else:
+            d.setVar('B', '${WORKDIR}/${BPN}-${PV}/')
+            workonsrcbuild = d.getVar('B')
+
+        if workonsrc != workonsrcbuild:
+            d.setVar('S', workonsrcbuild)
+
+        local_srcuri = []
+        fetch = bb.fetch2.Fetch((d.getVar('SRC_URI') or '').split(), d)
+        for url in fetch.urls:
+            url_data = fetch.ud[url]
+            parm = url_data.parm
+            if (url_data.type == 'file' or
+                    'type' in parm and parm['type'] == 'kmeta'):
+                local_srcuri.append(url)
+
+        d.setVar('SRC_URI', ' '.join(local_srcuri))
+
+        if '{SRCPV}' in d.getVar('PV', False):
+            # Dummy value because the default function can't be called with blank SRC_URI
+            d.setVar('SRCPV', '999')
+
+        if d.getVar('CONFIGUREOPT_DEPTRACK') == '--disable-dependency-tracking':
+            d.setVar('CONFIGUREOPT_DEPTRACK', '')
+
+        tasks = filter(lambda k: d.getVarFlag(k, "task"), d.keys())
+
+        for task in tasks:
+            if task.endswith("_setscene"):
+                # sstate is never going to work for workon source trees, disable it
+                bb.build.deltask(task, d)
+            else:
+                # Since configure will likely touch ${S}, ensure only we lock so one task has access at a time
+                d.appendVarFlag(task, "lockfiles", " ${S}/singletask.lock")
+
+            # We do not want our source to be wiped out, ever (kernel.bbclass does this for do_clean)
+            cleandirs = oe.recipeutils.split_var_value(d.getVarFlag(task, 'cleandirs', False) or '')
+            setvalue = False
+            for cleandir in cleandirs[:]:
+                if oe.path.is_path_parent(workonsrc, d.expand(cleandir)):
+                    cleandirs.remove(cleandir)
+                    setvalue = True
+            if setvalue:
+                d.setVarFlag(task, 'cleandirs', ' '.join(cleandirs))
+
+        fetch_tasks = ['do_fetch', 'do_unpack']
+        # If we deltask do_patch, there's no dependency to ensure do_unpack gets run, so add one
+        # Note that we cannot use d.appendVarFlag() here because deps is expected to be a list object, not a string
+        d.setVarFlag('do_configure', 'deps', (d.getVarFlag('do_configure', 'deps', False) or []) + ['do_unpack'])
+
+        for task in d.getVar("SRCTREECOVEREDTASKS").split():
+            if local_srcuri and task in fetch_tasks:
+                continue
+            bb.build.deltask(task, d)
+
+        d.prependVarFlag('do_compile', 'prefuncs', "workonsrc_compile_prefunc ")
+        d.prependVarFlag('do_configure', 'prefuncs', "workonsrc_configure_prefunc ")
+
+        d.setVarFlag('do_compile', 'file-checksums', '${@srctree_hash_files(d)}')
+        d.setVarFlag('do_configure', 'file-checksums', '${@srctree_configure_hash_files(d)}')
+
+        # We don't want the workdir to go away
+        d.appendVar('RM_WORK_EXCLUDE', ' ' + d.getVar('PN'))
+
+        bb.build.addtask('do_buildclean',
+                         'do_clean' if d.getVar('S') == d.getVar('B') else None,
+                         None, d)
+
+
+        # If B=S the same builddir is used even for different architectures.
+        # Thus, use a shared CONFIGURESTAMPFILE and STAMP directory so that
+        # change of do_configure task hash is correctly detected and stamps are
+        # invalidated if e.g. MACHINE changes.
+        if d.getVar('S') == d.getVar('B'):
+            configstamp = '${TMPDIR}/work-shared/${PN}/${EXTENDPE}${PV}-${PR}/configure.sstate'
+            d.setVar('CONFIGURESTAMPFILE', configstamp)
+            d.setVar('STAMP', '${STAMPS_DIR}/work-shared/${PN}/${EXTENDPE}${PV}-${PR}')
+            d.setVar('STAMPCLEAN', '${STAMPS_DIR}/work-shared/${PN}/*-*')
+}
+
+python workonsrc_configure_prefunc() {
+    srctree_rsync_files(d)
+    s_dir = d.getVar('S')
+    # Create desired symlinks
+    symlinks = (d.getVar('EXTERNALSRC_SYMLINKS') or '').split()
+    newlinks = []
+    for symlink in symlinks:
+        symsplit = symlink.split(':', 1)
+        lnkfile = os.path.join(s_dir, symsplit[0])
+        target = d.expand(symsplit[1])
+        if len(symsplit) > 1:
+            if os.path.islink(lnkfile):
+                # Link already exists, leave it if it points to the right location already
+                if os.readlink(lnkfile) == target:
+                    continue
+                os.unlink(lnkfile)
+            elif os.path.exists(lnkfile):
+                # File/dir exists with same name as link, just leave it alone
+                continue
+            os.symlink(target, lnkfile)
+            newlinks.append(symsplit[0])
+    # Hide the symlinks from git
+    try:
+        git_exclude_file = os.path.join(s_dir, '.git/info/exclude')
+        if os.path.exists(git_exclude_file):
+            with open(git_exclude_file, 'r+') as efile:
+                elines = efile.readlines()
+                for link in newlinks:
+                    if link in elines or '/'+link in elines:
+                        continue
+                    efile.write('/' + link + '\n')
+    except IOError as ioe:
+        bb.note('Failed to hide EXTERNALSRC_SYMLINKS from git')
+}
+
+python workonsrc_compile_prefunc() {
+    srctree_rsync_files(d)
+    # Make it obvious that this is happening, since forgetting about it could lead to much confusion
+    bb.plain('NOTE: %s: compiling from workon source tree %s' % (d.getVar('PN'), d.getVar('WORKONSRC')))
+}
+
+do_buildclean[dirs] = "${S} ${B}"
+do_buildclean[nostamp] = "1"
+do_buildclean[doc] = "Call 'make clean' or equivalent in ${B}"
+workonsrc_do_buildclean() {
+	if [ -e Makefile -o -e makefile -o -e GNUmakefile ]; then
+		rm -f ${@' '.join([x.split(':')[0] for x in (d.getVar('EXTERNALSRC_SYMLINKS') or '').split()])}
+		if [ "${CLEANBROKEN}" != "1" ]; then
+			oe_runmake clean || die "make failed"
+		fi
+	else
+		bbnote "nothing to do - no makefile found"
+	fi
+}
+
+def srctree_rsync_files(d):
+    import subprocess, os.path
+
+    workonsrc = d.getVar('WORKONSRC')
+    workonprebuilt = workonsrc.replace("build/../src/", "build/../prebuilt/")
+    if not os.path.exists(workonsrc):
+        if os.path.exists(workonprebuilt):
+            workonsrc = workonprebuilt
+        else:
+            bb.warn("Both %s and %s aren't existed" % (workonsrc, workonprebuilt) )
+
+    if workonsrc:
+        d.setVar('S', workonsrc)
+        workonsrcbuild = d.getVar('WORKONSRC_BUILD')
+        if workonsrcbuild:
+            d.setVar('B', workonsrcbuild)
+        else:
+            d.setVar('B', '${WORKDIR}/${BPN}-${PV}/')
+            workonsrcbuild = d.getVar('B')
+
+        if workonsrc != workonsrcbuild:
+            cmd = "mkdir -p %s" % (workonsrcbuild)
+            subprocess.call(cmd, shell=True)
+
+            if os.path.exists(workonsrc):
+                workonsrc_rsync_appended_flag = d.getVar('WORKONSRC_RSYNC_APPENDED_FLAG')
+                if workonsrc_rsync_appended_flag is None:
+                    workonsrc_rsync_appended_flag=""
+                cmd = "rsync -aL %s %s/* %s" % (workonsrc_rsync_appended_flag, workonsrc, workonsrcbuild)
+                ret = subprocess.call(cmd, shell=True)
+                if ret != 0:
+                    bb.fatal("rsync -aL %s %s/* %s failed." % (workonsrc_rsync_appended_flag, workonsrc, workonsrcbuild))
+            d.setVar('S', workonsrcbuild)
+
+def srctree_hash_files(d, srcdir=None):
+    import shutil
+    import subprocess
+    import tempfile
+
+    s_dir = srcdir or d.getVar('WORKONSRC')
+    git_dir = None
+
+    try:
+        git_dir = os.path.join(s_dir,
+            subprocess.check_output(['git', '-C', s_dir, 'rev-parse', '--git-dir'], stderr=subprocess.DEVNULL).decode("utf-8").rstrip())
+    except subprocess.CalledProcessError:
+        pass
+
+    ret = " "
+    if git_dir is not None:
+        oe_hash_file = os.path.join(git_dir, 'oe-devtool-tree-sha1')
+        with tempfile.NamedTemporaryFile(prefix='oe-devtool-index') as tmp_index:
+            # Clone index
+            shutil.copyfile(os.path.join(git_dir, 'index'), tmp_index.name)
+            # Update our custom index
+            env = os.environ.copy()
+            env['GIT_INDEX_FILE'] = tmp_index.name
+            subprocess.check_output(['git', 'add', '-A', '.'], cwd=s_dir, env=env)
+            sha1 = subprocess.check_output(['git', 'write-tree'], cwd=s_dir, env=env).decode("utf-8")
+        with open(oe_hash_file, 'w') as fobj:
+            fobj.write(sha1)
+        ret = oe_hash_file + ':True'
+    else:
+        ret = s_dir + '/*:True'
+    return ret
+
+def srctree_configure_hash_files(d):
+    """
+    Get the list of files that should trigger do_configure to re-execute,
+    based on the value of CONFIGURE_FILES
+    """
+    in_files = (d.getVar('CONFIGURE_FILES') or '').split()
+    out_items = []
+    search_files = []
+    for entry in in_files:
+        if entry.startswith('/'):
+            out_items.append('%s:%s' % (entry, os.path.exists(entry)))
+        else:
+            search_files.append(entry)
+    if search_files:
+        s_dir = d.getVar('WORKONSRC')
+        for root, _, files in os.walk(s_dir):
+            for f in files:
+                if f in search_files:
+                    out_items.append('%s:True' % os.path.join(root, f))
+    return ' '.join(out_items)
+
+EXPORT_FUNCTIONS do_buildclean