i.MX6 Mfgtool中ucl文件解析

本文主要讲述基于Mfgtool V2来说明ucl.xml文件的使用,以及解释其中的意思。
关于ucl2.xml的介绍可以参照Manufacturing Tool V2 UCL User Guide.docx文件。


Mfgtool启动参数

Mfgtool/目录下会有各种.vbs的脚本文件,比如说:
mfgtool2-android-mx6qp-xxx-emmc.vbs文件,文件名标记这是使用Android系统,平台是imx6qp,板子为xxx,使用emmc启动。内容如下:
vbs文件

启动这个脚本文件会去启动mfgtools2.exe应用程序,并将其中的参数传递给mfgtools2.exe。各个参数的大概解释如下:

  • -c “”linux””:用于告知ucl2.xml文件在路径为Profiles\linux\OS Firmware\目录下;
  • -l ""i.MX6QP-xxx-eMMC"":用于标记在ucl2.xml文件中使用哪个LIST name
  • -s:可自定义参数传递给ucl2.xml文件使用;

具体的参数解释如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
MfgTool2 can support command line feature, the commands that can be accepted are “-c, -l, -p and -noui”. 
The format of command line looks like:
MfgTool2.exe [-noui] [-c] [“chip profile folder name”] [-l] [“list name”] [-p] [number][-s] [“variable=value” ]
Parameters description:
-noui: this command has no any parameter, if this command is used, the application will use the console interface, otherwise, the GUI interface will be used.
Note: this command must be the second parameter (the first parameter is application name), if it is used.
-c: indicate the target profile name. The parameter of this command is a string with a pair of double quotes.
-l: indicate the target operation list name which can be found in the file located at "profiles/CHIP_PROFILE/OS Firmware/ucl2.xml". The parameter of this command is a string with a pair of double quotes.
-p: indicate the number of ports which indicates how many boards can be supported simultaneously. The parameter of this command must be a number between 1 and 4.
-s: Set ucl variable value. Support multiply if you need set more one variable.

All above parameters are not mandatory, if no parameter in the command line, the application will try to find the parameter from the corresponding file, e.g. if ‘-c’ parameter is not provided in the command line, the application will try to get it from ‘cfg.ini’ file just like the v2.0.x, if the application can't get the parameter from both the command line and cfg.ini file, the application will fail to run.

If both command line and cfg.ini/UIcfg.ini assign the same parameter, the application will take the command line parameter with priority.

Press CTRL+C or the Close button to close the APP.

当启动.vbs脚本运行失败后,会有如下提示:
失败提示

此时在当前目录下会生成MfgTool.log文件,查看该文件即可知道错误的原因,一般情况下是要烧写的文件与ucl2.xml标记要烧写的文件名或路径没有对应,或者缺少ucl2.xml指定的文件。
在此并不建议使用-s传递给ucl2.xml参数。一般我们开发中同时开发一个或者两个项目,将所要烧写的image文件固定文件名存放在某个固定目录下,然后在ucl2.xml指定即可。
而这个-s参数的出现是为了应对不同的开发项目中不同的board、soc、plus等,-s参数的出现有更多的扩展性,但是目前我们暂时不需要。


ucl2.xml简介

1
2
3
Manufacturing (Mfg) tool provides a flexible way for users to set their own operations.
An xml script file is used to configure the users operation.
An xml file typically consists of a number of tasks which can be executed by running the manufacturing tool just once.

ucl2.xml的结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<UCL>
<CFG>
<STATE name="BootStrap" dev="MX6SL" vid="15A2" pid="0063"/>
<STATE name="BootStrap" dev="MX6D" vid="15A2" pid="0061"/>
<STATE name="BootStrap" dev="MX6Q" vid="15A2" pid="0054"/>
<STATE name="BootStrap" dev="MX6SX" vid="15A2" pid="0071"/>
<STATE name="BootStrap" dev="MX6UL" vid="15A2" pid="007D"/>
<STATE name="BootStrap" dev="MX7D" vid="15A2" pid="0076"/>
<STATE name="Updater" dev="MSC" vid="066F" pid="37FF"/>
</CFG>

<LIST name="i.MX6QP-xxx-eMMC" desc="Write i.MX6QP-xxx system boot from eMMC">
<CMD>

</CMD>

<CMD>

</CMD>
</LIST>

<LIST>
<CMD>

</CMD>
</LIST>
</UCL>
```

(1)、全局配置
在`<CFG>`和`</CFG>`中间属于全局配置,这里的配置固定。

(2)、hid设备
``` c
<STATE name="BootStrap" dev="MX6Q" vid="15A2" pid="0054"/>

这里的USB pid”0054”and vid”15A2”标记当前板子是USB HID设备的pid和vid。这也就是为什么在download模式下,板子首先会被识别为HID设备。

(3)、mass storage设备

1
<STATE name="Updater"   dev="MSC" vid="066F" pid="37FF"/>

这里的USB pid”37FF”and vid”066F”标记当前板子是USB MSC大容量存储设备的pid和vid。

(4)、<LIST></LIST>中间为命令合集配置
<LIST name="xxx", desc="xxx">
name和desc都是用于注释使用,在一个ucl2.xml文件中会有多个<LIST>,每个<LIST>通过name来区分,并在.vbs决定使用哪个<LIST>。大概的结构如下:

1
2
3
4
5
<LIST name="i.MX6QP-xxx-eMMC" desc="Write i.MX6QP-xxx system boot from eMMC">
<CMD>

</CMD>
</LIST>

(5)、<CMD></CMD>之间为具体的命令,包括两种类型的命令:

  • Host specific commands:parsed and executed by host tool;
    Host specific commands
  • firmware specific commands:parsed and executed by firmware runs on targeted device。
    firmware specific commands
    firmware specific commands

CMD例子分析

(1)、

1
2
3
4
<!--
Write xxx system boot from emmc,kernel from emmc
-->
<LIST name="i.MX6QP-xxx-eMMC" desc="Write i.MX6QP-xxx system boot from eMMC">

用来区分标记烧写"i.MX6QP-xxx-eMMC"的平台;

(2)、

1
2
3
4
5
6
7
8
9
10
<CMD type="find" body="Recovery" timeout="180"/>
<CMD type="boot" body="Recovery" file ="files/xxx/u-boot-mx6q-xxx-mfg.bin">Loading U-boot</CMD>
<CMD type="load" file="files/xxx/uImage-mx6q-xxx-mfg" address="0x10800000"
loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE">Loading Kernel.</CMD>

<CMD type="load" file="initramfs.cpio.gz.uboot" address="0x12800000"
loadSection="OTH" setion="OTH" HasFlashHeader="FALSE">Loading Initramfs.</CMD>

<CMD type="jump"> Jumping to OS image. </CMD>
<CMD type="find" body="Updater" timeout="360"/>

此处将Mfgtoolsfirmware(u-boot,uImage,ramdisk)load到RAM指定的位置上,然后跳转启动mini os。
前两个文件用户可以自己客制化编译,后面的ramdisk需要NXP提供。如果想要自己修改ramdisk,可以参照:https://community.nxp.com/thread/300430

此处将uImage镜像load到RAM的0x10800000位置上,将ramdisk镜像load到0x12800000的位置上。
注意这两个地址之间的大小一定要足够容纳下整个uImage的大小。

(3)、

1
2
<CMD type="push" body="send" file="files/xxx/mknandpartition-xxx.sh.tar">Sending partition shell</CMD>
<CMD type="push" body="$ tar xf $FILE "> Partitioning...</CMD>

将分区脚本的压缩文件mknandpartition-xxx.sh.tar发送到$FILE并解压$FILE文件。

(4)、

1
2
3
<CMD type="push" body="mknod block,mmcblk0,/dev/mmcblk0,block"/>
<CMD type="push" body="mknod block,mmcblk0boot0,/dev/mmcblk0boot0,block"/>
<CMD type="push" body="mknod block,mmcblk0boot1,/dev/mmcblk0boot1,block"/>

创建/dev/mmcblk0的设备节点,用于创建分区使用。

(5)、

1
2
<CMD type="push" body="$ dd if=/dev/zero of=/dev/mmcblk0 bs=128M count=1"> Erasing MBR and kernel parameters...</CMD>
<CMD type="push" body="$ sh mknandpartition-xxx.sh /dev/mmcblk0"> Partitioning...</CMD>

清除/dev/mmcblk0 128M大小的信息,之后执行脚本mknandpartition-xxx.sh,这个脚本的内容为:

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/sh

# 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
128M,300M,83
428M,254M,83
686M,256M,83
EOF

使用sfdisk命令在/dev/mmcblk0上面创建三个分区,分区的信息如下:

  • 第1个分区:起始位置为128M,大小为300M,83表示linux下挂载的磁盘;
  • 第2个分区:起始位置为428M,大小为254M,
  • 第3个分区:起始位置为686M,大小为256M。
    注意:这里的分区信息要与挂载的文件大小相对应。比如说第1个分区设置为300M,是为了挂载system分区,要保证system.img的小于300M。
    当然,这里的分区是要跟emmc 的layout挂钩的。

