这里以基于 IMX6_L4.1.15_2.1.0_MFG_TOOL 修改后的文件为说明,官方下载可以去 NXP 官网直接搜。

# mfgtool 工具

mfgtool 工具是 freescale 为 i.MX 系列处理器打造的 Linux Firmware (uboot/kernel) 烧录工具,被收购后由 NXP 维护,其工具支持单独烧录某一系统分区,支持烧录 spi flash、 nor flash、sd card、nand flash、emmc 等存储介质,只需简单的配置,即可将编译好的镜像文件和文件系统烧录到完整的板上。同时 mfgtool 工具也作为一个可量产性的工具,它支持多通道的烧录。

最新版的 mfgtool 工具可看:https://github.com/nxp-imx/mfgtools

对于官方 L4.1.15_2.1.0 版本,解压后里面有两个压缩包,两个压缩包的区别在名字上已经写的很详细了。 “without-rootfs” 和 “with-rootfs”,一个是没有文件系统和一个是具有文件系统,对比可以看到 without-rootfs 中的 rootfs 是个空的包。

# 配置文件

在该版本中,主要用到的配置 UICfg.ini、cfg.ini 以及 ucl2.xml。

# UICfg.ini

UICfg.ini 文件用于配置端口数量,表示同时支持多少个单板。

UICfg.ini 文件的格式如下:

[UICfg]
PortMgrDlg=1

例如,如果一次只支持一个单板,则应该设置 PortMgrDlg=1 。目前最多支持 4 块单板,所以 PortMgrDlg 可以设置为 1 - 4,默认为 1。

# cfg.ini

cfg.ini 文件用于配置目标芯片配置文件和目标操作列表。

该文件的格式如下所示:

[profiles]
chip = Linux
[platform]
board = SabreSD
[LIST]
name = SDCard
[variable]
board = sabresd
mmc = 0
bootimx = 14x14evk
bootdtb = 14x14-evk
6uluboot = 14x14ddr3arm2
6uldtb = 14x14-ddr3-arm2
lite = l
initramfs = fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot
seek = 1
rootfs = rootfs
6ulnor = qspi1
part_nor = 0
part_uboot = 0
part_kernel = 1
part_dtb = 2
part_rootfs = 3
  • profiles/chip 为目标配置文件名称(不区分大小写)。

  • LIST/name 为目标操作列表名称(区分大小写),可在 profiles/CHIP_PROFILE/OS Firmware/ucl2.xml 文件中找到。 ucl2.xml 内容在后续说明。

  • platform/board 目前预留,未使用,请忽略。

  • variableucl2.xml 文件中的引用变量,其引用的方式为 %…%

# ucl2.xml

以下为个人自用修改后的版本,适用于 6UL 和 6ULL:

<!--
* Copyright (C) 2012, Freescale Semiconductor, Inc. All Rights Reserved.
* The CFG element contains a list of recognized usb devices.
*  DEV elements provide a name, class, vid and pid for each device.
*
* Each LIST element contains a list of update instructions.
*  "Install" - Erase media and install firmware.
*  "Update" - Update firmware only.
*
* Each CMD element contains one update instruction of attribute type.
*  "pull" - Does UtpRead(body, file) transaction.
*  "push" - Does UtpWrite(body, file) transaction.
*  "drop" - Does UtpCommand(body) then waits for device to disconnect.
*  "boot" - Finds configured device, forces it to "body" device and downloads "file".
*  "find" - Waits for "timeout" seconds for the "body" device to connect.
*  "show" - Parse and show device info in "file".  
-->
<UCL>
  <CFG>
    <STATE name="BootStrap" dev="MX6UL" vid="15A2" pid="007D"/>
    <STATE name="BootStrap" dev="MX6ULL" vid="15A2" pid="0080"/>
    <STATE name="Updater"   dev="MSC" vid="066F" pid="37FF"/>
  </CFG>
  
  <LIST name="eMMC" desc="Choose eMMC as media">
	<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-imx6ul%lite%%bootimx%_emmc.imx" ifdev="MX6UL MX6ULL">Loading U-boot</CMD>
		
	<CMD state="BootStrap" type="load" file="firmware/zImage" address="0x80800000"
		loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6UL MX6ULL">Loading Kernel.</CMD>
	<CMD state="BootStrap" type="load" file="firmware/%initramfs%" address="0x83800000"
		loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6UL MX6ULL">Loading Initramfs.</CMD>
	<CMD state="BootStrap" type="load" file="firmware/zImage-imx6ul%lite%-%bootdtb%-emmc.dtb" address="0x83000000"
		loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6UL MX6ULL">Loading device tree.</CMD>
	<CMD state="BootStrap" type="jump" > Jumping to OS image. </CMD>
	<!-- create partition -->
	<CMD state="Updater" type="push" body="send" file="mksdcard.sh.tar">Sending partition shell</CMD>
	<CMD state="Updater" type="push" body="$ tar xf $FILE "> Partitioning...</CMD>
	<!-- 使用 mksdcard.sh 脚本为设备 "/dev/mmcblk% mmc%" 创建分区 -->
	<CMD state="Updater" type="push" body="$ sh mksdcard.sh /dev/mmcblk%mmc%"> Partitioning...</CMD>
	<!-- burn uboot -->
	<CMD state="Updater" type="push" body="$ while [ ! -e /dev/mmcblk%mmc% ]; do sleep 1; echo \"waiting...\"; done ">Waiting for the partition ready</CMD>
	<!-- 清除 uboot env, 总大小 8*1K,并且跳过了前面 768 blocks, 这里是 User Data Area(UDA) 区域,并不是 Boot Area Patition(boot) 区域 -->
	<CMD state="Updater" type="push" body="$ dd if=/dev/zero of=/dev/mmcblk%mmc% bs=1k seek=768 conv=fsync count=8">clear u-boot arg</CMD>
	<!-- access boot partition -->
	<!-- 使 emmc 的 boot0 分区变为可读写 -->
	<CMD state="Updater" type="push" body="$ echo 0 > /sys/block/mmcblk%mmc%boot0/force_ro">access boot partition 1</CMD>
	<!-- 将 uboot 烧录到 emmc 的 boot0 分区,在系统盘符里分区的序号是从 0 开始,也就是 boot0 -->
	<CMD state="Updater" type="push" body="send" file="files/u-boot-imx6ul%lite%%6uluboot%_emmc%board%.imx" ifdev="MX6UL MX6ULL">Sending u-boot.bin</CMD>
	<CMD state="Updater" type="push" body="$ dd if=$FILE of=/dev/mmcblk%mmc%boot0 bs=512 seek=2">write U-Boot to sd card</CMD>
	<!-- 使 emmc 的 boot0 分区变为只读 -->
	<CMD state="Updater" type="push" body="$ echo 1 > /sys/block/mmcblk%mmc%boot0/force_ro"> re-enable read-only access </CMD>
	<!-- 将 boot0 分区使能,那么启动的时候就会从 emmc 的 boot1 区域启动。
	emmc boot 序号是从 1 开始的,这里的 enable 1 指的是选择 emmc boot 分区的第一个分区进行引导,是针对 emmc 的 PARTITION_CONFIG 寄存器而言的。
	而上面的 /sys/block/mmcblk% mmc% boot0 指是针对 linux 系统而言的,其实指的都是统一个分区,就是 emmc boot 的最开始的分区。 -->
	<CMD state="Updater" type="push" body="$ mmc bootpart enable 1 1 /dev/mmcblk%mmc%">enable boot partion 1 to boot</CMD>
	<!-- create fat partition -->
	<CMD state="Updater" type="push" body="$ while [ ! -e /dev/mmcblk%mmc%p1 ]; do sleep 1; echo \"waiting...\"; done ">Waiting for the partition ready</CMD>
	<!-- 对 /dev/mmcblk% mmc% p1 分区 1 进行格式化 -->
	<CMD state="Updater" type="push" body="$ mkfs.vfat -F 32 /dev/mmcblk%mmc%p1">Formatting rootfs partition</CMD>
	<!-- 挂载 /dev/mmcblk% mmc% p1 分区 1 -->
	<CMD state="Updater" type="push" body="$ mkdir -p /mnt/mmcblk%mmc%p1"/>
	<CMD state="Updater" type="push" body="$ mount -t vfat /dev/mmcblk%mmc%p1 /mnt/mmcblk%mmc%p1"/>
	<!-- burn kernel -->
	<CMD state="Updater" type="push" body="send" file="files/zImage">Sending kernel zImage</CMD>
	<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/zImage">write kernel image to sd card</CMD>
	<!-- burn dtb -->
	<CMD state="Updater" type="push" body="send" file="files/zImage-imx6ul%lite%-%6uldtb%%board%-emmc.dtb" ifdev="MX6UL MX6ULL">Sending Device Tree file</CMD>
	<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/imx6ul%lite%-%6uldtb%%board%.dtb" ifdev="MX6UL MX6ULL">write device tree to sd card</CMD>
	<!-- 取消对 /dev/mmcblk% mmc% p1 分区的挂载 -->
	<CMD state="Updater" type="push" body="$ umount /mnt/mmcblk%mmc%p1">Unmounting fat partition</CMD>
	<!-- create rootfs partition -->
	<CMD state="Updater" type="push" body="$ while [ ! -e /dev/mmcblk%mmc%p2 ]; do sleep 1; echo \"waiting...\"; done ">Waiting for the partition ready</CMD>
	<!-- 对 /dev/mmcblk% mmc% p2 分区 2 进行格式化 -->
	<CMD state="Updater" type="push" body="$ mkfs.ext3 -F -E nodiscard /dev/mmcblk%mmc%p2">Formatting rootfs partition</CMD>
	<!-- 挂载 /dev/mmcblk% mmc% p2 分区 2 -->
	<CMD state="Updater" type="push" body="$ mkdir -p /mnt/mmcblk%mmc%p2"/>
	<CMD state="Updater" type="push" body="$ mount -t ext3 /dev/mmcblk%mmc%p2 /mnt/mmcblk%mmc%p2"/>
	<!-- burn rootfs -->
	<CMD state="Updater" type="push" body="pipe tar -jxv -C /mnt/mmcblk%mmc%p2" file="files/%rootfs%.tar.bz2" ifdev="MX6UL MX6ULL">Sending and writting rootfs</CMD>
	<CMD state="Updater" type="push" body="frf">Finishing rootfs write</CMD>
	<!-- 取消对 /dev/mmcblk% mmc% p2 分区的挂载 -->
	<CMD state="Updater" type="push" body="$ umount /mnt/mmcblk%mmc%p2">Unmounting rootfs partition</CMD>
	<CMD state="Updater" type="push" body="$ echo Update Complete!">Done</CMD>
  </LIST>
  <!-- burn uboot only because spi-nor flash is small (4M). kernel is beyond 5M now -->
  <LIST name="Nor Flash" desc="Choose Nor flash as media">
	<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-imx6ul%lite%%bootimx%_sd.imx" ifdev="MX6UL MX6ULL">Loading U-boot</CMD>
	<CMD state="BootStrap" type="load" file="firmware/zImage" address="0x80800000"
		loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6UL MX6ULL">Loading Kernel.</CMD>
	<CMD state="BootStrap" type="load" file="firmware/%initramfs%" address="0x83800000"
		loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6UL MX6ULL">Loading Initramfs.</CMD>
	<CMD state="BootStrap" type="load" file="firmware/zImage-imx6ul%lite%-%bootdtb%.dtb" address="0x83000000"
		loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6UL MX6ULL">Loading device tree.</CMD>
	<CMD state="BootStrap" type="jump" > Jumping to OS image. </CMD>
	<CMD state="Updater" type="push" body="$ flash_erase /dev/mtd%part_nor% 0 0">Erasing Boot partition</CMD>
	<CMD state="Updater" type="push" body="send" file="files/u-boot-imx6ul%lite%%6uluboot%_%nor%.imx" ifdev="MX6UL MX6ULL">Sending u-boot.bin</CMD>
	<CMD state="Updater" type="push" body="$ dd if=$FILE of=/dev/mtd%part_nor% bs=1k seek=%seek%" ifdev="MX6UL MX6ULL">write U-Boot to NOR flash</CMD>
	<CMD state="Updater" type="push" body="$ echo Update Complete!">Done</CMD>
  </LIST>
  <LIST name="Quad Nor Flash" desc="Choose Quad Nor flash as media">
	<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-imx6ul%lite%%bootimx%_%6ulnor%.imx" ifdev="MX6UL MX6ULL">Loading U-boot</CMD>
	<CMD state="BootStrap" type="load" file="firmware/zImage" address="0x80800000"
		loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6UL MX6ULL">Loading Kernel.</CMD>
	<CMD state="BootStrap" type="load" file="firmware/%initramfs%" address="0x83800000"
		loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6UL MX6ULL">Loading Initramfs.</CMD>
	<CMD state="BootStrap" type="load" file="firmware/zImage-imx6ul%lite%-%bootdtb%.dtb" address="0x83000000"
		loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6UL MX6ULL">Loading device tree.</CMD>
	<CMD state="BootStrap" type="jump" > Jumping to OS image. </CMD>
	<CMD state="Updater" type="push" body="$ flash_erase /dev/mtd0 0 20">Erasing Boot partition</CMD>
	<CMD state="Updater" type="push" body="send" file="files/u-boot-imx6ul%lite%%6uluboot%_%6ulnor%.imx" ifdev="MX6UL MX6ULL">Sending u-boot.bin</CMD>
	<CMD state="Updater" type="push" body="$ dd if=$FILE of=/dev/mtd0 bs=1k seek=4" ifdev="MX6UL MX6ULL">write U-Boot to NOR flash</CMD>
	<!--QSPI header-->
	<CMD state="Updater" type="push" body="send" file="qspi-header.sh.tar">Sending qspi header shell</CMD>
	<CMD state="Updater" type="push" body="$ tar xf $FILE "> Extracting...</CMD>
	<CMD state="Updater" type="push" body="send" file="files/%norconfig%">Sending QSPI header config file</CMD>
	<CMD state="Updater" type="push" body="$ sh qspi-header.sh $FILE"> Generating the ascii value header</CMD>
	<!--hexdump to convert ascii value to hex file-->
	<CMD state="Updater" type="push" body="$ busybox hexdump -R qspi-tmp > qspi-header">Converting ascii value to hex file</CMD>
	<CMD state="Updater" type="push" body="$ dd if=qspi-header of=/dev/mtd0 bs=1k seek=1" ifdev="MX6UL MX6ULL">Writing header to NOR flash</CMD>
	<!--delete temporary files-->
	<CMD state="Updater" type="push" body="$ rm qspi-tmp">Deleting temporary file</CMD>
	<CMD state="Updater" type="push" body="$ rm qspi-header">Deleting temporary file</CMD>
	<CMD state="Updater" type="push" body="$ echo Update Complete!">Done</CMD>
  </LIST>
  <LIST name="NAND Flash" desc="Choose NAND as media">
	<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-imx6ul%lite%%bootimx%_%nand%.imx" ifdev="MX6UL MX6ULL">Loading U-boot</CMD>
	<CMD state="BootStrap" type="load" file="firmware/zImage" address="0x80800000"
		loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6UL MX6ULL">Loading Kernel.</CMD>
	<CMD state="BootStrap" type="load" file="firmware/%initramfs%" address="0x83800000"
				loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6UL MX6ULL">Loading Initramfs.</CMD>
	<CMD state="BootStrap" type="load" file="firmware/zImage-imx6ul%lite%-%bootdtb%-%nanddtb%.dtb" address="0x83000000"
		loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6UL MX6ULL">Loading device tree.</CMD>
	<CMD state="BootStrap" type="jump" > Jumping to OS image. </CMD>
	<!--burn the uboot to NAND: -->	
	<CMD state="Updater" type="push" body="$ mount -t debugfs debugfs /sys/kernel/debug">Mounting debugfs</CMD>
	<CMD state="Updater" type="push" body="$ flash_erase /dev/mtd%part_uboot% 0 0">Erasing Boot partition</CMD>
	<CMD state="Updater" type="push" body="send" file="files/u-boot-imx6ul%lite%%6uluboot%_%nand%.imx" ifdev="MX6UL MX6ULL">Sending u-boot.bin</CMD>
	<CMD state="Updater" type="push" body="$ kobs-ng init -x -v --chip_0_device_path=/dev/mtd%part_uboot% $FILE">Flashing Bootloader</CMD>
	<!--burn the kernel to NAND: -->
	<CMD state="Updater" type="push" body="$ flash_erase /dev/mtd%part_kernel% 0 0">Erasing Kernel partition</CMD>
	<CMD state="Updater" type="push" body="send" file="files/zImage">Sending kernel zImage</CMD>
	<CMD state="Updater" type="push" body="$ nandwrite -p /dev/mtd%part_kernel% -p $FILE">Flashing Kernel</CMD>
	<!--burn the dtb to NAND: -->
	<CMD state="Updater" type="push" body="$ flash_erase /dev/mtd%part_dtb% 0 0">Erasing dtb partition</CMD>
	<CMD state="Updater" type="push" body="send" file="files/zImage-imx6ul%lite%-%6uldtb%-%nanddtb%.dtb" ifdev="MX6UL MX6ULL">Sending Device Tree file</CMD>
	<CMD state="Updater" type="push" body="$ nandwrite -p /dev/mtd%part_dtb% -p $FILE">Flashing dtb</CMD>
	<!--burn the rootfs to NAND: -->
	<CMD state="Updater" type="push" body="$ flash_erase /dev/mtd%part_rootfs% 0 0">Erasing rootfs partition</CMD>
	<CMD state="Updater" type="push" body="$ ubiformat /dev/mtd%part_rootfs%"/>
	<CMD state="Updater" type="push" body="$ ubiattach /dev/ubi_ctrl -m %part_rootfs%">Attaching UBI partition</CMD>
	<CMD state="Updater" type="push" body="$ ubimkvol /dev/ubi0 -Nrootfs -m"/>
	<CMD state="Updater" type="push" body="$ mkdir -p /mnt/mtd%part_rootfs%"/>
	<CMD state="Updater" type="push" body="$ mount -t ubifs ubi0:rootfs /mnt/mtd%part_rootfs%"/>
	<CMD state="Updater" type="push" body="pipe tar -jxv -C /mnt/mtd%part_rootfs%" file="files/%rootfs%.tar.bz2" ifdev="MX6UL MX6ULL">Sending and writting rootfs</CMD>
	<CMD state="Updater" type="push" body="frf">Finishing rootfs write</CMD>
	<CMD state="Updater" type="push" body="$ umount /mnt/mtd%part_rootfs%">Unmounting rootfs partition</CMD>
	<CMD state="Updater" type="push" body="$ echo Update Complete!">Done</CMD>
  </LIST>
</UCL>

这是一个 xml 文件,所以遵循 xml 语法,根元素 <UCL> <UCL/> ,它表示更新命令列表(Update Command List,UCL);标签 <CFG> </CFG> ,元素中包含可识别 usb 设备的列表;标签 <LIST> </LIST> ,元素 name 用于匹配 cfg.ini 文件中的 LIST/name 参数或脚本输入参数,元素 desc 用于描述说明;标签 <CMD> </CMD> 嵌套于 <LIST> </LIST> 下,属于命令标签,在不同的阶段下命令是不一样的(大致分为两个阶段 BootStrap 和 Updater),mfgtool 工具的命令分为主机特定命令(Host Specific Commands)与固件特定命令(Firmware Specific Commands),其中主机特定命令是由 mfgtool 工具解析和执行,而固件特定命令由目标设备上的固件运行解析和执行。

note:拓展一下,关于 mmc bootpart enable 1 1 <device> 命令,是用于修改 emmc 启动使能位 BOOT_PARTITION_ENABLE

img

关于该命令的解释:

mmc bootpart enable <boot_partition> <send_ack> <device>
    Enable the boot partition for the <device>.
    Disable the boot partition for the <device> if <boot_partition> is set to 0.
    To receive acknowledgment of boot from the card set <send_ack>
    to 1, else set it to 0

