4. U-Boot环境变量配置:baudrate、loadaddr、bootargs等关键变量详解

环境变量这东西,说白了就是U-Boot的「记忆」。没有它,你每次上电都得重新敲一遍命令,那谁受得了?我刚开始搞嵌入式那会儿,就吃过这个亏——烧完固件忘了设baudrate,串口打印全是乱码,折腾了半小时才发现是波特率没改过来。

今天咱们就挑几个最关键的变量,掰开揉碎了讲。你只要把这几个搞明白,串口烧录这块基本就通了。

4.1 baudrate —— 串口通信的「共同语言」

baudrate,就是波特率。它决定了U-Boot和你的PC串口工具之间,每秒能传多少位数据。两边必须设成一样的,否则就是鸡同鸭讲。

常见波特率: 9600、19200、38400、115200、1500000

我个人习惯用115200。为什么?因为大部分SoC的默认波特率就是这个,省得改来改去。但有些老平台默认是9600,你上来就设115200,那肯定乱码。

小技巧: 如果你不确定当前波特率,可以按住复位键,同时快速敲回车,看哪个波特率能打出菜单。我当年就是这么试出来的。

设置方法很简单:

setenv baudrate 115200
saveenv

嗯,这里要注意——改完波特率之后,你的串口工具也得同步改。否则你这边设了115200,那边还是9600,照样乱码。

避坑指南: 我曾经在量产时遇到过一个问题——某批次板子的晶振有偏差,导致115200波特率下误码率飙升。后来我改成57600就稳了。所以,如果你发现烧录经常失败,先别急着怀疑代码,试试降低波特率。

4.2 loadaddr —— 数据该往哪儿放?

loadaddr,就是加载地址。你通过串口把数据传过来,U-Boot得知道往内存的哪个位置放。这个地址设错了,轻则烧录失败,重则把U-Boot自己给覆盖了——那板子就变砖了。

不同的平台,loadaddr的默认值不一样:

平台 默认loadaddr 说明
ARM (Cortex-A) 0x82000000 常用,避开U-Boot自身区域
ARM (Cortex-M) 0x20000000 SRAM地址,空间有限
x86 0x100000 1MB处,避开BIOS区域
RISC-V 0x80200000 常用起始地址

你想想看,为什么ARM上常用0x82000000?因为U-Boot自己通常运行在0x80000000附近,留出一点余量,避免覆盖。我见过有人图省事,直接把loadaddr设成0x80000000,结果一烧录,U-Boot自己先挂了。

setenv loadaddr 0x82000000
saveenv
建议: 如果你不确定当前内存布局,可以先执行 bdinfo 命令,它会打印出内存的起始地址和大小。然后你再选一个安全的位置。

4.3 bootargs —— 内核的「启动参数」

bootargs,这玩意儿是传给Linux内核的启动参数。它告诉内核:根文件系统在哪儿、控制台用哪个串口、内存多大等等。设错了,内核起不来。

一个典型的bootargs长这样:

setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootfstype=ext4

拆开来看:

  • console=ttyS0,115200 —— 内核的调试信息通过串口0输出,波特率115200
  • root=/dev/mmcblk0p2 —— 根文件系统在SD卡的第二个分区
  • rw —— 以读写方式挂载
  • rootfstype=ext4 —— 文件系统类型是ext4

我记得有一次,客户说他们的板子内核起不来,打印到「Starting kernel...」就卡住了。我一看bootargs,console设成了ttyS1,但板子只有ttyS0有输出。改过来就好了。说白了,就是串口号搞错了。

串口烧录时常用的bootargs:
setenv bootargs console=ttyS0,115200 root=/dev/ram0 rw initrd=0x82000000,8M

这个配置的意思是:内核启动后,从内存地址0x82000000加载一个8MB的initrd作为临时根文件系统。适合串口烧录后直接启动测试。

4.4 其他关键变量

除了上面三个,还有几个变量你最好也了解一下:

变量名 作用 典型值
bootdelay 启动倒计时秒数 3
bootcmd 倒计时结束后自动执行的命令 run distro_bootcmd
ipaddr 板子的IP地址(网络烧录用) 192.168.1.100
serverip TFTP服务器的IP地址 192.168.1.1
filesize 最近一次传输的文件大小(只读) 0x400000

bootdelay设成0的话,板子上电就直接启动,不给你敲命令的机会。量产时这么干没问题,但调试阶段千万别——我吃过这个亏,板子一直循环重启,想进U-Boot都进不去。

4.5 环境变量的保存与恢复

改完变量,记得 saveenv。否则断电就丢了。U-Boot会把环境变量保存到存储介质上——可能是SPI Flash、NAND、MMC或者EMMC。

如果你把环境变量搞乱了,别慌。大部分U-Boot都支持恢复出厂设置:

env default -a
saveenv
reset

这个命令会把所有环境变量重置为编译时的默认值。我当年第一次用U-Boot时,把baudrate改成了1000000(1Mbps),结果串口工具不支持,板子直接失联。就是用这招救回来的。

注意: 如果你改了baudrate之后失联了,可以试试在U-Boot启动时按住某个按键(通常是空格或Enter),它会进入一个「安全模式」,用默认的波特率启动。具体按键看你的板子文档。

4.6 知识体系总览

下面这张图,把咱们今天讲的内容串起来了。你可以看到,环境变量在串口烧录流程中扮演的角色:

U-Boot环境变量在串口烧录中的角色 PC串口工具 U-Boot串口驱动 环境变量配置中心 baudrate | loadaddr | bootargs | bootdelay 波特率匹配 baudrate=115200 数据加载地址 loadaddr=0x82000000 内核启动参数 bootargs=console=... 串口烧录成功 数据正确传输 → 内核正常启动 三个关键变量分别控制:通信速率、数据存放位置、内核启动行为

从这张图可以看得很清楚:baudrate决定了你能不能和板子「说上话」,loadaddr决定了数据放哪儿,bootargs决定了内核怎么跑。三个变量,环环相扣,缺一不可。

好了,关于环境变量这块,核心就是这些。你只要把baudrate、loadaddr、bootargs这三个搞明白,串口烧录的配置部分就没什么大问题了。剩下的,就是多动手试试——改一个变量,烧一次,看看效果。实践出真知嘛。

可可精品资料库