#!/bin/bash # this project absolute path PRJ_PATH=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd) # top project absolute path TOP_PATH=$(realpath $PRJ_PATH/..) # binaries install path INST_PATH=$PRJ_PATH/install # 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 } # parser configure file and export environment variable function export_env() { export BOARD=`jq -r ".bsp.board" $CONF_FILE | tr 'A-Z' 'a-z'` export BSPVER=`jq -r ".bsp.version" $CONF_FILE | tr 'A-Z' 'a-z'` export URL=`jq -r ".bsp.download" $CONF_FILE | tr 'A-Z' 'a-z'` export DISTRO=`jq -r ".system.distro" $CONF_FILE | tr 'A-Z' 'a-z'` export DISVER=`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 ROOTFS=rootfs-${DISTRO}-${DISVER} export IMAGE_NAME=$DISTRO-$DISVER-$BSPVER.img # i.MX6ULL only need build uboot-imx if [[ $BOARD =~ 6ull ]] ; then # u-boot will be deployed in 2nd sector on eMMC/TFCard export UBOOT_SECTOR=2 # i.MX8MP need build atf and u-boot elif [[ $BOARD =~ 8mp ]] ; then # u-boot will be deployed in 64th sector on eMMC/TFCard export UBOOT_SECTOR=64 fi } function do_fetch() { cd $PRJ_PATH SRCS=$ROOTFS SUFIX=tar.xz if [ -d $ROOTFS/bin ] ; then pr_info "$ROOTFS fetched already" return ; fi if [ $DISTRO == yocto ] ; then if [[ $YCT_VER != hardknott && $YCT_VER != honister ]] ; then SUFIX=tar.zst fi fi # Download source code packet if [ ! -s $TARBALL_PATH/$ROOTFS.$SUFIX ] ; then pr_info "start fetch $ROOTFS source code" mkdir -p $TARBALL_PATH wget $URL/$BOARD/rootfs/$ROOTFS.$SUFIX -P $TARBALL_PATH fi # decompress source code packet mkdir -p $ROOTFS do_unpack $TARBALL_PATH/$ROOTFS.$SUFIX $ROOTFS } # System image layout map: # +-------------------+--------------------+----------------------+ # | Raw Part(10MB) | FAT32 Part2(100MB) | EXT4 Part3(All left) | # +-------------------+--------------------+----------------------+ # | U-boot on #2/#64 | Kernel and DTB | Root file system | # +-------------------+--------------------+----------------------+ function build_image() { UBOOT_SIZE=10 UBOOT_BINPATH=$TOP_PATH/bootloader/install/ KERNEL_BINPATH=$TOP_PATH/kernel/install/ export LOOP_DEV=`losetup -f | cut -d/ -f3` export MNT_POINT=$PRJ_PATH/mnt pr_warn "Build $DISTRO-$DISVER system image" 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=66 conv=notrunc,sync pr_info "start install linux kernel images" mkdir -p $MNT_POINT mount -t vfat /dev/mapper/${LOOP_DEV}p1 ${MNT_POINT} cp -rf $KERNEL_BINPATH/zImage ${MNT_POINT}/ cp -rf $KERNEL_BINPATH/${BOARD}.dtb ${MNT_POINT}/ cp -rf $KERNEL_BINPATH/overlays/ ${MNT_POINT}/ cp -rf files/config-${BOARD}.txt ${MNT_POINT}/config.txt 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/* $ROOTFS/lib/ pr_info "start install root filesystem" mount -t ext4 /dev/mapper/${LOOP_DEV}p2 ${MNT_POINT} cp -af $ROOTFS/* ${MNT_POINT} cp -rf files/pinctrl-${BOARD} ${MNT_POINT}/usr/sbin/pinctrl cp -rf files/pinloop ${MNT_POINT}/usr/sbin/ cp -rf files/expand_rootfs ${MNT_POINT}/usr/sbin/ chmod +x ${MNT_POINT}/usr/sbin/pinctrl chmod +x ${MNT_POINT}/usr/sbin/pinloop chmod +x ${MNT_POINT}/usr/sbin/expand_rootfs sync && umount ${MNT_POINT} pr_warn "Build $DISTRO-$DISVER system image down" } 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 [ -z ${LOOP_DEV} ] ; then return ; fi 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 mkdir -p $INST_PATH cp $UBOOT_BINPATH/u-boot-${BOARD}.imx $INST_PATH mv $IMAGE_NAME $INST_PATH cd $INST_PATH pr_info "\ncompress system images $IMAGE_NAME" bzip2 $IMAGE_NAME pr_info "\nsystem images installed to '$INST_PATH'" ls && echo "" } function do_clean() { for d in rootfs-* do rm -rf $PRJ_PATH/$d done rm -rf $INST_PATH rm -f *.img rm -rf $TARBALL_PATH } #+-------------------------+ #| 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 "start build $DISTRO-$DISVER for ${BOARD}" trap 'exit_handler' EXIT do_fetch do_build do_install