一 应用场景描述:
全新的板子,主要是全新的eMMC。需要通过USB DFU,把uboot,kernel,rootfs等烧录到eMMC,然后由eMMC启动至系统。
二 版本及环境:
1 SDK版本:
ti-processor-sdk-linux-am62xx-evm-09.00.00.03-Linux-x86-Install.bin。也就是SDK-09的版本。
2 Windows的DFU支持。
1)DFU的usb驱动安装。
Zadig - USB driver installation made easy (akeo.ie)
下载zadig工具,安装驱动。将板子设置成USB DFU模式,上电,windows即可识别DFU 设备。
2)dfu-util工具。此文档调试,使用的是dfu-util-0.11版本的。
三 文件的准备。
1 编译支持DFU的uboot。(很关键的步骤)
安装的sdk09版本里的uboot,就可以支持DFU模式。
另外,sdk08版本的uboot,也就是uboot2021的版本,是需要打补丁的。也就是部分文件需要修改才能支持DFU功能。
但是sdk09的版本,也就是uboot2023的版本,是不需要打补丁修改文件的。
编译uboot的时候,需要使用am62x_evm_r5_usbdfu_defconfig这个配置。
修改Rules.make里的。
另外,还可以参考文档里的
3.5.3. Flash via USB Device Firmware Upgrade (DFU)
Override the bootcmd command to receive the environment variable text file after DFU boot. Following change needs to be done
CONFIG_BOOTCOMMAND="setenv dfu_alt_info_flashenv uEnv.txt ram 0x82000000 0x10000000; setenv dfu_alt_info ${dfu_alt_info_flashenv}; dfu 0 ram 0; env import -t ${loadaddr} $filesize; run user_commands;"
Add above line to am62x_evm_a53_defconfig file
修改这个BOOTCMDMAND之后呢,DFU把uboot刷到芯片后,uboot启动后,就自动进入cmd模式,不需要手动敲回车进入命令模式。
而且,自动进入命令行模式之后,可以通过dfu把用户自定义的命令传进入执行。也就是.\dfu-util\dfu-util.exe -R -a uEnv.txt -D .\uEnv.txt --device ,0451:* 这个命令。
DFU的uboot用到这四个文件。
其中,
uEnv.txt的内容为:user_commands=echo Flashing_on_eMMC; setenv dfu_alt_info ${dfu_alt_info_emmc}; dfu 0 mmc 0;
其它三个文件为支持DFU的uboot文件。这三个文件是准备通过USB DFU下载到芯片,在芯片内存上运行的,并不是要烧录到eMMC里的。
2 待烧录至eMMC的文件。
其中,tiboo3.bin, tispl.bin, u-boot.img 就是正常的uboot文件,正常编译的,或者sdk预编译自带的。
ti_rootfs.ext4是一个包含了内核和文件系统的包。
sdk09里自带有文件系统包。我们可以用这个文件系统包制作ext4包。
这里参考了这个文档:
FAQ] SK-AM62: How to flash eMMC using USB DFU on AM62x-SK E2
不过有些出入。
$ cd <path-ti-psdk>/filesystem
$ dd if=/dev/null of=tisdk-base.ext4 bs=1M seek=512
$ mkfs.ext4 -F tisdk-base.ext4
$ mkdir mnt_fs
$ sudo mount -t ext4 tisdk-base.ext4 mnt_fs
$ cd mnt_fs
$ sudo tar xvf ../tisdk-base-image-am62xx-evm.tar.xz
$ cd ..
$ sudo umount mnt_fs
我这里改成了512M,因为用300的时候,解压出来提示空间不够,最后文件系统起不来。改成512M是可以的。这里要注意一下。
四 实际调试。
环境和文件准备好了,重要的就是实际调试了。
1 将板子设置成DFU模式,在windows 电脑这边识别成DFU模式。
2 将板子的调试串口接到电脑上,方便查看和输入命令交互。
3 开始DFU 操作。这里分两步:
1) 先把支持DFU的uboot 刷到板子上,让板子可以二次进入DFU模式。
E:\TI_AM62X\DFU_flash\dfu-util\dfu-util.exe -R -a 0 -D tiboot3.bin
E:\TI_AM62X\DFU_flash\dfu-util\dfu-util.exe -R -a 0 -D tispl.bin
E:\TI_AM62X\DFU_flash\dfu-util\dfu-util.exe -R -a 1 -D u-boot.img
到这里就自动进入命令模式了,并且当前状态是等待用户传入新的命令。
..\dfu-util\dfu-util.exe -R -a uEnv.txt -D .\uEnv.txt --device ,0451:*
这个步骤和下面的操作是等价的。
当然,如果你首次调试,可能得不到上面的画面,你得到的是这样的:
如果到不了这一步,可能eMMC没有识别,或者eMMC没有格式化。
先确保mmc list 能识别出来eMMC。那可能就是全新的eMMC,需要格式化了。
在uboot命令里执行
setenv uuid_gpt_disk 8f8c2a63-82d2-4693-95e2-fb4d6479aad2
setenv uuid_gpt_rootfs e14aea3b-1f60-447e-b0df-37a749a387e9
setenv partitions " uuid_disk=${uuid_gpt_disk};name=rootfs,start=2MiB,size=-,uuid=${uuid_gpt_rootfs}"
gpt write mmc 0 ${partitions}
(8f8c2a63-82d2-4693-95e2-fb4d6479aad2,e14aea3b-1f60-447e-b0df-37a749a387e9这两个数据,是在电脑用uuidgen来生成的。)
再看mmc part
好了,到这一步,我建议你从头再开始。
好了,假装你已经重新再来了,最后执行了dfu 0 mmc 0 成功了。
这时候就可以执行eMMC的烧录了。
2) 开始进入eMMC烧录。
在sdk09的安装包里,有个bin目录,有个DFU_FLASH目录,里面有个u-boot_flashwriter.sh 脚本。
解读之后,发现其实是可以在windows操作的。
我们要烧录的文件也就这四个。
整理出来之后,就四个命令:
..\dfu-util\dfu-util.exe -a tiboot3.bin.raw -D E:\TI_AM62X\sd_uboot\tiboot3.bin --device ,0451:*
..\dfu-util\dfu-util.exe -a tispl.bin.raw -D E:\TI_AM62X\sd_uboot\tispl.bin --device ,0451:*
..\dfu-util\dfu-util.exe -a u-boot.img.raw -D E:\TI_AM62X\sd_uboot\u-boot.img --device ,0451:*
..\dfu-util\dfu-util.exe -R -a rootfs -D E:\TI_AM62X\sd_uboot\ti_rootfs.ext4 --device ,0451:*
在这一步,基本上就可以认为是烧录正常了。
好了,到这一步,我们先看看能不能从eMMC启动,还遇到啥情况。
断电。休息一下。
五 eMMC的启动。
烧录好了,接下来就是验证看看eMMC的启动了。
这里,要将芯片设置成eMMC的启动。这一步很关键。
B6~B3: 1001b。 引脚设置为eMMC Boot。注意,不要选using UDA。
可以看到已经可以从eMMC启动uboot了。
但是没有看到kernel和文件系统起来。这是怎么回事呢。
还是这个文档:
最后提到:
To boot kernel from eMMC, use the following commands after writing rootfs to user partition:
- setenv mmcdev 0
- setenv bootpart 0
- boot
The board should now boot from eMMC with the updated files.
原来还不能默认启动内核和文件系统呀。
还需要在uboot下面执行这两个命令。
好,我们再来一次,重新上电,进入uboot的命令模式:
=> setenv mmcdev 0
=> setenv bootpart 0
=> boot
switch to partitions #0, OK
mmc0(part 0) is current device
SD/MMC found on device 0
Failed to load 'boot.scr'
Can't set block device
## Error: "main_cpsw0_qsgmii_phyinit" not defined
20593152 bytes read in 126 ms (155.9 MiB/s)
57500 bytes read in 15 ms (3.7 MiB/s)
Working FDT set to 88000000
## Flattened Device Tree blob at 88000000
Booting using the fdt blob at 0x88000000
Working FDT set to 88000000
ERROR: reserving fdt memory region failed (addr=ff700000 size=8ca000 flags=4)
Loading Device Tree to 000000008feee000, end 000000008fffffff ... OK
Working FDT set to 8feee000
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[ 0.000000] Linux version 6.1.33-g40c32565ca (oe-user@oe-host) (aarch64-oe-linux-gcc (GCC) 11.3.0, GNU ld (GNU Binutils) 2.38.20220708) #1 SMP PREEMPT Thu Jul 6 14:17:24 UTC 2023
[ 0.000000] Machine model: Texas Instruments AM625 SK
[ 0.000000] earlycon: ns16550a0 at MMIO32 0x0000000002800000 (options '')
[ 0.000000] printk: bootconsole [ns16550a0] enabled
。。。。。
可以看到加载内核并启动了。
文件系统也起来了。
到此,DFU 烧录eMMC启动基本调试通了。
还有几个待优化或者待解决的问题:
1. 针对全新的eMMC,需要手动格式化。这对于生产烧录来说,还需要优化的。如果SDK不支持,那就只能由用户来修改uboot,在自己的应用场景里实现了。
2. 烧录好eMMC后,不能默认从eMMC启动到内核和文件系统。这也是需要优化的地方,同样,是需要由用户来修改uboot。自己实现了。
该篇文档主要在用于记录调试DFU烧录eMMC过程的,在调试过程,也感谢TI的工程师的支持和解答疑惑。
并整理出来,让更多开发者少走弯路。一起交流学习。