系统烧写方法(MfgTool烧写工具)

2023-11-18

前面我们已经移植好了uboot 和linux kernle,制作好了根文件系统。但是我们移植都是通过网络来测试的,在实际的产品开发中肯定不可能通过网络来运行,否则没网的时候产品岂不是就歇菜了。因此我们需要将uboot、linux kernel、.dtb(设备树)和rootfs这四个文件烧写到板子上的EMMC、NAND 或QSPI Flash 等其他存储设备上,这样不管有没有网络我们的产品都可以正常运行。本章我们就来学习一下如何使用NXP 官方提供的MfgTool 工具通过USB OTG 口来烧写系统。

MfgTool 工具简介

MfgTool 工具是NXP 提供的专门用于给I.MX 系列CPU 烧写系统的软件,可以在NXP 官网下载到。

此工具已经放到了开发板光盘中,路劲为:5、开发工具->3、NXP 官方原版MFG_TOOL烧写工具->L4.1.15_2.0.0-ga_mfg-tools.tar.gz。此软件在Windows下使用,对于我们来说太友好了。将此压缩包进行解压,解压完成以后会出现一个名为L4.1.15_2.0.0-ga_mfg-tools的文件夹,进入此文件夹,此文件夹的内容如图39.1.1 所示:

在这里插入图片描述
从图39.1.1 可以看出,有两个.txt 文件和两个.gz 压缩包。.txt 文档就不去看了,重点是这两个.gz 压缩包,这两个压缩包的区别在名字上已经写的很详细了。“without-rootfs”和“with-rootfs”,一个是带rootfs 和一个是不带rootfs。mfg_tools 这个工具本意是给NXP 自己的开发板设计的烧写软件,所以肯定带有自家开发板对应的uboot、linux kernel 和rootfs 的文件。我们肯定是要烧
写文件系统的,所以选择mfgtools-with-rootfs.tar.gz 这个压缩包,继续对其解压,解压出一个名为mfgtools-with-rootfs 的文件夹,此文件夹就包含有我们需要的烧写工具。

进入目录mfgtools-with-rootfs\mfgtools 中,在此目录下有几个文件夹和很多的.vbs 文件,如图39.1.2 所示:
在这里插入图片描述
我们只关心图39.1.2 中Profiles 这个文件夹,因为后面要烧写文件就放到这个文件夹中。MfgTool2.exe 就是烧写软件,但是我们不会直接打开这个软件烧写,mfg_tools 不仅能烧写I.MX6U,而且也能给I.MX7、I.MX6Q 等芯片烧写,所以在烧写之前必须要进行配置,指定烧写的是什么芯片,烧写到哪里去?

下面的这些众多的.vbs 文件就是配置脚本,烧写的时候通过双击这些.vbs 文件来打开烧写工具。这些.vbs 烧写脚本既可以根据处理器的不同,由用户选择向I.MX6D、I.MX6Q、I.MX6S、I.MX7、I.MX6UL 和I.MX6ULL 等的哪一款芯片烧写系统。也可以根据存储芯片的不同,选择向EMMC、NAND 或QSPI Flash 等的哪一种存储设备烧写,功能非常强大!!我们现在需要向I.MX6U 烧写系统,因此需要参考表39.1.1 所示的5 个烧写脚
本:

脚本文件 描述
mfgtool2-yocto-mx-evk-emmc.vbs EMMC 烧写脚本
mfgtool2-yocto-mx-evk-nand.vbs NAND 烧写脚本
mfgtool2-yocto-mx-evk-qspi-nor-n25q256a.vbs QSPI Flash 烧写脚本,型号为n25q256a
mfgtool2-yocto-mx-evk-sdcard-sd1.vbs 如果SD1 和SD2 接的SD 卡,这两个文件分
mfgtool2-yocto-mx-evk-sdcard-sd2.vbs 别向SD1 和SD2 上的SD 卡烧写系统。

本书用的是正点原子的EMMC 版核心板,因此只会用到mfgtool2-yocto-mx-evk-emmc.vbs 这个烧写脚本,如果用其他的核心板请参考相应的烧写脚本。

MfgTool 工作原理简介

MfgTool 只是个工具,具体的原理不需要去深入研究,大概来了解一下其工作原理就行了,知道它的工作流程就行了。

USB接线

1、连接USB 线

MfgTool 是通过USB OTG 接口将系统烧写进EMMC 中的,正点原子I.MX6U-ALPHA 开发板上的USB OTG 口如图39.2.1.1 所示:
在这里插入图片描述
在烧写之前,需要先用USB 线将图39.2.2.1 中的USB_OTG1 接口与电脑连接起来。

2、拨码开关拨到USB 下载模式

将图39.2.2.1 中的拨码开关拨到“USB”模式,如图39.2.2.2 所示:
在这里插入图片描述
如果插了TF 卡,请弹出TF 卡,否则电脑不能识别USB!等识别出来以后再插上TF 卡!

一切准备就绪以后,按一下开发板的复位键,此时就会进入到USB 模式,如果是第一次进入USB 模式的话可能会久一点,这个是免驱的,因此不需要安装驱动。第一次进入USB 模式会在电脑右下角有如图39.2.2.3 所示提示:

在这里插入图片描述

一旦第一次设置好设备以后,后面每次连接都不会有任何提示了。到这里,我们的开发板已经和电脑连接好了,可以开始烧写系统了。

