Skip to content

LV020-mfgtool烧写流程

一、烧写过程分析

我们接下来实例分析一下点击这个 mfgtool2-yocto-mx-evk-emmc.vbs 之后会发生什么。

1. 参数配置

我们看一下这个 mfgtool2-yocto-mx-evk-emmc.vbs 脚本:

vb
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

可以得到这些配置项:

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

name=eMMC

我们结合一下 cfg.ini,我们会得到传入 ucl2.xml 文件的各个参数的值:

ini
[profiles]
chip = Linux

[platform]
board = SabreSD

[LIST]
name = eMMC

[variable]
board = sabresd
mmc = 1
sxuboot=sabresd
sxdtb=sdb
7duboot=sabresd
7ddtb=sdb
6uluboot=14x14evk
6uldtb=14x14-evk
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

2. CFG

首先进入 CFG 标签,开始选择器件,这里正点原子 alpha 开发板使用的是 imx6ull,所以这里 dev 肯定是 "MX6ULL"。

xml
  <CFG>
    <!-- 其他的省略 -->
    <STATE name="BootStrap" dev="MX6ULL" vid="15A2" pid="0080"/>
    <STATE name="Updater"   dev="MSC" vid="066F" pid="37FF"/>
  </CFG>

3. LIST

前面根据最终配置参数,我们的 name = eMMC,所以会选到这个 LIST:

xml
<LIST name="eMMC" desc="Choose eMMC as media">
    <!-- 其他的省略 -->
</LIST>

后面我们只需要关注这个标签里的命令即可。

4. CMD——BootStrap

4.1 BootStrap——uboot

xml
<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-imx6q%plus%%board%_sd.imx" ifdev="MX6Q">Loading U-boot</CMD>
<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-imx6dl%board%_sd.imx" ifdev="MX6D">Loading U-boot</CMD>
<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-imx6sx%board%_emmc.imx" ifdev="MX6SX">Loading U-boot</CMD>
<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-imx7d%7duboot%_sd.imx" ifdev="MX7D">Loading U-boot</CMD>
<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-imx6ul%6uluboot%_emmc.imx" ifdev="MX6UL">Loading U-boot</CMD>
<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-imx6ul%lite%%6uluboot%_emmc.imx" ifdev="MX6ULL">Loading U-boot</CMD>

前面我们知道 dev 是等于 MX6ULL,所以这里只需要关注:

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

%lite%根据前面的配置文件为 l,%6uluboot%为 14x14evk,所以这里展开就是:

xml
<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-imx6ull14x14evk_emmc.imx" ifdev="MX6ULL">Loading U-boot</CMD>

这个时候就使用的是这个文件:

image-20241104232733823

这个时候,mfgtool 就会将这个 imx 文件下载到 DRAM 中。

4.2 BootStarp——kernel

接下来是内核:

xml
<CMD state="BootStrap" type="load" file="firmware/zImage" address="0x12000000" loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6Q MX6D">Loading Kernel.</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>

不管哪一款芯片,内核镜像的名字都是 zimage, 只是下载的位置不同,我们这里是 MX6ULl,所以是这个:

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

使用的就是这个文件:

image-20241104234003124

4.3 BootStrap——Initramfs

xml
<CMD state="BootStrap" type="load" file="firmware/%initramfs%" address="0x12C00000"
	loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6Q MX6D">Loading Initramfs.</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>

这个文件就是启动阶段 linux 系统使用的最小根文件系统,只包含一些简单命令。根据前面的配置文件,这里的%initramfs%是:

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

所以这里展开就是:

xml
<CMD state="BootStrap" type="load" file="firmware/fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot" address="0x83800000" loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6SL MX6SX MX7D MX6UL MX6ULL">Loading Initramfs.</CMD>

就是这个文件:

image-20241104234352843

4.4 BootStrap——device tree

然后就是设备树啦,我们来看一下 :

xml
	<CMD state="BootStrap" type="load" file="firmware/zImage-imx6q%plus%-%board%%ldo%.dtb" address="0x18000000"
		loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6Q">Loading device tree.</CMD>
	<CMD state="BootStrap" type="load" file="firmware/zImage-imx6dl-%board%%ldo%.dtb" address="0x18000000"
		loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6D">Loading device tree.</CMD>
	<CMD state="BootStrap" type="load" file="firmware/zImage-imx6sx-%sxdtb%-emmc.dtb" address="0x83000000"
		loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6SX">Loading device tree.</CMD>
	<CMD state="BootStrap" type="load" file="firmware/zImage-imx7d-%7ddtb%.dtb" address="0x83000000"
		loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX7D">Loading device tree.</CMD>
	<CMD state="BootStrap" type="load" file="firmware/zImage-imx6ul-%6uldtb%-emmc.dtb" address="0x83000000"
		loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6UL">Loading device tree.</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>

