#!/bin/bash
|
|
# Build Cortex-M FreeRTOS SDK or not
|
#BUILD_MCORE=yes
|
|
# this project absolute path
|
PRJ_PATH=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
|
|
# top project absolute path
|
TOP_PATH=$(realpath $PRJ_PATH/..)
|
|
# binaries build prefix install path
|
PRFX_PATH=$PRJ_PATH/install
|
|
# binaries finally install path if needed
|
#INST_PATH=/tftp
|
|
# download taballs path
|
TARBALL_PATH=$PRJ_PATH/tarballs
|
|
# config file path
|
CONF_FILE=$TOP_PATH/config.json
|
|
# shell script will exit once get command error
|
set -e
|
|
#+-------------------------+
|
#| Shell script functions |
|
#+-------------------------+
|
|
function pr_error() {
|
echo -e "\033[40;31m $1 \033[0m"
|
}
|
|
function pr_warn() {
|
echo -e "\033[40;33m $1 \033[0m"
|
}
|
|
function pr_info() {
|
echo -e "\033[40;32m $1 \033[0m"
|
}
|
|
# decompress a packet to destination path
|
function do_unpack()
|
{
|
tarball=$1
|
dstpath=`pwd`
|
|
if [[ $# == 2 ]] ; then
|
dstpath=$2
|
fi
|
|
pr_info "decompress $tarball => $dstpath"
|
|
mkdir -p $dstpath
|
case $tarball in
|
*.tar.gz)
|
tar -xzf $tarball -C $dstpath
|
;;
|
|
*.tar.bz2)
|
tar -xjf $tarball -C $dstpath
|
;;
|
|
*.tar.xz)
|
tar -xJf $tarball -C $dstpath
|
;;
|
|
*.tar.zst)
|
tar -I zstd -xf $tarball -C $dstpath
|
;;
|
|
*.tar)
|
tar -xf $tarball -C $dstpath
|
;;
|
|
*.zip)
|
unzip -qo $tarball -d $dstpath
|
;;
|
|
*)
|
pr_error "decompress Unsupport packet: $tarball"
|
return 1;
|
;;
|
esac
|
}
|
|
# select firmware version by BSP version
|
function export_fmver()
|
{
|
if [[ $BSP_VER =~ 6.1.36 ]] ; then
|
|
export FMW_IMX=firmware-imx-8.21
|
|
fi
|
|
export FMWS="$FMW_IMX"
|
export FMW_URL=https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/
|
export FMW_PATH=$PRJ_PATH/firmware/
|
}
|
|
# parser configure file and export environment variable
|
function export_env()
|
{
|
export BOARD=`jq -r ".bsp.board" $CONF_FILE | tr 'A-Z' 'a-z'`
|
export BSP_VER=`jq -r ".bsp.version" $CONF_FILE | tr 'A-Z' 'a-z'`
|
export BSP_URL=`jq -r ".bsp.giturl" $CONF_FILE`
|
export CROSS_COMPILE=`jq -r ".bsp.cortexAtool" $CONF_FILE`
|
export MCORE_COMPILE=`jq -r ".bsp.cortexMtool" $CONF_FILE`
|
|
export BRANCH=$BSP_VER
|
export JOBS=`cat /proc/cpuinfo | grep processor | wc -l`
|
export ARCH=arm
|
|
# i.MX6ULL only need uboot-imx
|
if [[ $BOARD =~ mx6ull ]] ; then
|
export SRCS="uboot-imx"
|
return ;
|
fi
|
|
export SRCS="uboot-imx imx-atf imx-mkimage"
|
export_fmver
|
|
if [[ $BOARD =~ mx8mp ]] ; then
|
|
ATF_PLATFORM=imx8mp
|
IMX_BOOT_SOC_TARGET=iMX8MP
|
IMXBOOT_TARGETS=flash_evk
|
IMXBOOT_DTB=imx8mp-evk.dtb
|
MKIMG_BIN_PATH=$PRJ_PATH/imx-mkimage/iMX8M/
|
|
elif [[ $BOARD =~ mx8mm ]] ; then
|
|
ATF_PLATFORM=imx8mm
|
IMX_BOOT_SOC_TARGET=iMX8MM
|
IMXBOOT_TARGETS=flash_ddr4_evk
|
IMXBOOT_DTB=imx8mm-ddr4-evk.dtb
|
MKIMG_BIN_PATH=$PRJ_PATH/imx-mkimage/iMX8M/
|
|
fi
|
}
|
|
function do_fetch()
|
{
|
cd $PRJ_PATH
|
|
for src in $SRCS
|
do
|
if [ -d $src ] ; then
|
pr_info "$src source code fetched already"
|
continue
|
fi
|
|
pr_info "start fetch $src source code"
|
|
if [[ $BSP_URL =~ github.com ]] ; then
|
git clone $BSP_URL/$src.git -b $BRANCH --depth=1
|
else
|
mkdir -p $TARBALL_PATH
|
|
# Download source code packet
|
if [ ! -s $TARBALL_PATH/$src.tar.xz ] ; then
|
wget $BSP_URL/imx/bsp/$BSP_VER/$src.tar.xz -P $TARBALL_PATH
|
fi
|
|
# decompress source code packet
|
do_unpack $TARBALL_PATH/$src.tar.xz
|
fi
|
|
# do patch if patch file exist
|
patch_file=$PRJ_PATH/patches/$BOARD/$src-$BSP_VER.patch
|
if [ -s $patch_file ] ; then
|
pr_warn "do patch for $src now..."
|
cd $src
|
patch -p1 < $patch_file
|
cd -
|
fi
|
done
|
|
# i.MX6ULL only need uboot-imx
|
if [[ $BOARD =~ mx6ull ]] ; then
|
return ;
|
fi
|
|
# Download CortexM FreeRTOS SDK if needed
|
if [ "$BUILD_MCORE" == "yes" ] ; then
|
|
src=cortexm-sdk
|
|
cd $PRJ_PATH
|
|
if [ -d $src ] ; then
|
pr_info "$src source code fetched already"
|
else
|
pr_info "start fetch $src source code"
|
|
if [[ $BSP_URL =~ github.com ]] ; then
|
pr_error "INFO: Please download $BOARD CortexM SDK from https://mcuxpresso.nxp.com by manual."
|
else
|
pack=cortexm-sdk-${BOARD}
|
|
# Download source code packet
|
if [ ! -s $TARBALL_PATH/$pack.tar.gz ] ; then
|
wget $BSP_URL/bsp/$BSP_VER/$pack.tar.gz -P $TARBALL_PATH
|
fi
|
|
# decompress source code packet
|
do_unpack $TARBALL_PATH/$pack.tar.gz $PRJ_PATH/$src
|
fi
|
fi
|
fi
|
|
# Download firmware from NXP official URL
|
mkdir -p $FMW_PATH && cd $FMW_PATH
|
|
for fmw in $FMWS
|
do
|
if [ -d $fmw ] ; then
|
pr_info "Firmware $fmw fetch already"
|
continue
|
fi
|
pr_info "start fetch $fmw firmware"
|
wget $FMW_URL/$fmw.bin
|
|
bash $fmw.bin --auto-accept > /dev/null 2>&1
|
done
|
|
rm -f *.bin
|
}
|
|
function build_atf()
|
{
|
SRC=imx-atf
|
|
pr_warn "start build $SRC"
|
cd $PRJ_PATH/${SRC}
|
|
make -j${JOBS} CROSS_COMPILE=${CROSS_COMPILE} PLAT=$ATF_PLATFORM bl31
|
|
set -x
|
cp build/$ATF_PLATFORM/release/bl31.bin $MKIMG_BIN_PATH
|
set +x
|
}
|
|
# Cortex-M SDK download from https://mcuxpresso.nxp.com/ by manual
|
function build_cortexM()
|
{
|
SRC=cortexm-sdk
|
|
if [ "$BUILD_MCORE" != "yes" ] ; then
|
pr_warn "Skip build Cortex-M core SDK source code '$SRC'"
|
return 0;
|
fi
|
|
if [[ $BOARD =~ mx8mp ]] ; then
|
EVK=evkmimx8mp
|
fi
|
DEMO_PATH=boards/$EVK/multicore_examples/rpmsg_lite_str_echo_rtos/armgcc
|
DEMO_BIN=release/rpmsg_lite_str_echo_rtos.bin
|
MCORE_IMAGE=cortexM-${BOARD}.bin
|
|
if [ ! -d $PRJ_PATH/$SRC ] ; then
|
pr_error "INFO: Please download $BOARD SDK from https://mcuxpresso.nxp.com by manual and"
|
pr_error " decompress it to folder '$PRJ_PATH/$SRC'"
|
exit;
|
fi
|
|
pr_warn "start build $SRC"
|
|
cd $PRJ_PATH/${SRC}/$DEMO_PATH
|
export ARMGCC_DIR=$(echo $MCORE_COMPILE | sed 's\/bin/.*\\')
|
|
#bash clean.sh
|
if [ ! -s $DEMO_BIN ] ; then
|
bash build_release.sh
|
fi
|
|
set -x
|
cp $DEMO_BIN $PRFX_PATH/$MCORE_IMAGE
|
set +x
|
}
|
|
function build_uboot()
|
{
|
SRC=uboot-imx
|
patch_file=$PRJ_PATH/patches/$BOARD/$SRC-$BSP_VER.patch
|
defconfig=${BOARD}_defconfig
|
|
pr_warn "start build $SRC"
|
cd $PRJ_PATH/${SRC}
|
|
# do patch if not patched
|
if [ ! -s configs/$defconfig -a -s $patch_file ] ; then
|
pr_warn "do patch for $SRC now..."
|
patch -p1 < $patch_file
|
fi
|
|
if [ ! -f .config ] ; then
|
make ARCH=arm ${BOARD}_defconfig
|
fi
|
make -j${JOBS} CROSS_COMPILE=${CROSS_COMPILE} ARCH=arm
|
|
# i.MX6ULL only need uboot-imx
|
if [[ $BOARD =~ mx6ull ]] ; then
|
cp u-boot-dtb.imx u-boot-${BOARD}.imx
|
chmod a+x u-boot-${BOARD}.imx
|
set -x
|
cp u-boot-${BOARD}.imx $PRFX_PATH
|
set +x
|
return 0;
|
fi
|
|
set -x
|
cp u-boot.bin $MKIMG_BIN_PATH
|
cp u-boot-nodtb.bin $MKIMG_BIN_PATH
|
cp spl/u-boot-spl.bin $MKIMG_BIN_PATH
|
cp arch/arm/dts/${BOARD}.dtb $MKIMG_BIN_PATH/$IMXBOOT_DTB
|
cp tools/mkimage $MKIMG_BIN_PATH/mkimage_uboot
|
set +x
|
}
|
|
# The diagram below illustrate a signed iMX8 flash.bin image layout:
|
# reference: uboot-imx/doc/imx/habv4/guides/mx8m_secure_boot.txt
|
#
|
# +-----------------------------+
|
# | |
|
# | *Signed HDMI/DP FW |
|
# | |
|
# +-----------------------------+
|
# | Padding |
|
# ------- +-----------------------------+ --------
|
# ^ | IVT - SPL | ^
|
# Signed | +-----------------------------+ |
|
# Data | | u-boot-spl.bin | |
|
# | | + | | SPL
|
# v | DDR FW | | Image
|
# ------- +-----------------------------+ |
|
# | CSF - SPL + DDR FW | v
|
# +-----------------------------+ --------
|
# | Padding |
|
# ------- +-----------------------------+ --------
|
# Signed ^ | FDT - FIT | ^
|
# Data | +-----------------------------+ |
|
# v | IVT - FIT | |
|
# ------- +-----------------------------+ |
|
# | CSF - FIT | |
|
# ------- +-----------------------------+ | FIT
|
# ^ | u-boot-nodtb.bin | | Image
|
# | +-----------------------------+ |
|
# Signed | | OP-TEE (Optional) | |
|
# Data | +-----------------------------+ |
|
# | | bl31.bin (ATF) | |
|
# | +-----------------------------+ |
|
# v | u-boot.dtb | v
|
# ------- +-----------------------------+ --------
|
#
|
#
|
# Reference: <<IMX_LINUX_USERS_GUIDE.pdf>> 4.5.13 How to build imx-boot image by using imx-mkimage
|
|
function build_imxboot()
|
{
|
SRC=imx-mkimage
|
|
pr_warn "start build $SRC"
|
cd $PRJ_PATH/${SRC}
|
|
# iMX8MP, iMX8MP
|
if [[ $BOARD =~ mx8m ]] ; then
|
pr_info "Copy DDR4 firmware to $MKIMG_BIN_PATH"
|
|
cp $FMW_PATH/firmware-imx-*/firmware/hdmi/cadence/signed_hdmi_imx8m.bin $MKIMG_BIN_PATH
|
cp $FMW_PATH/firmware-imx-*/firmware/ddr/synopsys/lpddr4_pmu_train_[1-2]d_imem_202006.bin $MKIMG_BIN_PATH
|
cp $FMW_PATH/firmware-imx-*/firmware/ddr/synopsys/lpddr4_pmu_train_[1-2]d_dmem_202006.bin $MKIMG_BIN_PATH
|
fi
|
|
make SOC=$IMX_BOOT_SOC_TARGET $IMXBOOT_TARGETS
|
|
cp $MKIMG_BIN_PATH/flash.bin u-boot-${BOARD}.imx
|
chmod a+x u-boot-${BOARD}.imx
|
|
cp u-boot-${BOARD}.imx $PRFX_PATH
|
}
|
|
function do_build()
|
{
|
cd $PRJ_PATH
|
mkdir -p $PRFX_PATH
|
|
build_uboot
|
|
# i.MX6ULL only need uboot-imx
|
if [[ ${BOARD} =~ mx6ull ]] ; then
|
return ;
|
fi
|
|
build_atf
|
build_imxboot
|
build_cortexM
|
}
|
|
function do_install()
|
{
|
cd $PRJ_PATH
|
|
echo ""
|
pr_info "bootloader installed to '$PRFX_PATH'"
|
ls $PRFX_PATH && echo ""
|
|
if [[ -n "$INST_PATH" && -w $INST_PATH ]] ; then
|
pr_info "install bootloader to '$INST_PATH'"
|
cp $PRFX_PATH/* $INST_PATH
|
#sz $PRFX_PATH/u-boot-${BOARD}.imx
|
fi
|
}
|
|
function do_clean()
|
{
|
for d in $SRCS
|
do
|
rm -rf $PRJ_PATH/$d
|
done
|
|
rm -rf $PRJ_PATH/firmware
|
rm -rf $PRJ_PATH/cortexm-sdk
|
rm -rf $PRJ_PATH/tarballs
|
rm -rf $PRFX_PATH
|
}
|
|
#+-------------------------+
|
#| Shell script body entry |
|
#+-------------------------+
|
|
cd $PRJ_PATH
|
|
export_env
|
|
if [[ $# == 1 && $1 == -c ]] ;then
|
pr_warn "start clean bootloader"
|
do_clean
|
exit;
|
fi
|
|
pr_warn "start build bootloader for ${BOARD}"
|
|
do_fetch
|
|
do_build
|
|
do_install
|