系统烧写原理

开发板连接电脑以后双击“mfgtool2-yocto-mx-evk-emmc.vbs”,打开下载对话框,如图39.2.2.1 所示:

在这里插入图片描述
如果出现“符合HID 标准的供应商定义设备”就说明连接正常,可以进行烧写,如果出现其他的字符那么就要检查连接是否正确。点击“Start”按钮即可开始烧写

烧写什么东西呢?肯定是烧写uboot、Linux kernel、.dtb 和rootfs,那么这四个应该放到哪里MfgTool 才能访问到呢?进入如下目录中:

L4.1.15_2.0.0-ga_mfg-tools/mfgtools-with-rootfs/mfgtools/Profiles/Linux/OS Firmware

此目录中的文件如图39.2.2.2 所示:

在这里插入图片描述

文件夹“OS Firmware”看名字就知道是存放系统固件的,我们重点关注files、firmware 这两个文件夹,以及ucl2.xml 这个文件。

在具体看这三个文件和文件夹之前,我们先来简单了解一下MfgTool 烧写的原理,主要分两个阶段:

  • ①、将firmware 目录中的uboot、linux kernel 和.dtb(设备树),通过USB OTG 将这个文件下载到开发板的DDR 中(注意不需要下载rootfs),目的就是在DDR 中启动Linux 系统,为后面的烧写做准备。

  • ②、经过第①步的操作,此时Linux 系统已经运行起来了,系统运行起来以后就可以很方便的完成对EMMC 的格式化、分区等操作。EMMC 分区建立好以后就可以从files 中读取要烧写的uboot、linux kernel、.dtb(设备树)和rootfs 这4 个文件,然后将其烧写到EMMC 中,这个就是MfgTool 的大概工作流程。

1、firmeare 文件夹

打开firmware 文件夹,里面有很多的.imx 结尾的uboot 文件、一个zImage 镜像文件、很多.dtb 结尾的设备树文件。这些文件都是NXP 官方开发板使用的,不同的板子使用不同的文件,其中我们需要关心的只有表39.2.2.1 中的这三个文件:

脚本文件 描述
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 开发板的设备树

表39.2.2.1 中的这三个文件就是I.MX6ULL EVK 开发板烧写系统的时候第一阶段所需的文件。如果要烧写我们的系统,就需要用我们编译出来的zImage、u-boot.imx 和imx6ull-alientek-emmc.dtb 这三个文件替换掉表39.2.2.1 中这三个文件。但是名字要和表39.2.2.1 中的一致,因此需要将u-boot.imx 重命名为u-boot-imx6ull14x14evk_emmc.imx,将imx6ull-alientek-emmc.dtb重命名为zImage-imx6ull-14x14-evk-emmc.dtb。

2、files 文件夹

将表39.2.2.1 中的这三个文件下载到开发板的DDR 上以后烧写的第一阶段就完成了,第二阶段就是从files 目录中读取整个系统文件,并将其烧写到EMMC 中。files 目录中的文件和firmware 目录中的基本差不多,都是不同板子对应的uboot、设备树文件,同样,我们只关心表39.2.2.2 中的四个文件:

脚本文件 描述
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 开发板的设备树
rootfs_nogpu.tar.bz2 根文件系统,注意和另外一个rootfs.tar.bz2 根文件系统区分开。nogpu 表示此根文件系统不包含GPU 的内容,I.MX6ULL 没有GPU,因此要使用此根文件系统

如果要烧写我们自己编译出来的系统,就需要用我们编译出来的zImage、u-boot.imx 和imx6ull-alientek-emmc.dtb 和rootfs 这四个文件替换掉表39.2.2.2 中这四个文件。

3、ucl2.xml 文件

files 和firmware 目录下有众多的uboot 和设备树,那么烧写的时候究竟选择哪一个呢?这个工作就是由ucl2.xml 文件来完成的。

ucl2.xml 以“< UCL>”开始,以“< /UCL>”结束。“< CFG>”和“< /CFG>”之间是配置相关内容,主要是判断当前是给I.MX 系列的哪个芯片烧写系统。“< LIST>”和“< /LIST>”之间的是针对不同存储芯片的烧写命令。整体框架如下:

<UCL>
	<CFG>
	......
	<!-- 判断向I.MX系列的哪个芯片烧写系统-->
	......
	</CFG>
	<LIST name="SDCard" desc="Choose SD Card as media">
	<!-- 向SD卡烧写Linux系统-->
	</LIST>
	<LIST name="eMMC" desc="Choose eMMC as media">
	<!-- 向EMMC烧写Linux系统-->
	</LIST>
	<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>
	<LIST name="NAND Flash" desc="Choose NAND as media">
	<!-- 向NAND Flash烧写Linux系统-->
	</LIST>
	<LIST name="SDCard-Android" desc="Choose SD Card as media">
	<!-- 向SD卡烧写Android系统-->
	</LIST>
	<LIST name="eMMC-Android" desc="Choose eMMC as media">
	<!-- 向EMMC烧写Android系统-->
	</LIST>
	<LIST name="Nand-Android" desc="Choose NAND as media">
	<!-- 向NAND Flash烧写Android系统-->
	</LIST>
	<LIST name="SDCard-Brillo" desc="Choose SD Card as media">
	<!-- 向SD卡烧写Brillo系统-->
	</LIST>