我们直接看这个 MX6ULL:

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

根据前面的配置文件,我们得到%lite%= l,%6uldtb%= 14x14-evk,所以这里命令展开就是:

xml
<CMD state="BootStrap" type="load" file="firmware/zImage-imx6ull-14x14-evk-emmc.dtb" address="0x83000000" loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6ULL">Loading device tree.</CMD>

就是这个文件:

image-20241104234816747

4.5 BootStrap——jump

这里就来到了第一阶段的结尾,则是 Jumping to OS image,应该就是去启动这个已经下载到 DRAM 的 Linux 系统,从而进入到系统烧写的第二个阶段,在看第二阶段的代码前,先总结一下第一阶段烧写了哪些固件,基于 i.mx6ul 这款 SoC,下载到 DRAM 的固件如下:

固件 下载文件
uboot firmware/u-boot-imx6ull14x14evk_emmc.imx
kernel firmware/zImage
initramfs firmware/fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot
dtb firmware/zImage-imx6ull-14x14-evk-emmc.dtb

这里结束,我们其实已经在开发板上运行起来了一个 linux 系统,后续第二阶段就是通过这个 linux 系统将相关的 uboot、kernel、dtb、rootfs 等烧写到 eMMC 中去。

5. CMD——Updater

5.1 Updater——create partition

一开始先创建分区:

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

我们看一下这个 mksdcard.sh.tar 文件里面是什么:

image-20241105000348103

我们打开这个脚本看一眼:

shell
#!/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

我们再来看一下%mmc%,根据前面的配置,这个值应该是 1,所以最后一个命令就是:

xml
<CMD state="Updater" type="push" body="$ sh mksdcard.sh /dev/mmcblk1"> Partitioning...</CMD>

可以看到是通过 mksdcard.sh 使用 sfdisk 工具对/dev/mmcblk1 进行分区。脚本的命令解析一下就是:

shell
node=/dev/mmcblk1
BOOT_ROM_SIZE=10
# 所以有
dd if=/dev/zero of=/dev/mmcblk1 bs=1024 count=1

sfdisk --force /dev/mmcblk1 << EOF
10M,500M,0c
600M,,83
EOF

5.2 Updater——burn uboot

我们来看一下这几条 CMD.

  • clear u-boot arg
xml
<!-- 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>

首先是清空要烧写 uboot 的区域,我们前面知道%mmc%= 1,所以这里就是:

xml
<CMD state="Updater" type="push" body="$ dd if=/dev/zero of=/dev/mmcblk1 bs=1k seek=768 conv=fsync count=8">clear u-boot arg</CMD>
  • access boot partition and send
xml
<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-imx6ul%lite%%6uluboot%_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>

这里这几个变量是:

ini
%mmc%=1
%lite%=l
%6uluboot%=14x14evk

变量的值替换后就是:

xml
<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="files/u-boot-imx6ull14x14evk_emmc.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>

这里的过程是先发送,再写入,发送的时候是这个目录的文件:

image-20241105065317996

这里要先了解一些 eMMC 的分区,在 eMMC 器件里有两种存储器,SRAM(静态随机访问存储器)和 NAND 闪存。SRAM 是位于控制器 ASIC 里面为了数据暂时保存以及被控制器微处理器快速访问的易失性存储器。NAND 阵列是由一个或者多个晶片组成的非易失性存储器,大概的框图如下:

eMMC深入浅出 第二章 eMMC结构 第二节 分区以及存储区域

mmcblk1boot0 其实就代表 eMMC 的 Boot Area Partitions(Boot Area 包含两个 Boot Area Partitions),一般是拿来存储 Bootloader,支持 SOC 从 eMMC 启动系统。详细的就不再说了,以后学习的时候再详细了解。

5.3 Updater——create fat partition

创建一个 fat 分区:

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

这里吧%mmc%= 1 替换一下就是:

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

这里先格式化分区,然后用 mount 命令挂载。