即第一个数值用于选定所引导的分区,第二个数值是决定是否要接收来自卡的引导确认。

# 分区处理

# mksdcard.sh.tar

该文件主要是用于烧录前对存储介质进行分区,在 ucl2.xml 上可以找到如下操作:

<!-- create partition -->
	<CMD state="Updater" type="push" body="send" file="mksdcard.sh.tar">Sending partition shell</CMD>
	<CMD state="Updater" type="push" body="$ tar xf $FILE "> Partitioning...</CMD>
	<CMD state="Updater" type="push" body="$ sh mksdcard.sh /dev/mmcblk%mmc%"> Partitioning...</CMD>

从上面可以看到它的处理流程:

  1. 先发送该文件到 RAM 运行中;
  2. 解压该文件;
  3. 利用 shell 命令执行解压出来的文件。

然后我们打开压缩包,查看里面的 shell 脚本:

#!/bin/sh
# partition size in MB
BOOT_ROM_SIZE=10
# wait for the SD/MMC device node ready
while [ ! -e $1 ]
do
sleep 1
echo “wait for $1 appear”
done
# call sfdisk to create partition table
# destroy the partition table
node=$1
dd if=/dev/zero of=${node} bs=1024 count=1
sfdisk --force ${node} << EOF
${BOOT_ROM_SIZE}M,120M,0c
200M,,83
EOF