</UCL>

ucl2.xml 首先会判断当前要向I.MX 系列的哪个芯片烧写系统,代码如下:

21 <CFG>
22 <STATE name="BootStrap" dev="MX6SL" vid="15A2" pid="0063"/>
23 <STATE name="BootStrap" dev="MX6D" vid="15A2" pid="0061"/>
24 <STATE name="BootStrap" dev="MX6Q" vid="15A2" pid="0054"/>
25 <STATE name="BootStrap" dev="MX6SX" vid="15A2" pid="0071"/>
26 <STATE name="BootStrap" dev="MX6UL" vid="15A2" pid="007D"/>
27 <STATE name="BootStrap" dev="MX7D" vid="15A2" pid="0076"/>
28 <STATE name="BootStrap" dev="MX6ULL" vid="15A2" pid="0080"/>
29 <STATE name="Updater" dev="MSC" vid="066F" pid="37FF"/>
30 </CFG>

通过读取芯片的VID 和PID 即可判断出当前要烧写什么处理器的系统,如果VID=0X15A2,PID=0080,那么就表示要给I.MX6ULL 烧写系统。确定了处理器以后就要确定向什么存储设备烧写系统,这个时候打开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 烧写系统,要烧写的存储设备就这样确定下来了。“wshShell.run”后面还有一堆的其他参数,这些参数都有对应的值,如下所示:

board=sabresd
mmc=1
6uluboot=14x14evk
6uldtb=14x14-evk

我们继续回到ucl2.xml 中,既然现在已经知道了是向I.MX6ULL 的EMMC 中烧写系统,那么直接在ucl2.xml 中找到相应的烧写命令就行了,因为相应的命令太长,为了缩小篇幅,我们就以uboot 的烧写为例讲解一下。前面说了烧写分两个阶段,第一步是通过USB OTG 向DDR中下载系统,第二步才是正常的烧写。通过USB OTG 向DDR 下载uboot 的命令如下:

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

上面的命令就是BootStrap 阶段,也就是第一阶段,“file”表示要下载的文件位置,在firmware目录下,文件名字为

u-boot-imx6ul%lite%%6uluboot%_emmc.imx

在L4.1.15_2.0.0-ga_mfg-tools\mfgtools-with-rootfs\mfgtools-with-rootfs\mfgtools 下找到cfg.ini 文件,该文件里包含了开发板的一些信息,查看cfg.ini 文件可得lite=l 以及一些字符串代表的值。
“%lite%”和“%6uluboot%”分别表示取lite 和6uluboot 的值,而lite=l,6uluboot=14x14evk,因此将这个值代入以后就是:

u-boot-imx6ull14x14evk _emmc.imx

所以,这里向DDR 中下载的是firmware/ u-boot-imx6ull14x14evk _emmc.imx 这个uboot 文件。同样的方法将.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(设备树)和根文件系统。

这个就是MfgTool 的整个烧写原理,弄懂了烧写原理以后就可以开始试着先将NXP 官方的系统烧写到正点原子的I.MX6U-ALPHA 开发板中。

烧写NXP 官方系统

我们先试着将NXP 官方的系统烧写到正点原子的I.MX6U-ALPHA 开发板中,主要是先熟悉一下烧写过程。因为正点原子的EMMC 核心版用的也是512MB 的DDR3 加8G 的EMMC,因此烧写NXP 官方的系统是没有任何问题的。烧写步骤如下:

①、连接好USB,拨码开关拨到USB 下载模式。
②、弹出TF卡,然后按下开发板复位按键。
③、打开SecureCRT。
③、双击“mfgtool2-yocto-mx-evk-emmc.vbs”,打开下载软件,如果出现“符合HID 标准的供应商定义设备”等字样就说明下载软件已经准备就绪。点击“Start”按钮开发烧写NXP 官方系统,烧写过程如图39.3.1 所示:
在这里插入图片描述
这个时候可以在SecurCRT 上看到具体的烧写过程,如图39.3.2 所示:
在这里插入图片描述
等待烧写完成,因为NXP 官方的根文件系统比较大,因此烧写的时候耗时会久一点。烧写完成以后MfgTool 软件如图39.3.3 所示:
在这里插入图片描述
烧写完成以后点击“Stop”按钮停止烧写,然后点击“Exit”键退出。拔出USB 线,将开发板上的拨码开关拨到EMMC 启动模式,然后重启开发板,此时就会从EMMC 启动。只是启动以后的系统是NXP 官方给I.MX6ULL EVK 开发板制作的,这个系统需要输入用户名,用户名为“root”,没有密码,如图39.3.3 所示:
在这里插入图片描述
在“imx6ul7d login:”后面输入“root”用户名,然后点击回车键即可进入系统中,进入系统以后就可以进行其他操作了。所以说,NXP 官方的系统其实是可以在正点原子的EMMC 版核心板上运行的。

烧写自制的系统

系统烧写

上一小节我们试着将NXP 官方提供的系统烧写到正点原子的I.MX6U-ALPHA 开发板中,目的是体验一下通过MfgTool 烧写系统的过程。本小节我们就来学习如何将我们做好的系统烧写到开发板中,首先是准备好要烧写的原材料:

  • ①、自己移植编译出来的uboot 可执行文件:u-boot.imx。
  • ②、自己移植编译出来的zImage 镜像文件和开发板对应的.dtb(设备树),对于I.MX6U-ALPHA 开发板来说就是imx6ull-alientek-emmc.dtb。
  • ③、自己构建的根文件系统rootfs,这里我们需要对rootfs 进行打包,进入到Ubuntu 中的rootfs 目录中,然后使用tar 命令对其进行打包,命令如下:
cd rootfs/
tar -vcjf rootfs.tar.bz2 *

完成以后会在rootfs 目录下生成一个名为rootfs.tar.bz2 的压缩包,将rootfs.tar.bz2 发送到windows 系统中。

将上面提到的这4 个“原材料”都发送到Windows 系统中,如图39.4.1 所示:

在这里插入图片描述
材料准备好以后还不能直接进行烧写,必须对其进行重命名,否则的话ucl2.xml 是识别不出来的,前面讲解ucl2.xml 语法的时候已经说过了,图39.4.1 中的这四个文件重命名见表39.4.1:

原名字 重命名
u-boot.imx u-boot-imx6ull14x14evk_emmc.imx
zImage zImage(不需要重命名)
imx6ull-alientek-emmc.dtb zImage-imx6ull-14x14-evk-emmc.dtb
rootfs.tar.bz2 rootfs_nogpu.tar.bz2

完成以后如图39.4.2 所示:
在这里插入图片描述
接下来就是用我们的文件替换掉NXP 官方的文件,先将图39.4.2 中的zImage、u-boot-imx6ull14x14evk_emmc.imx 和zImage-imx6ull-14x14-evk-emmc.dtb 这三个文件拷贝到mfgtools-with-rootfs/mfgtools/Profiles/Linux/OS Firmware/firmware目录中,替换掉原来的文件。然后将图39.4.2 中的所有4 个文件都拷贝到mfgtools-with-rootfs/mfgtools/Profiles/Linux/OS Firmware/files目录中,这两个操作完成以后我们就可以进行烧写了。

双击“mfgtool2-yocto-mx-evk-emmc.vbs”,打开烧写软件,点击“Start”按钮开始烧写,由于我们自己制作的rootfs 比较小,因此烧写相对来说会快一点。烧写完成以后设置开发板从EMMC 启动,启动我们刚刚烧写进去的系统,测试有没有问题。

注意!一旦自己改造的mfgtools 工具能够正常烧写系统,那么mfgtools-with-rootfs/mfgtools/Profiles/Linux/OS Firmware/firmware 目录下的文件以后就不能再修改!否则可能导致烧写失败!

网络开机自启动设置

大家在测试网络的时候可能会发现网络不能用,这并不是因为我们将系统烧写到EMMC中以后网络坏了,是因为网络没有打开

前面我们用NFS 挂载根文件系统的时候因为要使用NFS服务,因此Linux 内核会打开eth0 这个网卡,现在我们不使用NFS 挂载根文件系统,因此Linux内核也就不会自动打开eth0 网卡了。

我们可以手动打开网卡,首先输入

ifconfig -a

命令查看一下eth0 和eth1 网卡是否都存在,结果如图39.4.3 所示:
在这里插入图片描述
可以看出eth0 好eth1 都存在,既然存在我们就打开,以打开eth0 网卡为例,输入如下命令打开eth0:

ifconfig eth0 up

打开网卡的时候会有如图39.4.4 所示的提示信息:
在这里插入图片描述
打开的时候会提示使用LAN8710/LAN8720 的网络芯片,eth0 连接成功,并且是100Mpbs全双工,eth0 链接准备就绪。这个时候输入“ifconfig”命令就会看到eth0 这个网卡,如图39.4.6所示:
在这里插入图片描述
接下来就是给每个eth0网卡设置IP 地址,如果你的开发板连接的路由器,那么可以通过路由器自动分配IP 地址,命令如下:

udhcpc -i eth0 //通过路由器分配IP 地址

如果你的开发板连接着电脑,那么就可以手动设置IP 地址,比如设置为192.168.1.251,命令如下:

ifconfig eth0 192.168.1.251 netmask 255.255.255.0 //设置IP 地址和子网掩码
route add default gw 192.168.1.1 //添加默认网关

推荐大家将开发板连接到路由器上,设置好IP 地址以后就可以测试网络了,比如ping 一下电脑IP 地址,或者ping 一下百度官网。

每次开机以后都要自己手动打开网卡,然后手动设置IP 地址也太麻烦了,有没有开机以后自动启动网卡并且设置IP 地址的方法呢?肯定有的,我们将打开网卡,设置网卡IP 地址的命令添加到/etc/init.d/rcS 文件中就行了,完成以后的rcS 文件内容如下所示:

1 #!/bin/sh
2
3 PATH=/sbin:/bin:/usr/sbin:/usr/bin
4 LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib
5 export PATH LD_LIBRARY_PATH runlevel
6
7 #网络开机自启动设置
8 ifconfig eth0 up
9 #udhcpc -i eth0
10 ifconfig eth0 192.168.1.251 netmask 255.255.255.0
11 route add default gw 192.168.1.1
......
12 #cd /drivers
13 #./hello &
14 #cd /

第8 行,打开eth0 网卡
第9 行,通过路由器自动获取IP 地址。
第10 行,手动设置eth0 的IP 地址和子网掩码。
第11 行,添加默认网关。

