目录
1、概述
本文章中分析的uxl2.xml来自于NXP的官方例程。
2、分析
2.1 cfg.ini
cfg.ini的内容比较简单,略过。
2.2 ucl2.xml
由于现在单板上使用的大多为emmc,因此本文只分析emmc相关的operation list。
a) global configuration
global configuration相关的<CFG>...</CFG>部分的内容也比较简单,略过。
b) operation list
<LIST name="eMMC" desc="Choose eMMC as media">
# command分为host command和firmware command。其中在BootStrap阶段执行的是host command,在Updater阶段执行的firmware command。
# host command由HCE(Host Command Engine)解析和执行;firmware command则由DCE(Device Command Engine)解析和执行,host只是把命令发送给device。
# host command主要有boot, load和jump三个。 firmware command则比较多。
<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-imx6q%plus%%board%_sd.imx" ifdev="MX6Q">Loading U-boot</CMD>
<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-imx6dl%board%_sd.imx" ifdev="MX6D">Loading U-boot</CMD>
<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-imx6sx%board%_emmc.imx" ifdev="MX6SX">Loading U-boot</CMD>
<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-imx7d%7duboot%_sd.imx" ifdev="MX7D">Loading U-boot</CMD>
<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-imx6ul%6uluboot%_emmc.imx" ifdev="MX6UL">Loading U-boot</CMD>
<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-imx6ul%lite%%6uluboot%_emmc.imx" ifdev="MX6ULL">Loading U-boot</CMD>
# 上面的6个cmd entry是在BoorStrap阶段,根据设备类型下载临时的uboot到ram中,注意boot命令是没有address参数的。
<CMD state="BootStrap" type="load" file="firmware/zImage" address="0x12000000"
loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6Q MX6D">Loading Kernel.</CMD>
<CMD state="BootStrap" type="load" file="firmware/zImage" address="0x80800000"
loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6SL MX6SX MX7D MX6UL MX6ULL">Loading Kernel.</CMD>
# 上面的2个cmd entry是在BoorStrap阶段,根据设备类型下载临时的zImage到ram中,不同的设备,下载的ram地址也不同。
<CMD state="BootStrap" type="load" file="firmware/%initramfs%" address="0x12C00000"
loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6Q MX6D">Loading Initramfs.</CMD>
<CMD state="BootStrap" type="load" file="firmware/%initramfs%" address="0x83800000"
loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6SL MX6SX MX7D MX6UL MX6ULL">Loading Initramfs.</CMD>
# 上面的2个cmd entry是在BoorStrap阶段,根据设备类型下载临时的rootfs到ram中,不同的设备,下载的ram地址也不同。
<CMD state="BootStrap" type="load" file="firmware/zImage-imx6q%plus%-%board%%ldo%.dtb" address="0x18000000"
loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6Q">Loading device tree.</CMD>
<CMD state="BootStrap" type="load" file="firmware/zImage-imx6dl-%board%%ldo%.dtb" address="0x18000000"
loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6D">Loading device tree.</CMD>
<CMD state="BootStrap" type="load" file="firmware/zImage-imx6sx-%sxdtb%-emmc.dtb" address="0x83000000"
loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6SX">Loading device tree.</CMD>
<CMD state="BootStrap" type="load" file="firmware/zImage-imx7d-%7ddtb%.dtb" address="0x83000000"
loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX7D">Loading device tree.</CMD>
<CMD state="BootStrap" type="load" file="firmware/zImage-imx6ul-%6uldtb%-emmc.dtb" address="0x83000000"
loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6UL">Loading device tree.</CMD>
<CMD state="BootStrap" type="load" file="firmware/zImage-imx6ul%lite%-%6uldtb%-emmc.dtb" address="0x83000000"
loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6ULL">Loading device tree.</CMD>
# 上面的6个cmd entry是在BoorStrap阶段,根据设备类型下载临时的设备数文件到ram中,不同的设备,下载的ram地址也不同。
<CMD state="BootStrap" type="jump" > Jumping to OS image. </CMD>
# 上面的cmd entry用于启动image,BootStrap阶段到此结束,临时的kernel和rootf已经运行起来了,下面开始Updater阶段,烧写正式的文件。
<!-- 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>
# 上面的3个用于下载mksdcard.sh.tar并解压,然后运行mksdcard.sh文件对emmc进行分区。%mmc%变量的值再cfg.ini中配置,mksdcard.sh的内容另外分析。
<!-- burn uboot -->
<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>
# 上面的cmd entry用于清空uboot args的区域。bs=1k表示输入和输出的block size为1k bytes;seek=768则表示输出端,即跳过emmc开始的768个block,每个block的大小由bs设定
# count=8,则表示需要处理的block数量为8个。
<!-- access boot partition -->
<CMD state="Updater" type="push" body="$ echo 0 > /sys/block/mmcblk%mmc%boot0/force_ro">access boot partition 1</CMD>
# 使能emmc的boot0区域的写功能,emmc的boot0和boot1默认是read only的。
<CMD state="Updater" type="push" body="send" file="files/u-boot-imx6q%plus%%board%_sd.imx" ifdev="MX6Q">Sending u-boot.bin</CMD>
<CMD state="Updater" type="push" body="send" file="files/u-boot-imx6dl%board%_sd.imx" ifdev="MX6D">Sending u-boot.bin</CMD>
<CMD state="Updater" type="push" body="send" file="files/u-boot-imx6sx%board%_emmc.imx" ifdev="MX6SX">Sending u-boot.bin</CMD>
<CMD state="Updater" type="push" body="send" file="files/u-boot-imx7d%7duboot%_sd.imx" ifdev="MX7D">Sending u-boot.bin</CMD>
<CMD state="Updater" type="push" body="send" file="files/u-boot-imx6ul%6uluboot%_emmc.imx" ifdev="MX6UL">Sending u-boot.bin</CMD>
<CMD state="Updater" type="push" body="send" file="files/u-boot-imx6ul%lite%%6uluboot%_emmc.imx" ifdev="MX6ULL">Sending u-boot.bin</CMD>
# 上面的6个cmd entry则是根据device类型下载正式的uboot到ddr中。
<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>
# 将下载的uboot写入到emmc的boot0区域,写入是block size=512,seek2表示跳过emmc的boot0起始的1k区域。
<CMD state="Updater" type="push" body="$ echo 1 > /sys/block/mmcblk%mmc%boot0/force_ro"> re-enable read-only access </CMD>
# 关闭emmc的boot0区域的写功能。
<CMD state="Updater" type="push" body="$ mmc bootpart enable 1 1 /dev/mmcblk%mmc%">enable boot partion 1 to boot</CMD>
# 使能emmc的boot分区的boot功能,boot分区的boot功能默认是关闭的。
<!-- 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>
# 等待emmc的p1分区就绪,为后面挂在文件系统做准备。
<CMD state="Updater" type="push" body="$ mkfs.vfat /dev/mmcblk%mmc%p1">Formatting rootfs partition</CMD>
# 将emmc的p1分区格式化为fat文件系统。
<CMD state="Updater" type="push" body="$ mkdir -p /mnt/mmcblk%mmc%p1"/>
# 在临时的rootfs的/mnt下创建mmcblk%mmc%p1目录。
<CMD state="Updater" type="push" body="$ mount -t vfat /dev/mmcblk%mmc%p1 /mnt/mmcblk%mmc%p1"/>
# 将emmc的p1分区挂到临时rootfs的/mnt目录下,为烧写内核和设备数文件做准备。
<!-- burn zImage -->
<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>
# 下载内核文件并写入刚刚创建的fat文件系统中。
<!-- burn dtb -->
<CMD state="Updater" type="push" body="send" file="files/zImage-imx6q%plus%-%board%%ldo%.dtb" ifdev="MX6Q">Sending Device Tree file</CMD>
<CMD state="Updater" type="push" body="send" file="files/zImage-imx6dl-%board%%ldo%.dtb" ifdev="MX6D">Sending Device Tree file</CMD>
<CMD state="Updater" type="push" body="send" file="files/zImage-imx6sx-%sxdtb%-emmc.dtb" ifdev="MX6SX">Sending Device Tree file</CMD>
<CMD state="Updater" type="push" body="send" file="files/zImage-imx7d-%7ddtb%.dtb" ifdev="MX7D">Sending Device Tree file</CMD>
<CMD state="Updater" type="push" body="send" file="files/zImage-imx6ul-%6uldtb%-emmc.dtb" ifdev="MX6UL">Sending Device Tree file</CMD>
<CMD state="Updater" type="push" body="send" file="files/zImage-imx6ul%lite%-%6uldtb%-emmc.dtb" ifdev="MX6ULL">Sending Device Tree file</CMD>
# 根据device类型下载设备数文件。
<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/imx6q%plus%-%board%.dtb" ifdev="MX6Q">write device tree to sd card</CMD>
<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/imx6dl-%board%.dtb" ifdev="MX6D">write device tree to sd card</CMD>
<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/imx6sx-%sxdtb%.dtb" ifdev="MX6SX">write device tree to sd card</CMD>
<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/imx7d-%7ddtb%.dtb" ifdev="MX7D">write device tree to sd card</CMD>
<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/imx6ul-%6uldtb%.dtb" ifdev="MX6UL">write device tree to sd card</CMD>
<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/imx6ul%lite%-%6uldtb%.dtb" ifdev="MX6ULL">write device tree to sd card</CMD>
# 根据device类型将刚刚下载的设备数文件写入到文件系统中。
<!-- burn m4 demo bins-->
<CMD state="Updater" type="push" body="send" file="files/imx7d_sabresd_m4_TCM_helloworld.bin" ifdev="MX7D">Sending helloworld demo</CMD>
<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/imx7d_sabresd_m4_TCM_helloworld.bin" ifdev="MX7D">write demo image to eMMC</CMD>
<CMD state="Updater" type="push" body="send" file="files/imx7d_sabresd_m4_TCM_mcctty.bin" ifdev="MX7D">Sending mcctty demo</CMD>
<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/imx7d_sabresd_m4_TCM_mcctty.bin" ifdev="MX7D">write demo image to eMMC</CMD>
<CMD state="Updater" type="push" body="send" file="files/imx7d_sabresd_m4_TCM_Pingpang.bin" ifdev="MX7D">Sending pingpong demo</CMD>
<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/imx7d_sabresd_m4_TCM_Pingpang.bin" ifdev="MX7D">write demo image to eMMC</CMD>
# 根据device类型下载demo并写入到fat文件系统中。
<CMD state="Updater" type="push" body="$ umount /mnt/mmcblk%mmc%p1">Unmounting vfat partition</CMD>
# 卸载emmc的p1分区的fat文件系统。
<!-- burn rootfs -->
<CMD state="Updater" type="push" body="$ mkfs.ext3 -F -E nodiscard /dev/mmcblk%mmc%p2">Formatting rootfs partition</CMD>
# 在emmc的p2分区上创建ext3文件系统。
<CMD state="Updater" type="push" body="$ mkdir -p /mnt/mmcblk%mmc%p2"/>
# 在临时的rootfs的/mnt路径下创建mmcblk%mmc%p2目录。
<CMD state="Updater" type="push" body="$ mount -t ext3 /dev/mmcblk%mmc%p2 /mnt/mmcblk%mmc%p2"/>
# 将emmc的p2分区的ext3文件系统挂载刚才创建的mmcblk%mmc%p1目录下。
<CMD state="Updater" type="push" body="pipe tar -jxv -C /mnt/mmcblk%mmc%p2" file="files/rootfs.tar.bz2" ifdev="MX6SL MX6D MX6Q MX6SX">Sending and writting rootfs</CMD>
<CMD state="Updater" type="push" body="pipe tar -jxv -C /mnt/mmcblk%mmc%p2" file="files/rootfs_nogpu.tar.bz2" ifdev="MX6UL MX7D MX6ULL">Sending and writting rootfs</CMD>
# 根据device下载正式的rootfs,并写入到emmc的p2分区上。
<CMD state="Updater" type="push" body="frf">Finishing rootfs write</CMD>
# 等待rootfs写入完成。
<CMD state="Updater" type="push" body="$ umount /mnt/mmcblk%mmc%p2">Unmounting rootfs partition</CMD>
# 卸载emmc的p2分区上的ext3文件系统。
<CMD state="Updater" type="push" body="$ echo Update Complete!">Done</CMD>
# 烧写完成
</LIST>
2.3 sdcard.sh
#!/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
# 等待emmc的分区就绪
# call sfdisk to create partition table
# destroy the partition table
node=$1
dd if=/dev/zero of=${node} bs=1024 count=1
# 清空emmc分区的起始1k区域,该区域存放的是分区表
sfdisk --force ${node} << EOF
${BOOT_ROM_SIZE}M,500M,0c
600M,,83
EOF
# 通过sfdisk命令,把10M~500M的区域划分为fat32分区,从600M到结束的区域划分为linux分区