前面几篇文章,已经搞定了Linux移植三巨头:uboot、kernel(包含dtb)和rootfs,除了uboot是烧写在SD中的,其它的都是在ubuntu虚拟机的nfs服务器中,运行时必须通过网络将这些文件加载到开发板的内存中运行。
本篇就来研究,将这几个文件打包烧写到板子的eMMC中,实现嵌入式Linux系统的烧写,这样,在没有网络的情况下,板子也可以正常运行。系统烧写使用的是NXP官方的MfgTool工具,通过USB OTG口来烧写。
一、MfgTool工具简介
MfgTool 工具是 NXP 提供的专门用于给 I.MX 系列 CPU 烧写系统的软件,可以在 NXP 官网下载到。该软件需要在Windows环境下使用。
这是使用正点原子提供的已经下载好的NXP烧写工具:L4.1.15_2.0.0-ga_mfg-tools.tar.gz。
将软件包解压,里面还有2个.gz 压缩包,一个是带rootfs,一个是不带rootfs,我们是需要烧写文件系统的,所以选择 mfgtools-with-rootfs.tar.gz 这个压缩包,继续解压。
进入目录 mfgtools-with-rootfs\mfgtools 中, 在此目录下有几个文件夹和很多的.vbs 文件:
Profiles文件夹
:要烧写的文件就放到这个文件夹中。MfgTool2.exe
:烧写软件,但不需要直接打开这个软件烧写。众多的.vbs 文件
:烧写配置脚本,指定烧写的芯片和地址,烧写的时候通过双击这些.vbs文件来打开烧写工具。这些.vbs 烧写脚本既可以根据处理器的不同,由用户选择向 I.MX6D、I.MX6Q、I.MX6S、I.MX7、I.MX6UL 和 I.MX6ULL 等的哪一款芯片烧写系统。也可以根据存储芯片的不同,选择向 EMMC、NAND 或 QSPI Flash 等的哪一种存储设备烧写,功能非常强大。
二、 MfgTool烧写步骤
2.1 连接USB OTG
MfgTool是通过USB OTG接口将系统烧写进EMMC中的,使用USB线连接电脑(使用USB OTG连接时,需要先把SD卡拔出)。
2.2 切换拨码开关模式
将拨码开关拨到USB下载模式
连接电源,进入USB模式,连接成功后电脑右下角会有提示
2.3 系统烧写
双击“mfgtool2-yocto-mx-evk-emmc.vbs” ,出现如下窗口:
如果出现“符合HID标准的供应商定义设备”就说明连接正常,可以进行烧写。若硬件连接完毕,烧写文件也配置好了,点击Start按钮即可一键烧写。
3 MfgTool烧写原理
我们需要烧写uboot、kernel、.dtb 和 rootfs这四个文件,它们一起构成了linux系统。
进入如下的系统固件目录中:
L4.1.15_2.0.0-ga_mfg-tools/mfgtools-with-rootfs/mfgtools/Profiles/Linux/OS Firmware
我们重点关注files、firmware这两个文件夹,以及ucl2.xml这个文件。
MfgTool烧写的工作过程主要分两个阶段:
- 第一阶段:MfgTool先通过USB OTG先将firmware目录中uboot、kernel和.dtb这是三个文件下载到开发板的DDR内存中(注意不需要下载 rootfs),就相当于直接在开发板的内存上启动Linux系统。
- 第二阶段:等Linux 系统启动以后(这时可以方便的完成对EMMC的格式化、分区等操作),再向EMMC中烧写完整的系统,包括files目录中的uboot、linux kernel、.dtb和rootfs这4个文件。
3.1 firmeare文件夹
mfgtools/Profiles/Linux/OS Firmware/firmware文件夹里有很多NXP官方开发板使用的文件,包括.imx 结尾的uboot文件、一个zImage镜像文件、很多.dtb结尾的设备树文件,我们需要注意其中三个文件:
zImage
:NXP官方I.MX6ULL EVK开发板的Linux镜像文件u-boot-imx6ull14x14evk_emmc.imx
:NXP官方I.MX6ULL EVK开发板的uboot文件zImage-imx6ull-14x14-evk-emmc.dtb
:NXP 官方I.MX6ULL EVK开发板的设备树
这3个文件即第一阶段需要烧写的文件,如果要烧写我们的系统,就要用自己编译的文件替换这3个文件。
3.2 files文件夹
mfgtools/Profiles/Linux/OS Firmware/files目录中的文件和firmware 目录中的基本差不多,这里就要注意下面4个文件
zImage
:同上u-boot-imx6ull14x14evk_emmc.imx
:同上zImage-imx6ull-14x14-evk-emmc.dtb
:同上rootfs_nogpu.tar.bz2
:根文件系统(nogpu表示不包含GPU的内容)
这4个文件即第二阶段需要烧写的文件,如果要烧写我们的系统,就要用自己编译的文件替换这4个文件。
3.3 ucl2.xml文件
mfgtools/Profiles/Linux/OS Firmware/ucl2.xml是一种XML格式的文件,用来指定files和firmware目录要烧写的uboot和设备树文件。
ucl2.xml 以 “<UCL>
” 开始, 以 “</UCL>
” 结束。 “<CFG>
”和“</CFG>
”之间是配置相关内容,“<LIST>
”和“</LIST>
”之间的是针对不同存储芯片的烧写命令。
ucl2.xml文件有600多行,这里抽取主干结构来看一个该文件的主要运行流程:
<UCL>
<CFG>
<!-- 判断向 I.MX 系列的哪个芯片烧写系统 -->
<STATE name="BootStrap" dev="MX6SL" vid="15A2" pid="0063"/>
<!-- ...省略若干行参数配置 -->
</CFG>
<LIST name="SDCard" desc="Choose SD Card as media">
<!-- 向 SD 卡烧写 Linux 系统 -->
<!-- ...省略若干行烧写配置 -->
</LIST>
<LIST name="eMMC" desc="Choose eMMC as media">
<!-- [1]向 EMMC 烧写 uboot(.imx) -->
<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-imx6ul%lite%%6uluboot%_emmc.imx" ifdev="MX6ULL">Loading U-boot</CMD>
<!-- [2]向 EMMC 烧写 Kernel(zImage) -->
<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>
<!-- [3]向 EMMC 烧写 initramfs -->
<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>
<!-- [4]向 EMMC 烧写 device tree(.dtb) -->
<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>
<!-- ...省略若干行烧写配置 -->
<!-- [5]跳转到系统镜像 -->
<CMD state="BootStrap" type="jump" > Jumping to OS image. </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">
<!-- 向 Nor Flash 烧写 Linux 系统 -->
<!-- ...省略若干行烧写配置 -->
</LIST>
<LIST name="Quad Nor Flash" desc="Choose Quad Nor flash as media">
<!-- 向 Quad Nor Flash 烧写 Linux 系统 -->
<!-- ...省略若干行烧写配置 -->
</LIST>
<!-- ...省略若干行其它存储位置的烧写 -->
</UCL>
ucl2.xml 首先会判断当前要向I.MX系列的哪个型号的芯片烧写系统:
通过读取芯片的VID和PID,即可判断要烧什么处理器的系统, 如VID=0X15A2,PID=0080,就表示要给I.MX6ULL烧写系统。
3.4 xxx.vbs文件
ucl2.xml文件中确定了要烧写的处理器型号以后,还要确定向什么存储设备烧写系统,这是在mfgtools/mfgtool2-yocto-mx-evk-emmc.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
注意“wshShell.run”这一行,调用了 mfgtool2.exe 这个软件,还给出了一堆的参数,包含“eMMC”字样,表示是向 EMMC 烧写系统
下面继续分析ucl2.xml文件中的烧写过程
前面说了烧写分两个阶段, 第一步是通过 USB OTG 向 DDR中下载系统,第二步才是正常的烧写。
根据当前是EMMC的板子,第1步烧写uboot的命令如下:
<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-imx6ul%lite%%6uluboot%_emmc.imx" ifdev="MX6ULL">Loading U-boot </CMD>
“file” 表示要下载的文件位置:
firmware/u-boot-imx6ul%lite%%6uluboot%_emmc.imx
“%lite%”
和“%6uluboot%”
分别表示取lite和6uluboot的值, 那lite和6uluboot的值是多少呢?在cfg.ini文件中有定义。
3.5 cfg.ini文件
mfgtools/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=14x14evk。
继续分析ucl2.xml文件中的烧写过程,将lite和6uluboot的值代入以后,要烧写的uboot文件名就是:
firmware/u-boot-imx6ull14x14evk _emmc.imx
同样的方法将.dtb(设备树)和zImage都下载到DDR中以后就会跳转去运行OS,这个时候会在MfgTool工具中会有“Jumping to OS image”提示语句,ucl2.xml中的跳转命令如下:
<CMD state="BootStrap" type="jump" > Jumping to OS image. </CMD>
启动Linux系统以后就可以在EMMC上创建分区,然后烧写uboot、zImage、.dtb(设备树)和根文件系统。
三、烧写自己的系统
准备要烧写的文件:
- 自己移植编译出来的uboot文件:u-boot.imx(位于u-boot源码主目录中)
- 自己移植编译出来的zImage镜像文件(位于Kernel源码的arch/arm/boot目录中)和开发板对应的.dtb(设备树)mx6ull-myboard.dtb(位于Kernel源码的arch/arm/boot/dts目录中)
- 自己构建的根文件系统rootfs
rootfs需要先打包成rootfs.tar.bz2,进入Ubuntu中的nfs目录下的rootfs目录,使用tar命令打包:
cd rootfs/
tar -vcjf rootfs.tar.bz2 *
将这4个文件复制到Windows系统中准备烧录。
总结一下要准备的文件,如下图:
烧写时,这里有两种修改方式进行烧写,一种是将自己的4个文件按照NXP官方的文件进行重命名,并替换掉官网的文件,即可直接烧录。另一种是改造MfgTool烧写工具,使得该烧写工具能够兼容自己板子的文件名。因为第2种修改比较麻烦,先使用第1种简单的方式进行烧写,只需要修改文件名即可,并且必须对其进行重命名,否则的话 ucl2.xml 是识别不出来的。
需要替换的名称为:
点击Start开始烧写,等待烧写完成:
烧录完,点击Stop退出即可。
然后切换板子为EMMC启动,复位重启开发板,正常情况下应该就可以看到烧录的系统正常启动了。
转载来源:i.MX6ULL嵌入式Linux开发6-系统烧写到eMMC与遇到的坑! - 知乎