修改好rcS 文件以后保存并退出,重启开发板,这个时候eth0 网卡就会在开机的时候自动启动了,我们也就不用手动添加相关设置了。

改造我们自己的烧写工具

改造MfgTool

在上一小节中我们已经实现了将自己的系统烧写到开发板中,但是使用的是“借鸡生蛋”的方法。我们通过将NXP 官方的系统更换成我们自己制作的系统来完成系统烧写,本节我们就来学习一下如何将MfgTool 这个工具改造成我们自己的工具,让其支持我们自己的开发板。要改造MfgTool,重点是三方面:

  • ①、针对不同的核心版,确定系统文件相关名字。
  • ②、新建我们自己的.vbs 文件。
  • ③、修改ucl2.xml 文件。

1、确定系统文件名字

确定系统文件名字完全是为了兼容不同的产品,比如某个产品有NAND 和EMMC 两个版本,那么EMMC 和NAND 这两个版本的uboot、zImage、.dtb 和rootfs 有可能不同。为了在MfgTool 工具中同时支持EMMC 和NAND 这两个版本的核心板,EMMC 版本的系统文件命名如图39.5.1.1 所示:
在这里插入图片描述
2、新建.vbs 文件

直接复制mfgtool2-yocto-mx-evk-emmc.vbs 文件即可,将新复制的文件重命名为mfgtool2-alientek-alpha-emmc.vbs,文件内容不要做任何修改,.vbs 文件我们就新建好了。

3、修改ucl2.xml 文件

在修改ucl2.xml 文件之前,先保存一份原始的ucl2.xml。将ucl2.xml 文件改为如下所示内容:

<!-- 正点原子修改后的ucl2.xml文件-->
<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>
<!-- 向EMMC烧写系统-->
<LIST name="eMMC" desc="Choose eMMC as media">
<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-alientek-emmc.imx" ifdev="MX6ULL">Loading U-boot</CMD>
<CMD state="BootStrap" type="load" file="firmware/zImage-alientek-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/imx6ull-alientek-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>
<!-- 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>
<!-- 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>
<!-- 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-alientek-emmc.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>
<!-- 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"/>
<!-- burn zImage -->
<CMD state="Updater" type="push" body="send" file="files/zImage-alientek-emmc">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/imx6ull-alientek-emmc.dtb" ifdev="MX6ULL">Sending Device Tree file</CMD>
<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/imx6ull-alientek-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>
<!-- 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-alientek-emmc.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="$ umount /mnt/mmcblk%mmc%p2">Unmounting rootfs partition</CMD>
<CMD state="Updater" type="push" body="$ echo Update Complete!">Done</CMD>
</LIST>
</UCL>

烧写测试

MfgTool 工具修改好以后就可以进行烧写测试了,将imx6ull-alientek-emmc.dtb、u-boot-alientek-emmc.imx 和zImage-alientek-emmc 这三个文件复制到mfgtools-with-rootfs/mfgtools/Profiles/Linux/OS Firmware/firmware 目录中。
将imx6ull-alientek-emmc.dtb、u-boot-alientek-emmc.imx、zImage-alientek-emmc 和rootfs-alientek-emmc.tar.bz2 这四个文件复制到
mfgtools-with-rootfs/mfgtools/Profiles/Linux/OS Firmware/files 目录中(相当于删除了其他无关的内容,只保留了4个有用的文件)。

在这里插入图片描述

点击“mfgtool2-alientek-alpha-emmc.vbs”打开MfgTool 烧写系统,等待烧写完成,然后设置拨码开关为EMMC 启动,重启开发板,系统启动信息如图39.5.2.1 所示:
在这里插入图片描述
从图39.5.2.1 可以看出,出现“Starting kernel …”以后就再也没有任何信息输出了,说明Linux 内核启动失败了。接下来就是解决为何Linux 内核启动失败这个问题。

解决Linux 内核启动失败

上一小节启动Linux 的时候出问题了,仔细观察uboot 输出的log 信息,会发现如图39.5.3.1 所示两行信息:
在这里插入图片描述
从图39.5.3.1 可以看出,在读取“imx6ull-14x14-evk.dtb”这个设备树文件的时候出错了。

重启uboot,进入到命令行模式,输入如下命令查看EMMC 的分区1 里面有没有设备树文件:

mmc dev 1 //切换到EMMC
ls mmc 1:1 //输出EMMC1 分区1 中的所有文件

结果如图39.5.3.2 所示:
在这里插入图片描述
从图39.5.3.2 可以看出,此时EMMC 的分区1 中是存在设备树文件的,只是文件名字为:imx6ull-alientek-emmc.dtb,因此读取imx6ull-14x14-evk.dtb 肯定会出错的,因为根本就不存在这个文件。之所以出现这个错误的原因是因为uboot 里面默认的设备树名字就是imx6ull-14x14-evk.dtb,这个我们在讲解uboot 的时候就已经说过了。解决方法很简单,有两种方法:

方法一:重新设置bootcmd 环境变量值

进入uboot 的命令行,重新设置bootcmd 和bootargs 这两个环境变量的值,这里要注意的是bootargs 的值也要重新设置一下,命令如下:

setenv bootcmd 'mmc dev 1;fatload mmc 1:1 80800000 zImage;fatload mmc 1:1 83000000 imx6ull-alientek-emmc.dtb;bootz 80800000 - 83000000'
setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
saveenv