(6)、

1
2
3
<CMD type="push" body="mknod block/mmcblk0,mmcblk0p1,/dev/mmcblk0p1,block"/>
<CMD type="push" body="mknod block/mmcblk0,mmcblk0p2,/dev/mmcblk0p2,block"/>
<CMD type="push" body="mknod block/mmcblk0,mmcblk0p3,/dev/mmcblk0p3,block"/>

创建3个分区的设备节点。

(7)、

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<CMD type="push" body="send" file="files/files/xxx/u-boot.imx">Sending u-boot.bin</CMD>
<CMD type="push" body="$ dd if=$FILE of=/dev/mmcblk0 bs=1k seek=1 conv=fsync">write u-boot.bin to nand</CMD>
<CMD type="push" body="$ sync">sync</CMD>

<CMD type="push" body="send" file="files/kernel-header">Sending kernel-header</CMD>
<CMD type="push" body="$ dd if=$FILE of=/dev/mmcblk0 bs=512 seek=1024">write kernel-header to eMMC</CMD>
<CMD type="push" body="$ dd if=$FILE of=/dev/mmcblk0 bs=512 seek=1280">write kernel-header to eMMC</CMD>

<CMD type="push" body="send" file="files/ramdisk-header">Sending ramdisk-header</CMD>
<CMD type="push" body="$ dd if=$FILE of=/dev/mmcblk0 bs=512 seek=1025">write ramdisk-header to eMMC</CMD>
<CMD type="push" body="$ dd if=$FILE of=/dev/mmcblk0 bs=512 seek=1281">write ramdisk-header to eMMC</CMD>

<CMD type="push" body="send" file="files/files/xxx/uImage">Sending kernel uImage</CMD>
<CMD type="push" body="$ dd if=$FILE of=/dev/mmcblk0 bs=1M seek=6 conv=fsync">write kernel image B to nand</CMD>
<CMD type="push" body="$ dd if=$FILE of=/dev/mmcblk0 bs=1M seek=1 conv=fsync">write kernel image A to nand</CMD>

<CMD type="push" body="send" file="files/files/xxx/uramdisk.img">Sending ramdisk image</CMD>
<CMD type="push" body="$ dd if=$FILE of=/dev/mmcblk0 bs=1M seek=59 conv=fsync">write ramdisk image B to nand</CMD>
<CMD type="push" body="$ dd if=$FILE of=/dev/mmcblk0 bs=1M seek=11 conv=fsync">write ramdisk image A to nand</CMD>

分别将u-boot.imx/kernel-header/ramdisk-header/uImage/uramdisk.img文件dd到指定的emmc位置上。
具体放到emmc的哪个位置上,要参考layout来进行设置。

(8)、

1
2
<CMD type="push" body="$ dd if=/dev/zero of=/dev/mmcblk0 bs=1M seek=127 count=1"> Erasing CCID...</CMD>
<CMD type="push" body="$ dd if=/dev/zero of=/dev/mmcblk0 bs=1M seek=894 count=4"> Erasing Data...</CMD>

1
2
<CMD type="push" body="send" file="files/files/xxx/bootani.img">Sending bootani image</CMD>
<CMD type="push" body="$ dd if=$FILE of=/dev/mmcblk0 bs=1M seek=107 conv=fsync">write bootani image to nand</CMD>

为什么这里要设置这些内容还不是很清楚。

(9)、

1
<CMD type="push" body="pipe dd of=/dev/mmcblk0p1 bs=1M conv=fsync" file="files/files/xxx/system.img">Sending and writting system image</CMD>

使用pipe去传输并dd大的文件(system.img 300M)而不是使用push
这里将system.imgdd到mmcblk磁盘上的第1个分区。

(10)、

1
2
<CMD type="push" body="$ mkfs.ext4 -O ^extent -L var /dev/mmcblk0p2">Formatting partition 1</CMD>
<CMD type="push" body="$ mkfs.ext4 -O ^extent -L data /dev/mmcblk0p3">Formatting partition 2</CMD>

使用mkfs.ext4的命令创建/var/data分区。

(11)、

1
2
<CMD type="push" body="$ sync">sync</CMD>	
<CMD type="push" body="$ echo Update Complete!">Done</CMD>

最后面标记烧录完毕。

Title:i.MX6 Mfgtool中ucl文件解析

Author:Victor Huang

Time:2019-06-08 / 13:06

Link:http://wowothink.com/084705fd/

License: Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)