加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
    • MfgTools工具目录
    • MfgTool工具工作过程
    • ucl2.xml文件讲解
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

飞凌嵌入式ElfBoard ELF 1板卡-mfgtools烧录流程之烧写原理

12/21 09:10
187
阅读需 35 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

MfgTools工具目录

MfgTool工具是一个NXP提供的OTG烧录工具,工具主目录主要由以下文件组成:

Profiles/目录:

(一)ProfilesLinuxOS Firmwarefiles中,存储着将要烧写到存储介质(启动介质)的目标镜像(uboot、内核、文件系统、设备树等)

(二)ProfilesLinuxOS Firmwarefirmware中,存储着引导烧写的镜像(uboot、内核、ramfs文件系统、设备树)

(三)ProfilesLinuxOS Firmware中,存储着ucl2.xml脚本和mksdcard.sh.tar分区脚本。

mx6ull-4gemmc-512mddr-qt5.6.vbs主要用于启动MfgTool2.exe程序,并向其传递配置参数,MfgTool2.exe程序会根据这些参数执行ProfilesLinuxOS Firmwareucl2.xml中的命令。

MfgTool工具工作过程

MfgTool工具工作过程主要分以下几个步骤:

(一)拨码无误,开发板上电之后,首先boot ROM(SOC内部code,boot ROM具体作用在以后章节会进一步讲解)开始运行,对USB外设进行初始化,并将开发板枚举成HID设备。

(二)Mfgtool工具检测到此HID设备,并与之建立连接。然后Mfgtool工具会解析Firmware目录下uboot,并使用uboot中的内存配置信息对开发板DDR进行初始化配置。

(三)DDR内存初始化完成之后,Mfgtool工具就会按照mfgtoolsProfilesLinuxOS Firmwareucl2.xml脚本中的命令将mfgtoolsProfilesLinuxOS Firmwarefirmware目录下uboot镜像、内核镜像、设备树以及ramfs加载到DDR内存中指定地址,然后发送指令给boot ROM,跳转到DDR内存的uboot入口地址,执行uboot,uboot进而启动内核,内核挂载ramfs文件系统。

(四)系统启动之后,会枚举USB作为一个MSC设备,此时SoC可以和主机进行高速数据传输

(五)然后,Mfgtool会逐一执行mfgtoolsProfilesLinuxOS Firmwareucl2.xml脚本中的命令,将mfgtoolsProfilesLinuxOS Firmwarefiles目录下的uboot、内核镜像、设备树文件、文件系统等逐一烧写到存储介质(启动介质)中。

ucl2.xml文件讲解

xml文件中会根据不同的板卡类型,选择不同的LIST,主要讲解EMMC版本的烧录流程:

(一)将引导镜像加载到DDR

在文件中查找<LIST name="eMMC" desc="Choose eMMC as media">

<LIST name="eMMC" desc="Choose eMMC as media">

<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-imx6ul%lite%%6uluboot%_emmc.imx" ifdev="MX6ULL">Loading U-boot</CMD>

<CMD state="BootStrap" type="load" file="firmware/zImage_emmc" address="0x80800000"

loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6SL MX6SX MX7D MX6UL MX6ULL">Loading Kernel.</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>

<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>

<CMD state="BootStrap" type="jump" > Jumping to OS image. </CMD>

可以看到先是加载了ProfilesLinuxOS Firmwarefirmware目录下的u-boot-imx6ul%lite%%6uluboot%_emmc.imx也就是固件下的u-boot-imx6ull14x14evk_emmc.imx文件。

这两个名称是如何定义的呢?在mfgtoos的根目录下的mx6ull-4gemmc-512mddr-qt5.6.vbs和cfg.ini文件中有相关定义,可以右键使用文本格式打开这两个文件进行查看。

cfg.ini文件如下:

[profiles]

chip = Linux




[platform]

board = SabreSD




[LIST]

name = SDCard




[variable]

board = sabresd

mmc = 0

sxuboot=sabresd

sxdtb=sdb

7duboot=sabresd

7ddtb=sdb

6uluboot=14x14ddr3arm2

6uldtb=14x14-ddr3-arm2

6ulldtb=14x14-ddr3-arm2

ldo=

plus=

lite=l

initramfs=fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot

seek = 1

sxnor=qspi2

7dnor=qspi1

6ulnor=qspi1

nor_part=0

可以看到,lite=l,6uluboot=14x14ddr3arm2,lite的定义没问题是l,但是6uluboot的定义也不是14x14evk呀,别着急看下一个文件。

mx6ull-8gemmc-512mddr-qt5.6.vbs:

Set wshShell = CreateObject("WScript.shell")

wshShell.run "mfgtool2.exe -c ""linux"" -l ""eMMC"" -s ""board=sabresd"" -s ""mmc=1"" -s ""6uluboot=14x14evk"" -s ""6uldtb=14x14-evk"""