5.4 Updater——burn zImage

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

这里就是烧写 zImage 文件,这里替换一下变量值就是:

xml
<!-- 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/mmcblk1p1/zImage">write kernel image to sd card</CMD>

就是把 zimage 烧写到 mmcblk1p1 这个分区中。这里会先发送然后再拷贝,使用的文件是这个:

image-20241105065429877

5.5 Updater——burn dtb

接下来是烧写设备树文件,这里只看 MX6ULL 的两行命令

xml
<CMD state="Updater" type="push" body="send" file="files/zImage-imx6ul%lite%-%6uldtb%-emmc.dtb" ifdev="MX6ULL">Sending Device Tree file</CMD>

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

变量值为:

ini
mmc = 1
6uluboot=14x14evk
6uldtb=14x14-evk
6ulldtb=14x14-ddr3-arm2

替换后如下所示:

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

<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk1p1/imx6ull-14x14-evk.dtb" ifdev="MX6ULL">write device tree to sd card</CMD>

这里有点奇怪,就是执行 cp 命令复制过程中把 zImage-imx6ull-14x14-evk-emmc.dtb 后面的-emmc 去掉了,可能是内核中设备树名字的问题,反正这里知道是复制设备树到对应文件中就是了。

5.6 Updater——burn m4 demo bins

这个看起来是烧写一些 demo 文件:

xml
<!-- burn m4 demo bins-->
<CMD state="Updater" type="push" body="send" file="files/imx7d_sabresd_m4_TCM_helloworld.bin" ifdev="MX7D">Sending helloworld demo</CMD>
<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/imx7d_sabresd_m4_TCM_helloworld.bin" ifdev="MX7D">write demo image to eMMC</CMD>
<CMD state="Updater" type="push" body="send" file="files/imx7d_sabresd_m4_TCM_mcctty.bin" ifdev="MX7D">Sending mcctty demo</CMD>
<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/imx7d_sabresd_m4_TCM_mcctty.bin" ifdev="MX7D">write demo image to eMMC</CMD>
<CMD state="Updater" type="push" body="send" file="files/imx7d_sabresd_m4_TCM_Pingpang.bin" ifdev="MX7D">Sending pingpong demo</CMD>
<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/imx7d_sabresd_m4_TCM_Pingpang.bin" ifdev="MX7D">write demo image to eMMC</CMD>

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

不过其实这里是 MX7D 才有,MX6ULL 没有,这里就不用管了。这里烧写完后面把 mmcblk1p1 卸载。

5.7 Updater——burn rootfs

接下来是烧写根文件系统:

xml
<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.tar.bz2" ifdev="MX6SL MX6D MX6Q MX6SX">Sending and writting rootfs</CMD>
<CMD state="Updater" type="push" body="pipe tar -jxv -C /mnt/mmcblk%mmc%p2" file="files/rootfs_nogpu.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>

我们根据配置文件对变量进行替换:

xml
<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"/>
<CMD state="Updater" type="push" body="pipe tar -jxv -C /mnt/mmcblk1p2" file="files/rootfs.tar.bz2" ifdev="MX6SL MX6D MX6Q MX6SX">Sending and writting rootfs</CMD>
<CMD state="Updater" type="push" body="pipe tar -jxv -C /mnt/mmcblk1p2" file="files/rootfs_nogpu.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/mmcblk1p2">Unmounting rootfs partition</CMD>
<CMD state="Updater" type="push" body="$ echo Update Complete!">Done</CMD>

一开始也是格式化了一个分区/dev/mmcblk1p2,然后对其进行挂载:

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

接下来是发送和写入根文件系统:

xml
<CMD state="Updater" type="push" body="pipe tar -jxv -C /mnt/mmcblk1p2" file="files/rootfs.tar.bz2" ifdev="MX6SL MX6D MX6Q MX6SX">Sending and writting rootfs</CMD>
<CMD state="Updater" type="push" body="pipe tar -jxv -C /mnt/mmcblk1p2" file="files/rootfs_nogpu.tar.bz2" ifdev="MX6UL MX7D MX6ULL">Sending and writting rootfs</CMD>
<CMD state="Updater" type="push" body="frf">Finishing rootfs write</CMD>

这里这个 pipe tar 命令有点没看懂,网上搜了下也没见这么用的,我猜测是 pipe 是管道,这个命令直接把根文件系统解压后写入 mmcblk1p2 这个分区,这里我们使用的是 MX6ULL,所以这里根文件系统是 ootfs_nogpu.tar.bz2:

image-20241105071304417

这个根文件系统包不包含 rootfs 这一级目录?解压后直接是根文件系统?我们解压看一下,为防止一堆文件出现,我们先创建一个目录:

shell
cd /d/devSoftware/L4.1.15_2.0.0-ga_mfg-tools/mfgtools-with-rootfs/mfgtools/Profiles/Linux/OS\ Firmware/files
mkdir temp
cp rootfs_nogpu.tar.bz2 temp/
cd temp
tar xf rootfs_nogpu.tar.bz2

这里需要注意,由于是 linux 根文件系统,这里会存储在大量的软链接,而 windows 下是没有软链接的概念的,所以这些文件解压时会报错,不用管,我们只是看看顶层目录长啥样而已。然后我们看一下这个目录:

image-20241105071750420

会发现直接就是根文件系统了,所以我么打包的时候也要注意,要保证解压出来的文件不在压缩包名的子目录中。到这里,烧写的第二阶段就结束了,之后就可以将拨码开关拨到 eMMC 启动,就可以启动系统了。

5.8 Updater——总结

第二阶段烧写了哪些文件?

固件 下载文件
uboot files/u-boot-imx6ull14x14evk_emmc.imx
kernel files/zImage
dtb files/zImage-imx6ull-14x14-evk-emmc.dtb
rootfs files/rootfs_nogpu.tar.bz2

二、NXP 官方系统烧写

正点原子的 alpha 开发板是参考按照 nxp imx6ul evk 评估板设计的,所以其实是可以直接烧写 nxp 官方镜像的,就是可能会有一些问题,但是并不影响启动。

1. 系统烧写到 EMMC

我们先来体验一下将 NXP 官方的镜像烧写到正点原子的开发板中,简单了解一下烧写过程。正点原子的 EMMC 核心版用的也是 512MB 的 DDR3 加 8G 的 EMMC,因此烧写 NXP 官方的系统是没有任何问题的。基本步骤如下:

  • (1)连接好 USB,拨码开关拨到 USB 下载模式。

  • (2)弹出 TF 卡,然后按下开发板复位按键,后续将系统烧写到 EMMC 中去,所以不需要 TF 卡。

  • (3)打开 MobaXterm,连接开发板,注意,此时需要两根 USB 线,一个连接在 USB OTG,用于烧写程序,另一个连接在串口,用于显示开发板串口的打印信息。

image-20230714181213952
  • (4)双击“mfgtool2-yocto-mx-evk-emmc.vbs”,打开下载软件,如果出现【符合 HID 标准的供应商定义设备】等字样就说明下载软件已经准备就绪。
image-20230714181753981
  • (5)点击【Start】按钮开发烧写 NXP 官方系统,在 uboot 烧写完成并启动后,串口就会有打印信息输出。烧写过程如图所示:
image-20230714181855110

然后我们可以在 MobaXterm 中看到当前的烧写过程,过程很漫长(主要是烧写根文件系统有大量的文件要拷贝,就很慢),这里就截取了一部分。

image-20230714182112631
  • (6)烧写完成状态如下图所示:
image-20221023145536704
  • (7)然后我们点击【Stop】,最后点击【Exit】退出即可。

2. 重启测试

上边烧写完毕后,我们拔出 USB 线,将开发板上的拨码开关拨到 EMMC 启动模式(1010 0110),然后重启开发板,此时就会从 EMMC 启动。只是启动以后的系统是 NXP 官方给 I.MX6ULL EVK 开发板制作的,这个系统需要输入用户名,用户名为“root”,没有密码,如下图:

image-20230714183618441

在“imx6ul7d login:”后面输入“root”用户名,然后点击回车键即可进入系统中,进入系统以后就可以进行其他操作了。由此可以看出,NXP 官方的系统其实是可以在正点原子的 EMMC 版核心板上运行的 。 正常来讲,若是有显示屏,则也会有一些显示信息,但是可能不清楚,并且位置也不是很对:

image-20230714183832269

参考资料

技术分享-NXP MFGTool 软件烧录原理 - 飞凌嵌入式行业资讯 - 保定飞凌嵌入式技术有限公司 (forlinx.com)

doc.embedfire.com/linux/imx6/base/zh/latest/building_image/burning_NXP_firmware.HTML