这里以基于 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
目前预留,未使用,请忽略。variable
为ucl2.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
:
关于该命令的解释:
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> |
从上面可以看到它的处理流程:
- 先发送该文件到 RAM 运行中;
- 解压该文件;
- 利用 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,给后面引用。 |
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-emmc | EMMC 烧写脚本 |
mfgtool2-yocto-mx-evk-nand | Nand 烧写脚本 |
mfgtool2-yocto-mx-evk-qspi-nor-n25q256a | QSPI Flash 烧写脚本,型号为 n25q256a |
关于烧写脚本命令参数,其烧写工具命令行的格式如下:
MfgTool2.exe [-c] [chip profile folder name] [-l] [list name] [-p] [number] [-s] [variable=value]
一般我们只用到:
- -c:指定目标配置文件的名称。如果不指定则读取
cfg.ini
中profiles/chip
的值。 - -l:指示目标操作列表名称。如果不指定则读取
cfg.ini
中LIST/name
的值。 - -p:表示同时支持的单板数量。如果不指定则读取
UICfg.ini
中UICfg/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.xml
中eMMC
标签为例)运行固件 下载文件 uboot firmware/u-boot-imx6ul%lite%%bootimx%_emmc.imx kernel firmware/zImage initramfs firmware/%initramfs% dtb firmware/zImage-imx6ul%lite%-%bootdtb%-emmc.dtb 结合上面图表中可以看出来,存放第一阶段所需的固件路径是
profiles/CHIP_PROFILE/OS Firmware/firmware
,CHIP_PROFILE
是由cfg.ini
中的profiles/chip
参数或mfgtool2-yocto-mx-evk-emmc
脚本里-c
所带参数决定,不区分大小写;对应的文件也依据ucl2.xml
中BootStrap
状态下的file
元素定义的文件名为基准。tips:一般这里是不需要改动了,因为只是为了引导实际烧写而提供一个运行平台而已。
第二阶段(通过从 DRAM 中启动的运行平台将目标镜像固化到存储介质中)
其所需的文件有:(以
ucl2.xml
中eMMC
标签为例)目标固件 下载文件 uboot files/u-boot-imx6ul%lite%%6uluboot%_emmc.imx kernel files/zImage dtb files/zImage-imx6ul%lite%-%6uldtb%-emmc.dtb rootfs files/%rootfs%.tar.bz2 同样的,在第二阶段存放所需的固件路径是
profiles/CHIP_PROFILE/OS Firmware/files
,对应的文件则依据ucl2.xml
中Updater
状态下的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 等。因此在实际使用中,当需要更新系统或设备树时,真正需要更改的是这几个文件。