设置好bootcmd 和bootargs 这两个环境变量以后重启开发板,Linux 系统就可以正常启动。

方法二:修改uboot 源码

第1 种方法每次重新烧写系统以后都要先手动设置一下bootcmd 的值,这样有点麻烦,有没有一劳永逸的方法呢?肯定是有的,就是直接修改uboot 源码。打开uboot 源码中的文件include/configs/mx6ull_alientek_emmc.h,在宏CONFIG_EXTRA_ENV_SETTINGS 中找到如下所示内容:

194 "findfdt="\
195 	"if test $fdt_file = undefined; then " \
196 		"if test $board_name = EVK && test $board_rev = 9X9; then " \
197				 "setenv fdt_file imx6ull-9x9-evk.dtb; fi; " \
198			 "if test $board_name = EVK && test $board_rev = 14X14; then " \
199				 "setenv fdt_file imx6ull-14x14-evk.dtb; fi; " \
200 		 "if test $fdt_file = undefined; then " \
201				 "echo WARNING: Could not determine dtb to use; fi; " \
202			 "fi;\0" \

findfdt 就是用于确定设备树文件名字的环境变量,fdt_file 环境变量保存着设备树文件名。

第196 行和197 行用于判断设备树文件名字是否为imx6ull-9x9-evk.dtb,第198 行和199 行用于判断设备树文件名字是否为imx6ull-14x14-evk.dtb。这两个设备树都是NXP 官方开发板使用的,I.MX6U-ALPHA 开发板用不到,因此直接将示例代码39.5.3.1 中findfdt 的值改为如下内容:

194 "findfdt="\
195 "if test $fdt_file = undefined; then " \
196 "setenv fdt_file imx6ull-alientek-emmc.dtb; " \
197 "fi;\0" \

第196 行,如果fdt_file 未定义的话,直接设置fdt_file= imx6ull-alientek-emmc.dtb,简单直接,不需要任何的判断语句。修改以后重新编译uboot,然后用将新的uboot 烧写到开发板中,烧写完成以后重启测试,Linux 内核启动正常。

总结

关于系统烧写就讲解到这里,本章我们使用NXP 提供的MfgTool 工具通过USB OTG 口向开发板的EMMC 中烧写uboot、Linux kernel、.dtb(设备树)和rootfs 这四个文件。在本章我们主要做了五个工作:

①、理解MfgTool 工具的工作原理。
②、使用MfgTool 工具将NXP 官方系统烧写到I.MX6U-ALPHA 开发板中,主要是为了体
验一下MfgTool 软件的工作流程以及烧写方法。
③、使用MfgTool 工具将我们自己编译出来的系统烧写到I.MX6U-ALPHA 开发板中。
④、修改MfgTool 工具,使其支持我们所使用的硬件平台。
⑤、修改相应的错误。

关于系统烧写的方法就讲解到这里,本章内容不仅仅是为了讲解如何向I.MX6ULL 芯片中烧写系统,更重要的是向大家详细的讲解了MfgTool 的工作原理。如果大家在后续的工作或学习中使用I.MX7 或者I.MX8 等芯片,本章同样适用。

随着本章的结束,本书第三篇的内容也正式结束了,第三篇是系统移植篇,重点就是uboot、Linux kernel 和rootfs 的移植,看似简简单单的“移植”两个字,引出的却是一篇300 多页的“爱恨情仇”。授人以鱼不如授人以渔,本可以简简单单的教大家修改哪些文件、添加哪些内容,怎么去编译,然后得到哪些文件。但是这样只能看到表象,并不能深入的了解其原理,为了让大家能够详细的了解整个流程,笔者义无反顾的选择了这条最难走的路,不管是uboot 还是Linux kernel,从Makefile 到启动流程,都尽自己最大的努力去阐述清楚。奈何,笔者水平有限,还是有很多的细节没有处理好,大家有疑问的地方可以一起讨论学习。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

