替代imx6ull mfgtool的方法

1. 背景

用mfgtool烧写imx6ull非常麻烦,要在windows下操作,每次也要等很久,我的使用场景就是两种:

第一种: 将boot/dtb/zImage/rootfs烧到一张sd卡,用sd卡启动(最方便,ubuntu PC操作)

第二种: 在sd卡启动的系统上,将镜像全部烧写到emmc(需要利用单板烧写)

2. 解题方法

因为NXP提供的烧写工具mfgtool就可以将准备好的上述镜像文件烧写到emmc或者sd卡中,而且mfgtool的原理是先下载并启动一个制作好的linux(ramfs), 再利用这个linux去烧写emmc或者sd卡。既然都是linux系统,我完全可以参考mfgtool的实现,在自己的ubuntu上实现sd卡的烧写,节省时间

参考ucl2.xml的流程:

3. 烧写脚本使用方法

@如果在ubuntu PC上烧写,需要看好你的sd卡是/dev/sdx,不要烧到了ubuntu本身的硬盘,并且需要注意的是要禁用ubuntu系统自己身的自动挂载功能,否则在脚本的磁盘操作中要告警:

ubuntu系统的磁盘自动挂载功能是由udisks2.service做的,如果你的系统会自动挂载U盘,不妨使用systemctl status udisks2.service看看日志就知道自动挂载是不是它干的,那么怎么禁用它呢?

参考: udisks - ArchWiki (archlinux.org)

自己写一个规则然后systemctl restart systemd-udevd来生效,比如我自己的系统上:

@如果在imx6ull上烧写emmc,也要禁用系统的自动挂载用能,比如我的单板上的自动挂载功能如下, 禁用即可

烧写过程截图:

ubuntu PC烧写:

imx6ull单板烧写:

4. 脚本代码

#!/bin/bash

# this script used to burn uboot/dtb/kernel/rootfs on sd card or emmc
readonly EMMC=/dev/mmcblk1
readonly EMMC_BOOT0=mmcblk1boot0
readonly EMMC_BOOT1=mmcblk1boot1

# create partition
function create_partition() {

    # partition size in MB
    local BOOT_ROM_SIZE=10

    # wait for the SD/MMC device node ready
    while [ ! -e "$1" ]
    do
        sleep 1
        echo "[DEBUG]wait for $1 appear"
    done

    # call sfdisk to create partition table
    # destroy the partition table
    local node=$1
    dd if=/dev/zero of="$1" bs=1024 count=1 conv=fsync

    # two partitions:
    # part1: boot:   10M~138M: zImage & dtb
    # part2: rootfs: 138M~end: rootfs

    #^-- SC1039: Use <<- instead of << if you want to indent the end token.
    #^-- SC1040: When using <<-, you can only indent with tabs.
    sfdisk --force "${node}" <<- PARTINFO
    ${BOOT_ROM_SIZE}M,128M,c
    138M,,83
    write
	PARTINFO

    #keep the name of BOOT_DEVICE
    BOOT_DEVICE=$1
    BOOT_PART=1
    ROOTFS_PART=2
    if [ "${BOOT_MEDIA}" = "${EMMC}" ]
    then
        BOOT_DEVICE=${EMMC}
        BOOT_PART=p1
        ROOTFS_PART=p2
    fi
}

# burn uboot
function burn_uboot() {
    
    # clear uboot env
    dd if=/dev/zero of=${BOOT_DEVICE} bs=1k seek=768 count=8 conv=fsync

    # burn uboot
    if [ "${BOOT_DEVICE}" = "${EMMC}" ]
    then
        echo 0 > /sys/block/${EMMC_BOOT0}/force_ro
        dd if="$1" of=${BOOT_DEVICE}boot0 bs=512 seek=2 conv=fsync
        echo 1 > /sys/block/${EMMC_BOOT0}/force_ro
        mmc bootpart enable 1 1 ${BOOT_DEVICE} #default boot0
    else
        dd if="$1" of=${BOOT_DEVICE} bs=1k seek=1 conv=fsync
    fi
}