Set wshShell = Nothing

能看到这里又重新定义了6uluboot的名称,在ucl2.xml文件中使用%lite%和%6uluboot%来引用这两个变量。所以u-boot-imx6ul%lite%%6uluboot%_emmc.imx就是u-boot-imx6ull14x14evk_emmc.imx文件。

这样芯片就会自动解析uboot然后对DDR进行初始化,引导固件中的uboot就开始运行了。

接下来就是将ProfilesLinuxOS Firmwarefirmware目录下的zImage_emmc加载到DDR的“0x80800000”地址,命令如下:

<CMD state="BootStrap" type="load" file="firmware/zImage_emmc" address="0x80800000"

loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6SL MX6SX MX7D MX6UL MX6ULL">Loading Kernel.</CMD>

然后是加载虚拟文件系统,将ProfilesLinuxOS Firmwarefirmware目录下的fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot加载到DDR的“0x83800000”,%initramfs%的定义在上文的cfg.ini文件中可以找到。这个虚拟文件系统又叫rmadisk,是将内存的一块地址虚拟成硬盘来使用,断电后是不会保存的。

<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>

然后加载设备树文件,将ProfilesLinuxOS Firmwarefirmware目录下的zImage-imx6ull-14x14-evk-emmc.dtb加载到DDR的“0x83000000”,最后jump命令跳转到虚拟文件系统中。

<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>

<CMD state="BootStrap" type="jump" > Jumping to OS image. </CMD>

(二)EMMC分区,进入到虚拟文件系统后就可以对EMMC进行分区了。

先是将ProfilesLinuxOS Firmware下的mksdcard.sh.tar包发送到了虚拟文件系统中。

<!-- create partition -->

<CMD state="Updater" type="push" body="send" file="mksdcard.sh.tar">Sending partition shell</CMD>

然后使用tar命令将压缩包解压:

<CMD state="Updater" type="push" body="$ tar xf $FILE "> Partitioning...</CMD>

最后执行mksdcard.sh对mmcblk1进行格式化和分区操作。%mmc%在上文中的mx6ull-8gemmc-512mddr-qt5.6.vbs文件中有定义。

<CMD state="Updater" type="push" body="$ sh mksdcard.sh /dev/mmcblk%mmc%"> Partitioning...</CMD>

接下来看一下mksdcard.sh中是如何进行格式化和分区的,在windows上解压mksdcard.sh.tar并打开mksdcard.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




# 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,500M,0c

600M,,83

EOF

先是循环检测虚拟文件系统中/dev/mmcblk1节点是否注册成功,$1就是传进来的第一个参数/dev/mmcblk1。

# wait for the SD/MMC device node ready

while [ ! -e $1 ]

do

sleep 1

echo “wait for $1 appear”

done

如果识别到了mmcblk1设备,就使用dd命令将EMMC的前1KB的空间清0,EMMC的前1KB空间保存的是它的分区表信息,所以在正常使用情况下千万不能执行如下操作。

# call sfdisk to create partition table

# destroy the partition table

node=$1

dd if=/dev/zero of=${node} bs=1024 count=1

接下来就是使用sfdisk命令对EMMC进行分区操作。

sfdisk --force ${node} << EOF

${BOOT_ROM_SIZE}M,500M,0c

600M,,83

EOF

0c为fat32格式,83为ext3格式,其中10-500M为fat32格式,使用来存储镜像的分区。600M之后的空间都为ext3格式的分区,是给文件系统来用的。在开发板的命令行执行df -h命令即可看到这些分区,如下:

root@ELF1:~# df -h

Filesystem      Size     Used    Avail   Use%  Mounted on

/dev/root        6.5G    746M    5.5G   12%    /

devtmpfs        89M     4.0K    89M    1%     /dev

tmpfs           40K      0       40K    0%     /mnt/ .psplash

tmpfs            249M   140K  249M   1%   /run

tmpfs            249M   140K  249M   1%   /var/volatile

/dev/mmcblk1p1  500M   12M   488M   3%   /run/media/mmcblk1p1

(三)格式化和烧录

uboot分区格式化和烧录,先是清除了mmcblk1偏移量768之后的8k字节,此位置存放的是uboot的环境变量。

<!-- 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>

然后使能mmcblk1boot0的写操作,将ProfilesLinuxOS Firmwarefiles目录下的u-boot.imx烧写到mmcblk1boot0分区。

<!-- access boot partition -->

<CMD state="Updater" type="push" body="$ echo 0 > /sys/block/mmcblk%mmc%boot0/force_ro">access boot partition 1</CMD>

<CMD state="Updater" type="push" body="send" file="files/ u-boot.imx" ifdev="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>

<CMD state="Updater" type="push" body="$ echo 1 > /sys/block/mmcblk%mmc%boot0/force_ro"> re-enable read-only access </CMD>

