4、U-Boot与TFTP烧录:U-Boot网络命令体系
嵌入式开发中,烧录系统最常用的方式就是通过网络。你想想看,总不能每次改个设备树都去插拔SD卡或者接JTAG吧?U-Boot自带的网络命令体系,就是干这个用的。我个人习惯先把网络调通,再考虑烧录的事。
4.1 U-Boot网络命令体系(ping/dhcp/tftp)
U-Boot的网络命令不多,但个个都是硬货。我列个表,你一看就明白。
| 命令 | 功能 | 典型用法 |
|---|---|---|
ping |
测试网络连通性 | ping 192.168.1.100 |
dhcp |
自动获取IP地址 | dhcp |
tftp |
通过TFTP下载文件 | tftp 0x42000000 uImage |
ping命令:说白了就是看板子和PC能不能说上话。我在项目中遇到过,明明网线插着,灯也亮,但就是ping不通。后来发现是PC的防火墙把ICMP包给拦了。嗯,这里要注意,U-Boot的ping实现比较精简,不支持域名解析,只能ping IP地址。
dhcp命令:这个命令挺省事。执行后U-Boot会自动向局域网内的DHCP服务器请求IP地址,同时会把serverip、gateway等环境变量也一并更新。我建议在调试初期先用dhcp,省得手动配错地址。
tftp命令:这才是重头戏。格式是 tftp [内存地址] [文件名]。比如 tftp 0x42000000 zImage,就是把PC上TFTP服务器根目录里的zImage文件,下载到板子的0x42000000地址处。为什么会用0x42000000?这是DDR内存的起始地址偏移量,不同芯片不一样,你得看芯片手册。
4.2 U-Boot环境变量配置(serverip/ipaddr/netmask/gateway)
U-Boot的环境变量,你可以理解成它的“配置文件”。网络相关的几个变量,必须配对了才能干活。
| 环境变量 | 含义 | 示例值 |
|---|---|---|
ipaddr |
开发板自己的IP地址 | 192.168.1.10 |
serverip |
PC端TFTP服务器的IP地址 | 192.168.1.100 |
netmask |
子网掩码 | 255.255.255.0 |
gateway |
网关地址(跨网段时必需) | 192.168.1.1 |
配置方法很简单,在U-Boot命令行里直接设:
setenv ipaddr 192.168.1.10
setenv serverip 192.168.1.100
setenv netmask 255.255.255.0
setenv gateway 192.168.1.1
saveenv
注意最后那个saveenv,不执行的话,重启就丢了。我曾经吃过这个亏,配了半天,一断电全没了,气得够呛。
如果你用的是dhcp,其实可以省掉手动配置。但我的习惯是:dhcp拿地址确认网络没问题后,再把地址手动写死。因为有些项目的网络环境没有DHCP服务器,或者分配的IP会变,写死了省心。
4.3 U-Boot下TFTP下载内核与设备树
网络通了,环境变量配好了,接下来就是真刀真枪地下载了。我一般按这个流程走:
- 先ping确认连通:
ping 192.168.1.100 - 下载设备树:
tftp 0x43000000 imx6ull-14x14-evk.dtb - 下载内核:
tftp 0x42000000 zImage - 启动内核:
bootz 0x42000000 - 0x43000000
这里的内存地址分配是有讲究的。我一般把内核放在0x42000000,设备树放在0x43000000,中间留出足够的空间,防止数据覆盖。你想想看,如果内核很大,设备树地址离得太近,下载设备树时就把内核尾巴给冲了,那启动肯定崩。
.dtb和.DTB是两码事。
4.4 U-Boot下TFTP下载根文件系统
根文件系统一般比较大,几十兆甚至上百兆。用TFTP下载到内存后,通常有两种处理方式:
- 直接NFS挂载:不烧写,通过网络挂载根文件系统,适合开发调试阶段。
- 烧写到Flash:下载到内存后,再用
update或nand write命令写到Flash里。
这里我重点讲烧写的方式。假设根文件系统是rootfs.ubifs格式:
# 1. 下载根文件系统到内存
tftp 0x44000000 rootfs.ubifs
# 2. 擦除NAND Flash上的对应分区
nand erase.part rootfs
# 3. 写入根文件系统
nand write 0x44000000 rootfs ${filesize}
注意${filesize}这个变量,它是tftp命令自动设置的,表示刚才下载的文件大小。用这个变量比手动输入字节数靠谱多了。我刚开始学的时候,傻乎乎地自己算大小,写错一次就得重来。
squashfs或ext4格式,烧写方式类似,只是文件系统和Flash类型不同。建议先确认你的Flash类型(NAND还是NOR),再选对应的烧写命令。
4.5 U-Boot下TFTP下载裸机程序
裸机程序没有操作系统,直接跑在硬件上。下载方式其实更简单,因为不需要考虑文件系统格式。裸机程序通常是.bin文件,下载到内存后直接跳转执行就行。
# 1. 下载裸机程序
tftp 0x40000000 led.bin
# 2. 跳转执行
go 0x40000000
go命令就是直接跳转到指定地址执行代码。这里要注意,裸机程序必须位置无关,或者链接地址和下载地址一致,否则跑不起来。我踩过这个坑,写了一个LED闪烁程序,链接地址是0x40000000,结果下载到0x41000000,一执行就死机。
另外,裸机程序一般比较小,几KB到几十KB,下载速度很快。但如果你用的是老旧的10M半双工网络,那速度就有点捉急了。我建议至少用100M全双工,TFTP下载速度能到几MB每秒,体验好很多。