系统烧写方法(MfgTool烧写工具) 的相关文章

  • 通过 SSH 将变量传递给远程脚本

    我正在通过 SSH 从本地服务器在远程服务器上运行脚本 首先使用 SCP 复制该脚本 然后在传递一些参数时调用该脚本 如下所示 scp path to script server example org another path ssh s
  • UDP 广播发送失败:在 Linux 2.6.30 上“网络无法访问”

    我用udp广播写了一个程序 代码段如下 struct sockaddr in broadcast addr socklen t sock len sizeof broadcast addr bzero broadcast addr sock
  • grails 上的同步块在 Windows 上有效,但在 Linux 上无效

    我有一个 grails 应用程序 它依赖于服务中的同步块 当我在 Windows 上运行它时 同步按预期工作 但当我在 ams linux 上运行时 会出现 StaleObjectStateException 该问题在以下示例中重现 cla
  • Bash 脚本 - 迭代 find 的输出

    我有一个 bash 脚本 其中需要迭代 find 命令输出的每一行 但似乎我正在迭代 find 命令中的每个单词 以空格分隔 到目前为止我的脚本看起来像这样 folders find maxdepth 1 type d for i in f
  • 在 shell 脚本中查找和替换

    是否可以使用 shell 在文件中搜索然后替换值 当我安装服务时 我希望能够在配置文件中搜索变量 然后在该值中替换 插入我自己的设置 当然 您可以使用 sed 或 awk 来完成此操作 sed 示例 sed i s Andrew James
  • 如何通过代理将套接字连接到http服务器?

    最近 我使用 C 语言编写了一个程序 用于连接到本地运行的 HTTP 服务器 从而向该服务器发出请求 这对我来说效果很好 之后 我尝试使用相同的代码连接到网络上的另一台服务器 例如 www google com 但我无法连接并从网络中的代理
  • 具有少量父设备属性的 udev 规则

    我需要复杂且通用的udev规则来确定插入任何 USB 集线器的特定端口的 USB 设备 所以 我必须结合设备树不同层的父属性 我有这个 udevadm info query all name dev ttyUSB0 attribute wa
  • 如何在 Linux 主机上的 docker 容器中挂载目录 [重复]

    这个问题在这里已经有答案了 我想将一个目录从 docker 容器挂载到本地文件系统 该目录是网站根目录 我需要能够使用任何编辑器在本地计算机上编辑它 我知道我可以跑docker run v local path container path
  • 如何成功使用RDAP协议代替whois

    我对新的 RDAP 协议有点困惑 也不知道何时进一步追求它有意义 在我看来 每个人都同意它是 whois 的继承者 但他们的数据库似乎是空的 在 ubuntu 上我尝试了 rdapper nicinfo 甚至他们的 RESTful API
  • 怎样才能使 Windows 成为一个开箱即用的 POSIX 兼容操作系统?

    这个问题的动机是我的一个牵强的梦想 即 nix 平台上可用的许多优秀软件可以轻松移植到 Windows 微软最近对开源和开放性采取了不同的方法 所以我真的很想知道如果微软有这样的倾向 这样的事情会有多可行 我很好奇的一些更具体的事情是 是否
  • gethostbyname() 或 getnameinfo() 如何在后台工作?

    How gethostbyname or getnameinfo 在后台工作 include
  • 如何让 clangd 转向 c++20

    当没有其他信息时 如何让 clangd 回退到 c 20 例如 在第一次构建之前 cmake 可以生成一个 这是在带有最新 LLVM 的 Arch Linux 上 这是通过 Emacs LSP 运行的 但这应该没有什么区别 你可以加 Com
  • git在Windows和Linux之间切换后强制刷新索引

    我有一个Windows和Linux共享的磁盘分区 格式 NTFS 它包含一个 git 存储库 约 6 7 GB 如果我只使用Windows or 只使用Linux操作 git 存储库一切正常 但是每次切换系统的时候git status命令将
  • 无法执行'x86_64-conda_cos6-linux-gnu-gcc':没有这样的文件或目录(pysam安装)

    我正在尝试安装 pysam 执行后 python path to pysam master setup py build 这个错误的产生是 unable to execute x86 64 conda cos6 linux gnu gcc
  • 为 Qt 应用程序创建 Linux 安装

    我刚刚用 Qt Creator 制作了一个很棒的程序 我对自己很满意 如何将其从台式机移至笔记本电脑 那么 最好的方法是安装程序 对吗 对于 Ubuntu 这是一个 Debian 软件包 对吗 我怎么做 有人这样做过吗 他们可以分享 QT
  • 如何以编程方式从Linux中的进程名称获取进程ID

    在我的项目中 我们使用 ACE 自适应通信环境 中间件来编写可在 Windows 和 Linux 上运行的独立于操作系统的代码 要求是从进程名称中获取进程 ID 由于 ACE 不支持这一点 因此我们必须使用特定于平台的宏来分离 Window
  • 如何让“grep”从文件中读取模式?

    假设有一个很大的文本文件 我只想打印与某些模式不匹配的行 显然 我可以使用egrep v patter1 pattern2 pattern3 现在 如果所有这些模式都在一个文本文件中怎么办 最好的制作方法是什么egrep从文件中读取模式 g
  • Bash 方法的返回值总是模 256

    我有一个 bash 脚本方法 它返回输入值 然而 返回值始终是模 256 的值 我用 google 搜索了一段时间 发现this http www tldp org LDP abs html exitcodes html文章说它总是以 25
  • 适用于 KDE 和 Gnome 的 Gui [重复]

    这个问题在这里已经有答案了 我想为一个现在是 CLI 的应用程序编写一个 gui 它需要在 KDE 和 Gnome DE 中 看起来不错 充分利用用户的外观设置 如果我选择 Qt 或 GTK 我能够做到这一点吗 它们与两个 DE 集成良好吗
  • 无需 cron 在后台发送邮件

    我想知道是否有一种方法可以运行 PHP 循环 以便在后台向订阅者发送几百封电子邮件 我的目标是格式化新闻通讯 单击发送 然后关闭浏览器或更改页面 当然 发送电子邮件的实际过程将在后台运行 不会因浏览器关闭而中断 我知道这可以通过 cron