接着根据里面的分段,把它分为 4 个处理分析:

BOOT_ROM_SIZE=10
# note:这里定义的是启动 ROM 10MB,给后面引用。
l
while [ ! -e $1 ]
do
sleep 1
echo “wait for $1 appear”
done
# note:$1 - 为命令行第一个传递的参数,结合 "$ sh mksdcard.sh/dev/mmcblk% mmc%",所以 $1 实际为 /dev/mmcblk% mmc% 。
node=$1
dd if=/dev/zero of=${node} bs=1024 count=1
# note:将 /dev/mmcblk% mmc% 分区的前导 1024 (1KB) 字节大小设 0,也就是擦除。
sfdisk --force ${node} << EOF
${BOOT_ROM_SIZE}M,120M,0c
200M,,83
EOF
# note:利用 sfdisk 对 /dev/mmcblk% mmc% 进行分区,共划分为两部分:从起始地址 10MB 开始至 120M 为一个分区,文件类型为 0c(W95 FAT32 (LBA));从地址 200MB 以后为一个分区,文件类型为 83(Linux)。关于对应的文件类型码,可以使用 "sfdisk -T" 查看。

这里的分区信息,可以在 uboot 引导中,使用 mmc part 命令查看分区信息(更多具体 uboot 启动信息可看 uboot 引导启动分析 ),例如以上的分区操作,可以得到:

=> mmc part
Partition Map for MMC device 1  --   Partition Type: DOS
Part    Start Sector    Num Sectors     UUID            Type
  1     20480           245760          00000000-01     0c
  2     409600          14860288        00000000-02     83
=> ls mmc 1:1
  6577568   zImage
    36093   imx6ull-14x14-lanjut.dtb
=> ls mmc 1:2
<DIR>       4096 .
<DIR>       4096 ..
<DIR>      16384 lost+found
<DIR>       4096 bin
<DIR>       4096 dev
<DIR>       4096 etc
<DIR>       4096 home
<DIR>       4096 lib
<DIR>       4096 media
<DIR>       4096 mnt
<DIR>       4096 proc
<DIR>       4096 run
<DIR>       4096 sbin
<DIR>       4096 sys
<SYM>          8 tmp
<DIR>       4096 usr
<DIR>       4096 var
=> mmc info
Device: FSL_SDHC
Manufacturer ID: 15
OEM: 100
Name: 8GTF4 
Bus Speed: 52000000
Mode: MMC High Speed (52MHz)
Rd Block Len: 512
MMC version 5.1
High Capacity: Yes
Capacity: 7.3 GiB
Bus Width: 8-bit
Erase Group Size: 512 KiB
HC WP Group Size: 8 MiB
User Capacity: 7.3 GiB WRREL
Boot Capacity: 4 MiB ENH
RPMB Capacity: 512 KiB ENH

可以看到 emmc 有 2 个分区

分区 1 是扇区:20480 ~ 245760 => 第 1 个分区存放 Linux 镜像文件和设备树,容量为 245760*512/1024/1025 = 120MB ,从 20480*512/1024/1025 = 10MB 开始。

分区 2 是扇区:409600 ~ 14860288 => 第 2 个分区存放根文件系统容量为 14860288*512/1024/1025 = 7256MB ,从 409600*512/1024/1025 = 200MB 开始。

因此总大小为:10MB(预留) + 120MB + 80MB(分割预留) + 7256MB = 7466 MB = 7.291015625 GB,而在这里实际使用的是 8G emmc 内存,所以除去 BOOT、RPMB 和 GPP(如果厂商设有 GPP)的分区,实际 UDA 分区的容量跟现在算出的差不多,具体以 datasheet 为准。

分区示例

# 烧录文件

mfgtool 文件目录下的文件夹和文件非常多,除了上面的配置文件外,还有烧录脚本文件(.vbs)和烧录所需文件(uboot、kernel、dtb、rootfs)

# 烧录脚本文件

在 win 平台下,目录下的 MfgTool2.exe 就是烧写工具,以 .vbs 结尾的文件就是烧写的配置文件;而在 Linux 平台下, mfgtoolcli 是该平台的烧写工具,可以通过执行 linux-cvbs.sh 脚本转换 .vbs 文件为 Linux 平台下的脚本。