# burn boot part
function burn_bootpart() {

    while [ ! -e "${BOOT_DEVICE}${BOOT_PART}" ]
    do
        echo "[debug]waiting bootpart...1"
        sleep 1
    done

    # format to FAT32
    mkfs.vfat -F 32 -n boot ${BOOT_DEVICE}${BOOT_PART}

    #while [ ! -e "${BOOT_DEVICE}${BOOT_PART}" ]
    #do
        #echo "[debug]waiting bootpart...2"
        #sleep 1
    #done

    mkdir -p /mnt/mmcblk0p1
    mount -t vfat ${BOOT_DEVICE}${BOOT_PART} /mnt/mmcblk0p1

    cp "$1" /mnt/mmcblk0p1 #dtb
    cp "$2" /mnt/mmcblk0p1 #zImage

    sleep 3
    sync
    umount /mnt/mmcblk0p1
    sleep 1
    rm -rf /mnt/mmcblk0p1
    sync
}

# burn rootfs
function burn_rootfs() {

    while [ ! -e "${BOOT_DEVICE}${ROOTFS_PART}" ]
    do
        echo "[debug]waiting rootfspart...1"
        sleep 1
    done

    # format to ext3
    mkfs.ext3 -F -j -L rootfs "${BOOT_DEVICE}${ROOTFS_PART}"

    while [ ! -e "${BOOT_DEVICE}${ROOTFS_PART}" ]
    do
        echo "[debug]waiting rootfspart...2"
        sleep 1
    done

    mkdir -p /mnt/mmcblk0p2
    mount -t ext3 "${BOOT_DEVICE}${ROOTFS_PART}" /mnt/mmcblk0p2

    echo "[DEBUG]buring rootfs......"
    tar -jxf "$1" -C /mnt/mmcblk0p2 #rootfs.tar.bz2
    sleep 1
    tar -jxf "$2" -C /mnt/mmcblk0p2/lib/modules #modules.tar.bz2
    sleep 1
    sync
    sleep 3
    umount /mnt/mmcblk0p2
    sleep 1
    rm -rf /mnt/mmcblk0p2
    sync
}

function usage() {
    echo "#################################################################################################################"
    echo "# Usage: ./burn_sdcard.sh <path> <uboot-name> <dtb-name> <zImage-name> <rootfs-name> <modules-name> <BOOT_MEDIA>#"
    echo "# Instruction    :   burn <your files locations> <your files> <to where>                                        #"
    echo "# Sd card Example: ./burn_sdcard.sh . uboot.imx dtb zImage rootfs.tar.bz2 modules.tar.bz2 /dev/sda              #"
    echo "# Emmc    Example: ./burn_sdcard.sh . uboot.imx dtb zImage rootfs.tar.bz2 modules.tar.bz2 /dev/mmcblk1          #"
    echo "#################################################################################################################"
    exit 0
}

#======main======
if [ $# -ne 7 ]
then
    usage
fi

readonly ABSOLUTE_PATH=$1
readonly UBOOT_IMG=${ABSOLUTE_PATH}/$2
readonly DTB=${ABSOLUTE_PATH}/$3
readonly ZIMAGE=${ABSOLUTE_PATH}/$4
readonly ROOTFS=${ABSOLUTE_PATH}/$5
readonly MODULES=${ABSOLUTE_PATH}/$6
readonly BOOT_MEDIA=$7 #/dev/sda | /dev/mmcblk1

#check exist? no here

echo "[DEBUG]burning......"
create_partition "${BOOT_MEDIA}"
burn_uboot "${UBOOT_IMG}"

echo "@@@@@@@@@@@@@@@@@@@@"
echo "checkcheckcheckcheck"
ls -la ${BOOT_MEDIA}*
echo "@@@@@@@@@@@@@@@@@@@@"

burn_bootpart "${DTB}" "${ZIMAGE}"
burn_rootfs "${ROOTFS}" "${MODULES}"
wait
echo "[DEBUG]burn ${BOOT_MEDIA} complete!"

5. 参考资料

1). ubuntu-debian怎么禁用自动挂载:

udisks - ArchWiki (archlinux.org)

补充一下udisks2与udiskie的关系:

udisks本身不能实现自动挂载功能,需要一些wrappers去共同实现automount功能,比如udiskie

2). shell脚本进入subshell场景分析

进入子shell的各种情况分析_什么情况下会进入子shell、-CSDN博客

3). dd命令的conv=fsync oflag=dsync/sync

dd命令的conv=fsync,oflag=sync/dsync_oflag=dsync-CSDN博客

最后,有个大佬跟我说自己写shell脚本可以用工具shellcheck去检查一下,apt update;apt install shell check;就可以使用了,当然这个脚本我没有使用,有不对的地方日后来改或者你给我留言

  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值