随机推荐

  • 简单介绍 os.path 模块常用方法

    来源 Python之禅 os path 在python中也算是一个常用的模块 特别是和文件系统打交道时 涉及到文件 目录操作经常会用到 你去看一些框架的源代码的时候也经常会使用到这些方法 如果去看官方文档 os path 大概提供了近20个
  • Android使用Thread.UncaughtExceptionHandler捕获/分析异常信息

    Thread中提供了一个UncaughtExceptionHandler接口能够获取应用的crash信息 该方法设置系统的默认异常处理器 发生crash的时候 系统就会回调UncaughtExceptionHandler的uncaughtE
  • pycharm翻译插件失效解决方法

    pycharm翻译插件失效解决方法 习惯用pycharm写程序的应该都知道一个翻译插件 Translation 可是最近发现翻译用不了了 我就开始着手探究解决这个问题 原因 经过四处打寻 判定谷歌2022年9月26日左右停止了在中国地区的谷
  • Docker修改,保存与新建

    https zhuanlan zhihu com p 57311853 https www runoob com w3cnote docker use container create image html
  • ES6迭代器、Set、Map集合和async异步函数

    目录 迭代器 Iterator 的作用 Iterator 的遍历过程 Set Map集合 map和对象区别 async异步函数 迭代器 迭代器 Iterator 就是这样一种机制 它是一种接口 为各种不同的数据结构提供统一的访问机制 任何数
  • nginx设置成服务并开机自动启动

    在 etc init d下创建文件nginx vim etc init d nginx 其内容参考nginx官方文档 需要注意的配置 nginx usr local nginx sbin nginx 修改成nginx执行程序的路径 NGIN
  • python求解一阶线性偏微分方程通解举例

    python求解一阶线性偏微分方程的通解举例 Python求解偏微分方程也是其一个应用方面 下面举例说明 一 问题 求一阶线性偏微分方程 x f x
  • C#处理JSON

    C 中总共有两种方式处理JSON 第一种 右击项目 gt 添加 gt 引用 这里重点介绍第二种方式 第二种 使用NuGet包 对没错 是Json Net 需要引入的命名空间是 这种方式直接使用工具 不需要进行new 生成JSON文件 对于序
  • Flutter保存和加密数据

    你有没有想过它是如何在手机上处理数据的 让我们一起加密任何文件或模型 我们将要做的 首先 我们谈论使用Flutter的加密 接下来 我们将创建一个文件管理器来保存数据 稍后做加密和解密pdf文件 最后 使用您自己的模型保存加密的pdf 完成
  • 使用Rational Rose进行用例图和活动图

    ROSE用例 ppt 下载地址 http download csdn net download yhyhelene 2949626 一 基于UML的用例模型实验 1 用例图 用例图描述的是参与者 Actor 所理解的系统功能 用于需求分析阶
  • 光立方软件部分

    单片机选用 STC12C5A60S2 x1 数据锁存器 74HC573 x8 简介https blog csdn net qq 43033547 article details 88910276 达林顿晶体管阵列 ULN2803 x1 简介
  • 智能交通的深度学习综述-基于图卷积神网络

    文章目录 Abstract and Introduction Related Work Problems Research directions Challenges Problems formulation and Graph const
  • 课时 17 自测题

    以下说法错误的是 单选题 A etcd 适合存储频繁变化的数据 B etcd 使用 go 语言编写 C etcd 是一个分布式系统 通常由多个 server 组成一个集群 etcd 满足了 CAP 原理中的哪些特性 单选题 A CA B C
  • vue判断上传的文件是否为xls或xlsx

    isexcel file const isXlS file type application vnd openxmlformats officedocument spreadsheetml sheet file type applicati
  • 河道水库测量用雷达水位计的特点

    雷达水位计是一款高精度且具有水面波动滤波处理的地表水水位测量 雨量监测系统 它采用喇叭天线的设计 降低功耗 宽范围的输入电压 专门设计于适合野外无人值守的野外自动站应用 测量不受大气温度 压力 空气密度 风 降水 相对湿度的影响 具有很高的
  • 【web安全】——XXE漏洞快速入门

    作者名 Demo不是emo 主页面链接 主页传送门创作初心 一切为了她座右铭 不要让时代的悲哀成为你的悲哀专研方向 网络安全 数据结构 每日emo 该怎么开口呢 今晚天气不错 但还是想你了 目录 一 初识XXE漏洞 1 XXE简介 2 XM
  • paintEvent(QPaintEvent *e)函数参数使用问题

    paintEvent QPaintEvent e 函数参数使用问题 自己重载paint Event 函数时是不用使用参数的 但是为了保证系统调用自己写的重载函数必须自己写的重载函数和系统的函数完全一样 所以必须这么写 void XVideo
  • 嵌入式学习手册1-什么是嵌入式

    嵌入式学习手册1 什么是嵌入式 一 嵌入式发展概述 在传统的开发过程中 都是软件直接操控硬件 软件和硬件完全耦合在一起 导致了以下问题 1 软件的移植性差 2 软件开发人员必须懂硬件 开发难度过大 3 软件功能性差 影响用户体验 因为20世
  • 杯子

    杯子 题目描述 小明买了N个容积可以是无穷大的杯子 刚开始的时候每个杯子里有1升水 接着小明发现杯子实在太多了 于是他决定保留不超过K个杯子 每次他选择两个当前含水量相等的杯子 把一个杯子的水全部倒进另一个里 然后把空瓶丢弃 不能丢弃有水的
  • 系统烧写方法(MfgTool烧写工具)

    目录 MfgTool 工具简介 MfgTool 工作原理简介 USB接线 系统烧写原理 烧写NXP 官方系统 烧写自制的系统 系统烧写 网络开机自启动设置 改造我们自己的烧写工具 改造MfgTool 烧写测试 解决Linux 内核启动失败