<CMD state="Updater" type="push" body="$ mmc bootpart enable 1 1 /dev/mmcblk%mmc%">enable boot partion 1 to boot</CMD>

接下来是格式化FAT32分区,并烧写zImage、logo图片和dtb文件,同样的先是检测/dev下有没有mmcblk1p1节点,使用mkfs.vfat命令将分区格式化为fat格式,再使用mdir命令创建挂载目录/mnt/mmcblk1p1,最后使用mount命令/dev下的mmcblk1p1挂载到新建的目录上。

<!-- 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>

<CMD state="Updater" type="push" body="$ mkfs.vfat /dev/mmcblk%mmc%p1">Formatting rootfs partition</CMD>

<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"/>

有了挂载目录,就可以将ProfilesLinuxOS Firmwarefiles目录下的镜像烧录到EMMC了,其实就是一个拷贝的操作。

先是拷贝ProfilesLinuxOS Firmwarefiles目录的zImage文件到EMMC。

<!-- 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>

<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/zImagebak">write kernel image to sd card</CMD>

然后是logo图片,

<!-- burn logo -->

<CMD state="Updater" type="push" body="send" file="files/logo.bmp">Sending logo bmp</CMD>

<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/logo.bmp">write logo bmp to sd card</CMD>

然后是dtb文件,再使用umount命令将挂载目录卸载掉。

<!-- burn dtb -->

<CMD state="Updater" type="push" body="send" <CMD state="Updater" type="push" body="send" file="files/imx6ull-elf1-emmc.dtb" ifdev="MX6ULL">Sending Device Tree file</CMD>

<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/imx6ull-elf1-emmc.dtb" ifdev="MX6ULL">write device tree to sd card</CMD>

<CMD state="Updater" type="push" body="$ umount /mnt/mmcblk%mmc%p1">Unmounting vfat partition</CMD>

最后是格式化ext3分区并烧录文件系统,与fat分区是同样的操作,先是使用mkfs.ext3命令将分区格式化为ext3格式,然后使用mkdir命令创建挂载分区目录/mnt/mmcblk1p2,并将分区挂载到目录上。

<!-- burn rootfs -->

<CMD state="Updater" type="push" body="$ mkfs.ext3 -F -E nodiscard /dev/mmcblk%mmc%p2">Formatting rootfs partition</CMD>

<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"/>

有了挂载目录,就可以将ProfilesLinuxOS Firmwarefiles下的文件系统压缩包rootfs.tar.bz2和模块驱动压缩包modules.tar.bz2解压到挂载目录中了,解压之后使用umount命令卸载挂载目录。

<CMD state="Updater" type="push" body="pipe tar -jxv -C /mnt/mmcblk%mmc%p2" file="files/rootfs.tar.bz2" ifdev="MX6UL MX7D MX6ULL">Sending and writting rootfs</CMD>

<CMD state="Updater" type="push" body="frf">Finishing rootfs write</CMD>

<CMD state="Updater" type="push" body="pipe tar -jxv -C /mnt/mmcblk%mmc%p2" file="files/modules.tar.bz2" ifdev="MX6UL MX7D MX6ULL">Sending and writting modules</CMD>

<CMD state="Updater" type="push" body="frf">Finishing modules software write</CMD>

<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>

(四)烧录技巧

前面了解了整个烧录的流程,我们就可以对ucl2.xml文件进行修改来方便烧写,其中烧录文件系统是最耗时的,因为文件系统的压缩包比较大,需要完全把压缩包解压到EMMC中,如果我们想要加快烧录时间,不希望烧录文件系统,我们就可以将ucl2.xml文件中烧录文件系统的部分屏蔽掉,屏蔽语法为<!-- -->方法如下:

<!-- burn rootfs -->

<!--

<CMD state="Updater" type="push" body="$ mkfs.ext3 -F -E nodiscard /dev/mmcblk%mmc%p2">Formatting rootfs partition</CMD>

<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"/>

<CMD state="Updater" type="push" body="pipe tar -jxv -C /mnt/mmcblk%mmc%p2" file="files/rootfs-qt.tar.bz2" ifdev="MX6UL MX7D MX6ULL">Sending and writting rootfs</CMD>

<CMD state="Updater" type="push" body="frf">Finishing rootfs write</CMD>

<CMD state="Updater" type="push" body="pipe tar -jxv -C /mnt/mmcblk%mmc%p2" file="files/modules.tar.bz2" ifdev="MX6UL MX7D MX6ULL">Sending and writting modules</CMD>

<CMD state="Updater" type="push" body="frf">Finishing modules software write</CMD>

<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>

-->

通过上面的学习,我们对Mfgtools工具的烧录原理已经有了充分的理解,那么我们就可以将这个工具进行修改变成自己的工具啦

相关推荐

电子产业图谱