文章目录
Linux系统移植:系统烧写
摘要:
本章使用 NXP 官方提供的 MfgTool 工具通过 USB OTG 口来烧写系统到设备
可以了解 Mfgtool 下载到开发板的大致原理
基于下载原理的了解,修改下载工具,适合我们自己的开发板进行下载
一、Mfgtool 获取
上 NXP 官网,下载 IMX6ULL 的工具包
下载地址:Mfgtool下载地址,下载后解压如下:
一个带文件系统烧写,一个不带
二、MfgTool 下载原理
2.1 连接开发板,配置下载方式
MfgTool 通过 USB OTG 接口将系统烧写进 EMMC 中的,烧写前先将系统修改成 USB 下载:
配置后通过 USB 连接开发板,显示连接如下:
2.2 执行 VBS 文件
然后进入 L4.1.15_2.0.0-ga_mfg-tools\mfgtools-with-rootfs\mfgtools
文件夹,文件夹下有大量的 .vbs 文件, .vbs 用于配置下载的参数,比如刚刚下载的文件夹下有下面几个 .vbs 文件可以配置不同的下载方式:
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
调用了 mfgtool2.exe 软件,传入参数后进行下载,然后我们以执行 mfgtool2-yocto-mx-evk-emmc.vbs
下载方式为例子,执行后打开程序,出现如下标注,说明连接开发板成功:
之后点击 Start 就会烧写系统,烧写 uboot、Linux kernel、.dtb 和 rootfs 这四个文件!
MfgTool 先通过 USB OTG 先将 uboot、kernel 和.dtb(设备树) 这是三个文件下载到开发板的 DDR 中,注意不需要下载 rootfs。就相当于直接在开发板的 DDR上启动 Linux 系统,等 Linux 系统启动以后再向 EMMC 中烧写完整的系统
在 L4.1.15_2.0.0-ga_mfg-tools/mfgtools-with-rootfs/mfgtools/Profiles/Linux/OS Firmware
目录下有如下文件:
firmware 文件夹有很多的.imx 结尾的 uboot 文件、一个 zImage 镜像文件、很多.dtb 结尾的设备树文件,而 files 目录下和 firmware 基本相同,只不过 firmware 用于下载到 DDR,而 file 用于下载到 EMMC
2.3 ucl2.xml 配置文件
该文件主要是判断当前是给 I.MX 系列的哪个芯片烧写系统,ucl2.xml 以 <UCL>开始,以 </UCL> 结束。<CFG> 和 </CFG> 之间是配置相关内容
通过读取芯片的 VID 和 PID 即可判断出当前要烧写什么处理器的系统,如果 VID=0X15A2, PID=0080,就表示要给 I.MX6ULL 烧写系统
以及配置下载相关的指令,<LIST> 和 </LIST> 之间的是针对不同存储芯片的烧写命令
前面提到下载分为两步,第一步先下载到DDR,启动系统,为后续下载到 EMMC 做准备,相关下载指令如下:
<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" address="0x80800000" loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6SL MX6SX MX7D MX6UL MX6ULL">Loading Kernel.</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>
BootStrap 表示第一下载阶段,file 表示要下载的文件位置,在 L4.1.15_2.0.0-ga_mfg-tools\mfgtools-with-rootfs\mfgtools-with-rootfs\mfgtools
下找到 cfg.ini 文件,该文件里包含了 file 内相关的参数值,比如文件中 lite=l,6uluboot=14x14evk,所以第一个指令 file 的最终值为 u-boot-imx6ull14x14evk _emmc.imx
下载完成后,启动系统
<CMD state="BootStrap" type="jump" > Jumping to OS image. </CMD>
启动后接着在 EMMC 上创建分区,然后烧写 uboot、zImage、.dtb(设备树) 和根文件系统
三、自定义 Mfgtool 烧写系统
上面我们获取了 Mfgtool,也大致了解了他运行下载的基本原理,下面我们修改 Mfgtool
3.1 下载文件准备
- uboot 引导文件:u-boot.imx(由 uboot 源码编译生成)
- zImage 镜像文件:系统内核运行文件(由 Linux 源码编译生成)
- dtb 设备树文件:内核运行需要的设备树(由 Linux 源码编译生成)
- rootfs 根文件系统 :内核正确运行需要的文件系统(由 Busybox 制作后打包)
这里我使用我之前做出来的uboot、文件系统、内核镜像和设备树
将文件放到 L4.1.15_2.0.0-ga_mfg-tools\mfgtools-with-rootfs\mfgtools\Profiles\Linux\OS Firmware、my_file
文件夹下面,my_file 是我们自己新建的文件夹
3.2 新建 VBS
复制 mfgtool2-yocto-mx-evk-emmc.vbs 文件,改成 mfgtool2-my-alpha-emmc.vbs 文件,文件内容如下:
我们不用修改,直接使用这个文件,虽然他传入了一些参数,但后面不使用他,直接硬改 xml 配置文件
3.3 修改ucl2.xml
硬件识别继续使用原来的
<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="BootStrap" dev="MX6ULL" vid="15A2" pid="0080"/>
<STATE name="Updater" dev="MSC" vid="066F" pid="37FF"/>
</CFG>
官方工具的 xml分为几个部分:
我们只要关注其中和 EMMC 相关的就行,修改其中的 ifdev=“MX6ULL” 指令,这个指令和 IMX6ULL 相关,因为下载分为两个阶段,第一个阶段用于在 DDR 上启动系统,第二阶段下载我们的文件系统,第一阶段我们保持不变,使用NXP提供的,将第二阶段文件路径替换成我们自己的就行
第一阶段指令:
<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" address="0x80800000" loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6ULL">Loading Kernel.</CMD>
<CMD state="BootStrap" type="load" file="firmware/%initramfs%" address="0x83800000" loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="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>
第二阶段指令
创建下载环境
<!-- 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/mmcblk1"> Partitioning...</CMD>
下载 uboot,路径换成我们自己的:
<!-- burn uboot -->
<CMD state="Updater" type="push" body="$ dd if=/dev/zero of=/dev/mmcblk1 bs=1k seek=768 conv=fsync count=8">clear u-boot env</CMD>
<CMD state="Updater" type="push" body="$ echo 0 > /sys/block/mmcblk1boot0/force_ro">access boot partition 1</CMD>
<CMD state="Updater" type="push" body="send" file="my_file/u-boot.imx" ifdev="MX6ULL">Sending u-boot.bin</CMD>
<CMD state="Updater" type="push" body="$ dd if=$FILE of=/dev/mmcblk1boot0 bs=512 seek=2">write U-Boot to sd card</CMD>
<CMD state="Updater" type="push" body="$ echo 1 > /sys/block/mmcblk1boot0/force_ro"> re-enable read-only access </CMD>
<CMD state="Updater" type="push" body="$ mmc bootpart enable 1 1 /dev/mmcblk1">enable boot partion 1 to boot</CMD>
格式化,并且挂载内核文件系统分区:
<!-- format and mount boot partition -->
<CMD state="Updater" type="push" body="$ while [ ! -e /dev/mmcblk1p1 ]; do sleep 1; echo \"waiting...\"; done ">Waiting for the partition ready</CMD>
<CMD state="Updater" type="push" body="$ mkfs.vfat -F 32 /dev/mmcblk1p1">Formatting rootfs partition</CMD>
<CMD state="Updater" type="push" body="$ mkdir -p /mnt/mmcblk1p1"/>
<CMD state="Updater" type="push" body="$ mount -t vfat /dev/mmcblk1p1 /mnt/mmcblk1p1"/>
设置下载过程中的 LOGO:
<!-- burn logo -->
<!--<CMD state="Updater" type="push" body="send" file="files/alientek.bmp">Sending Boot Logo</CMD>
<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk1p1/alientek.bmp">write boot logo to sd card</CMD> >
下载 zImage 镜像,换成我们自己的路径
<!-- burn zImage -->
<CMD state="Updater" type="push" body="send" file="my_file/zImage">Sending kernel zImage</CMD>
<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk1p1/zImage">write kernel image to sd card</CMD>
下载设备树,换成我们自己的设备树路径:
<!-- burn dtb -->
<CMD state="Updater" type="push" body="send" file="my_file/imx6ull-my-emmc.dtb" ifdev="MX6ULL">Sending Device Tree file</CMD>
<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk1p1/imx6ull-my-emmc.dtb" ifdev="MX6ULL">write device tree to eMMC card</CMD>
<CMD state="Updater" type="push" body="$ sleep 1">delay</CMD>
<CMD state="Updater" type="push" body="$ sync">Sync...</CMD>
<CMD state="Updater" type="push" body="$ umount /mnt/mmcblk1p1">Unmounting vfat partition</CMD>
格式化并挂载根文件系统分区
<!-- format and mount rootfs partition -->
<CMD state="Updater" type="push" body="$ mkfs.ext3 -F -E nodiscard /dev/mmcblk1p2">Formatting rootfs partition</CMD>
<CMD state="Updater" type="push" body="$ mkdir -p /mnt/mmcblk1p2"/>
<CMD state="Updater" type="push" body="$ mount -t ext3 /dev/mmcblk1p2 /mnt/mmcblk1p2"/>
下载根文件系统,换成我们的根文件系统路径
<!-- burn rootfs -->
<CMD state="Updater" type="push" body="pipe tar -jxv -C /mnt/mmcblk1p2" file="my_file/rootfs.tar.bz2" ifdev="MX6ULL">Sending and writting rootfs</CMD>
<CMD state="Updater" type="push" body="frf">Finishing rootfs write</CMD>
<CMD state="Updater" type="push" body="$ sleep 1">delay</CMD>
<CMD state="Updater" type="push" body="$ sync">Sync...</CMD>
<CMD state="Updater" type="push" body="$ umount /mnt/mmcblk1p2">Unmounting rootfs partition</CMD>
<CMD state="Updater" type="push" body="$ echo Update Complete!">Done</CMD>
修改后保存,执行我们的 VBS 脚本
下载完成如下:
调整 BOOT 拨码开关,启动系统,提示缺少设备树,因为我用的是原子编译的uboot,他的设备树名称不同,我直接在 boot 命令行修改,设置一下设备树,直接启动
setenv fdt_file imx6ull-my-emmc.dtb
boot
系统启动成功: