#!/bin/bash
|
|
# this project absolute path
|
PRJ_PATH=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
|
|
# top project absolute path
|
TOP_PATH=$(realpath $PRJ_PATH/..)
|
|
# binaries build prefix install path
|
PRFX_PATH=$PRJ_PATH/install
|
|
# binaries finally install path if needed
|
#INST_PATH=/tftp
|
|
# compress system image or not
|
COMPRESS=yes
|
|
# 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
|
set -u
|
|
#+-------------------------+
|
#| Shell script functions |
|
#+-------------------------+
|
|
function pr_error() {
|
echo -e "\033[40;31m $1 \033[0m"
|
}
|
|
function pr_warn() {
|
echo -e "\033[40;33m $1 \033[0m"
|
}
|
|
function pr_info() {
|
echo -e "\033[40;32m $1 \033[0m"
|
}
|
|
# decompress a packet to destination path
|
function do_unpack()
|
{
|
tarball=$1
|
dstpath=`pwd`
|
|
if [[ $# == 2 ]] ; then
|
dstpath=$2
|
fi
|
|
pr_info "decompress $tarball => $dstpath"
|
|
mkdir -p $dstpath
|
case $tarball in
|
*.tar.gz)
|
tar -xzf $tarball -C $dstpath
|
;;
|
|
*.tar.bz2)
|
tar -xjf $tarball -C $dstpath
|
;;
|
|
*.tar.xz)
|
tar -xJf $tarball -C $dstpath
|
;;
|
|
*.tar.zst)
|
tar -I zstd -xf $tarball -C $dstpath
|
;;
|
|
*.tar)
|
tar -xf $tarball -C $dstpath
|
;;
|
|
*.zip)
|
unzip -qo $tarball -d $dstpath
|
;;
|
|
*)
|
pr_error "decompress Unsupport packet: $tarball"
|
return 1;
|
;;
|
esac
|
}
|
|
# parser configure file and export environment variable
|
function export_env()
|
{
|
export BOARD=`jq -r ".bsp.board" $CONF_FILE | tr 'A-Z' 'a-z'`
|
export BSP_VER=`jq -r ".bsp.version" $CONF_FILE | tr 'A-Z' 'a-z'`
|
export BSP_URL=`jq -r ".bsp.giturl" $CONF_FILE`
|
export DIS_TYPE=`jq -r ".system.distro" $CONF_FILE | tr 'A-Z' 'a-z'`
|
export DIS_VER=`jq -r ".system.version" $CONF_FILE | tr 'A-Z' 'a-z'`
|
export IMAGE_SIZE=`jq -r ".system.imgsize" $CONF_FILE | tr 'A-Z' 'a-z'`
|
export BOOT_SIZE=`jq -r ".system.bootsize" $CONF_FILE | tr 'A-Z' 'a-z'`
|
|
export LOOP_DEV=`losetup -f | cut -d/ -f3`
|
export MNT_POINT=$PRJ_PATH/mnt
|
|
export ROOTFS=rootfs-${DIS_VER}
|
export UBOOT_BINPATH=$TOP_PATH/bootloader/install/
|
export KERNEL_BINPATH=$TOP_PATH/kernel/install/
|
export ROOTFS_YCTPATH=$TOP_PATH/yocto/install/
|
export IMAGE_NAME=${DIS_TYPE}-${DIS_VER}-${BSP_VER}.img
|
export KERNEL_IMAGE=Image
|
|
if [[ $BOARD =~ mx8ulp ]] || [[ $BOARD =~ mx8mq ]] || [[ $BOARD =~ mx8mm ]] ; then
|
export UBOOT_OFFSET_SECTOR=66
|
elif [[ $BOARD =~ mx8mn ]] || [[ $BOARD =~ mx8mp ]] || [[ $BOARD =~ mx93 ]] ; then
|
export UBOOT_OFFSET_SECTOR=64
|
elif [[ $BOARD =~ mx6 ]] || [[ $BOARD =~ mx7 ]] ; then
|
export UBOOT_OFFSET_SECTOR=2
|
export KERNEL_IMAGE=zImage
|
fi
|
}
|
|
function do_fetch()
|
{
|
cd $PRJ_PATH
|
|
if [ -d $ROOTFS/bin ] ; then
|
pr_info "$ROOTFS fetched already"
|
return ;
|
fi
|
|
if [[ $DIS_TYPE == yocto ]] ; then
|
TAR_TYPE=tar.zst
|
else
|
TAR_TYPE=tar.xz
|
fi
|
|
# Decompress the rootfs form Yocto build install path
|
if [[ $DIS_TYPE == yocto ]] ; then
|
|
for tarball in $ROOTFS_YCTPATH/*.${TAR_TYPE}
|
do
|
if [ -s $tarball ] ; then
|
pr_warn "Decompress $ROOTFS from yocto install path"
|
mkdir -p $ROOTFS
|
do_unpack $tarball $ROOTFS
|
return ;
|
fi
|
done
|
fi
|
|
tarball=rootfs-${DIS_TYPE}-${DIS_VER}.${TAR_TYPE}
|
|
if [[ $BSP_URL =~ github.com ]] ; then
|
|
pr_error "INFO: Please download $tarball and decompress it to folder '$PRJ_PATH/$ROOTFS'"
|
|
else
|
|
pr_info "INFO: download $tarball form $BSP_URL"
|
|
mkdir -p $TARBALL_PATH
|
|
# Download source code packet
|
if [ ! -s $TARBALL_PATH/$tarball ] ; then
|
wget $BSP_URL/imx/${BOARD}/rootfs/$tarball -P $TARBALL_PATH
|
fi
|
|
# decompress source code packet
|
do_unpack $TARBALL_PATH/$tarball $ROOTFS
|
fi
|
|
if [ ! -d $ROOTFS/bin ] ; then
|
pr_error "Fetch rootfs $ROOTFS failed"
|
exit ;
|
fi
|
}
|
|
# System image layout map:
|
# +-------------------+--------------------+----------------------+
|
# | Raw Part(10MB) | FAT32 Part2(100MB) | EXT4 Part3(All left) |
|
# +-------------------+--------------------+----------------------+
|
# | U-boot on #64 | Kernel and DTB | Root file system |
|
# +-------------------+--------------------+----------------------+
|
|
function build_image()
|
{
|
# Uboot size set be 10MB and deployed in 64th sector on eMMC/TFCard
|
UBOOT_SIZE=10
|
|
mkdir -p $MNT_POINT
|
|
pr_info "start generate empty system image"
|
dd if=/dev/zero of=${IMAGE_NAME} bs=1024k count=${IMAGE_SIZE} conv=sync
|
chmod a+x ${IMAGE_NAME}
|
|
pr_info "start partition system image"
|
fat_start=$UBOOT_SIZE
|
fat_end=`expr $UBOOT_SIZE + $BOOT_SIZE`
|
parted ${IMAGE_NAME} mklabel msdos
|
parted ${IMAGE_NAME} mkpart primary fat32 ${fat_start}M ${fat_end}M
|
parted ${IMAGE_NAME} mkpart primary ext4 ${fat_end}M 100%
|
sync
|
|
pr_info "losetup system image on $LOOP_DEV"
|
losetup /dev/${LOOP_DEV} ${IMAGE_NAME}
|
kpartx -av /dev/${LOOP_DEV}
|
|
pr_info "start format system image"
|
mkfs.vfat /dev/mapper/${LOOP_DEV}p1
|
mkfs.ext4 /dev/mapper/${LOOP_DEV}p2
|
sync
|
|
pr_info "start install u-boot image"
|
dd if=$UBOOT_BINPATH/u-boot-${BOARD}.imx of=${IMAGE_NAME} bs=512 seek=$UBOOT_OFFSET_SECTOR conv=notrunc,sync
|
|
pr_info "start install linux kernel images"
|
mount -t vfat /dev/mapper/${LOOP_DEV}p1 ${MNT_POINT}
|
cp -rf $KERNEL_BINPATH/$KERNEL_IMAGE ${MNT_POINT}/
|
cp -rf $KERNEL_BINPATH/${BOARD}.dtb ${MNT_POINT}/
|
|
sync && umount ${MNT_POINT}
|
|
pr_info "update drivers in root filesystem"
|
rm -rf $ROOTFS/lib/modules/
|
mkdir -p $ROOTFS/lib/modules/
|
cp -rf $KERNEL_BINPATH/lib/modules/[0-9]*\.[0-9]*\.[0-9]* $ROOTFS/lib/modules/
|
|
pr_info "start install root filesystem"
|
mount -t ext4 /dev/mapper/${LOOP_DEV}p2 ${MNT_POINT}
|
cp -af $ROOTFS/* ${MNT_POINT}
|
sync && umount ${MNT_POINT}
|
|
pr_warn "Build system image $IMAGE_NAME done"
|
}
|
|
function exit_handler()
|
{
|
pr_warn "Shell script exit now, do some clean work\n"
|
set +e
|
|
if mountpoint ${MNT_POINT} > /dev/null 2>&1 ; then
|
pr_info "umount ${MNT_POINT}"
|
umount ${MNT_POINT} > /dev/null 2>&1
|
fi
|
|
rm -rf ${MNT_POINT}
|
|
if [ -e /dev/mapper/${LOOP_DEV}p1 ] ; then
|
pr_info "kpartx -dv /dev/${LOOP_DEV}"
|
kpartx -dv /dev/${LOOP_DEV}
|
fi
|
|
losetup -a | grep "${LOOP_DEV}" > /dev/null 2>&1
|
if [ $? == 0 ] ; then
|
pr_info "losetup -d /dev/${LOOP_DEV}"
|
losetup -d /dev/${LOOP_DEV}
|
fi
|
}
|
|
function do_build()
|
{
|
cd $PRJ_PATH
|
|
build_image
|
}
|
|
function do_install()
|
{
|
cd $PRJ_PATH
|
|
if [[ `echo $COMPRESS | tr 'A-Z' 'a-z'` == "yes" ]] ; then
|
pr_info "Start bzip2 compress $IMAGE_NAME"
|
rm -f $IMAGE_NAME.bz2
|
bzip2 $IMAGE_NAME
|
fi
|
|
mkdir -p $PRFX_PATH
|
mv $IMAGE_NAME* $PRFX_PATH
|
cp $UBOOT_BINPATH/u-boot-${BOARD}.imx $PRFX_PATH
|
|
if [[ -n "$INST_PATH" && -w $INST_PATH ]] ; then
|
pr_info "install bootloader and system image to '$INST_PATH'"
|
cp $PRFX_PATH/u-boot-${BOARD}.imx $INST_PATH
|
cp $PRFX_PATH/$IMAGE_NAME* $INST_PATH
|
fi
|
}
|
|
function do_clean()
|
{
|
for d in rootfs-*
|
do
|
rm -rf $PRJ_PATH/$d
|
done
|
|
rm -rf $PRJ_PATH/tarballs
|
rm -rf $PRFX_PATH
|
rm -f *.img
|
}
|
|
#+-------------------------+
|
#| Shell script body entry |
|
#+-------------------------+
|
|
if [ `id -u` != 0 ] ; then
|
pr_error "ERROR: This shell script must run as root"
|
exit;
|
fi
|
|
cd $PRJ_PATH
|
|
export_env
|
|
if [[ $# == 1 && $1 == -c ]] ;then
|
pr_warn "start clean system image"
|
do_clean
|
exit;
|
fi
|
|
pr_warn "Build system image $IMAGE_NAME"
|
|
trap 'exit_handler' EXIT
|
|
do_fetch
|
|
do_build
|
|
do_install
|