该烧写工具能支持多款 i.MX 系统的 SoC 系统烧写,还能支持 Nand Flash、eMMC 和 SD 卡等存储介质的烧写;因此,在对每一款 SoC 进行系统烧写之前,需要进行配置并指定好需要烧写的芯片以及存储介质等,然后通过执行相应的脚本文件运行;一般常用的脚本有如下几个:

脚本文件名描述
mfgtool2-yocto-mx-evk-emmcEMMC 烧写脚本
mfgtool2-yocto-mx-evk-nandNand 烧写脚本
mfgtool2-yocto-mx-evk-qspi-nor-n25q256aQSPI Flash 烧写脚本,型号为 n25q256a

关于烧写脚本命令参数,其烧写工具命令行的格式如下:

MfgTool2.exe [-c] [chip profile folder name] [-l] [list name] [-p] [number] [-s] [variable=value]

一般我们只用到:

  • -c:指定目标配置文件的名称。如果不指定则读取 cfg.iniprofiles/chip 的值。
  • -l:指示目标操作列表名称。如果不指定则读取 cfg.iniLIST/name 的值。
  • -p:表示同时支持的单板数量。如果不指定则读取 UICfg.iniUICfg/PortMgrDlg 的值。
  • -s:设置 ucl2.xml 中的变量值;支持多变量配置。如果不指定则读取 cfg.ini 中所需的 variable 引用变量值。

更多格式可看目录下的 ~\Document\V2\Manufacturing Tool V2 Quick Start Guide.docx 文档。

例如,自定义一个烧录脚本:

Set wshShell = CreateObject("WScript.shell")
wshShell.run "mfgtool2.exe -c ""linux"" -l ""eMMC"" -s ""board=-lanjut"" -s ""mmc=1"" -s ""6uluboot=14x14"" -s ""6uldtb=14x14"""
Set wshShell = Nothing

note:

可能会想,为什么没有列出 SD Card 烧写脚本,是因为用 SD Card 作烧写,用命令操作会好一点。

# 烧录所需文件

前面说到,在执行 ucl2.xml 的一系列操作中,存在两个阶段:

  • 第一阶段(把系统烧写到 DRAM 中,然后 Jumping to OS image,以此为运行平台)

    其所需的文件有:(以 ucl2.xmleMMC 标签为例)

    运行固件下载文件
    ubootfirmware/u-boot-imx6ul%lite%%bootimx%_emmc.imx
    kernelfirmware/zImage
    initramfsfirmware/%initramfs%
    dtbfirmware/zImage-imx6ul%lite%-%bootdtb%-emmc.dtb

    结合上面图表中可以看出来,存放第一阶段所需的固件路径是 profiles/CHIP_PROFILE/OS Firmware/firmwareCHIP_PROFILE 是由 cfg.ini 中的 profiles/chip 参数或 mfgtool2-yocto-mx-evk-emmc 脚本里 -c 所带参数决定,不区分大小写;对应的文件也依据 ucl2.xmlBootStrap 状态下的 file 元素定义的文件名为基准。

    tips:一般这里是不需要改动了,因为只是为了引导实际烧写而提供一个运行平台而已。

  • 第二阶段(通过从 DRAM 中启动的运行平台将目标镜像固化到存储介质中)

    其所需的文件有:(以 ucl2.xmleMMC 标签为例)

    目标固件下载文件
    ubootfiles/u-boot-imx6ul%lite%%6uluboot%_emmc.imx
    kernelfiles/zImage
    dtbfiles/zImage-imx6ul%lite%-%6uldtb%-emmc.dtb
    rootfsfiles/%rootfs%.tar.bz2

    同样的,在第二阶段存放所需的固件路径是 profiles/CHIP_PROFILE/OS Firmware/files ,对应的文件则依据 ucl2.xmlUpdater 状态下的 file 元素定义的文件名为基准。

总结一下烧录流程:

第一步:烧录 profiles/CHIP_PROFILE/OS Firmware/firmware 路径下的 uboot、kernel、initramfs、dtb 到 DRAM 中;然后执行 Jumping to OS image,这时候在已运行的系统中去执行第二个步骤。

第二步:通过从 DRAM 中已经启动的系统上,将 profiles/CHIP_PROFILE/OS Firmware/files 路径下的目标固件 uboot、kernel、dtb、rootfs 烧写到存储介质中上,如 eMMC、Nand 等。因此在实际使用中,当需要更新系统或设备树时,真正需要更改的是这几个文件。

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

夏沫の浅雨 微信支付

微信支付

夏沫の浅雨 支付宝

支付宝