快速理解 U-Boot:它是什么、为什么要有命令、环境变量和启动参数怎么工作

可以把 U-Boot 理解成开发板的 “开机管家 + BIOS + 调试小系统”。
它不是 Linux 内核,也不是 rootfs,而是在内核起来之前,先把板子唤醒、把硬件准备好、把内核镜像搬到内存里,最后把 CPU 控制权交给内核。


U-Boot 是什么?

U-Boot 全称是 Universal Boot Loader,也就是“通用引导加载程序”。
嵌入式板子上电后,芯片内部固化的 BootROM 会先运行,它负责从 eMMC、SD 卡、SPI Flash 等介质里把 U-Boot 加载进来。

U-Boot 起来以后,主要做几件事:

  • 初始化 DDR 内存;
  • 初始化串口、eMMC/SD、Flash、网络等外设;
  • 读取环境变量;
  • 从存储或网络加载内核镜像、设备树 DTB、initrd;
  • 设置内核启动参数 bootargs;
  • 启动内核,把控制权交给 Linux。

U-Boot 的最终目的是什么?

U-Boot 的最终目的不是“让自己运行”,而是 让 Linux 内核正确启动。

可以把它理解成机场地勤:

  • 飞机不是地勤;
  • 但飞机起飞前,地勤必须检查跑道、加油、放行;
  • 地勤工作完成后,飞机才能起飞。

U-Boot 也一样:它把硬件准备好、把内核和 DTB 搬到内存、把启动参数交给内核,然后跳转执行内核。跳转之后,U-Boot 通常就不再运行了。


为什么 U-Boot 要有命令?

因为开发阶段经常要调试。比如:

  • 内核起不来,要看内存里有没有正确加载镜像;
  • 想换一个新的 zImage/DTB 测试;
  • 想临时修改串口波特率、根分区路径;
  • 想从网络下载镜像,而不是每次都重新烧 eMMC;
  • 想确认 eMMC 分区是否正确;
  • 想手动执行一次启动流程,看哪里报错。

如果 U-Boot 只能自动启动,没有命令交互,调试会非常困难。
所以 U-Boot 启动时通常会倒计时几秒,如果按下 Ctrl + C 任意键,就会进入 U-Boot 命令行。


常用 U-Boot 命令

命令 作用 可以怎么理解
help / ? 查看支持的命令 相当于“帮助菜单”
printenv 查看所有环境变量 查看当前启动配置
setenv 设置或修改环境变量 临时改启动参数
saveenv 把环境变量保存到 Flash/eMMC 让修改重启后仍然生效
bootm / bootz / booti 启动内核镜像 把 CPU 交给内核
tftp 从网络下载文件到内存 快速调试内核/DTB
ping 测试网络是否通 检查板子和主机网络
mmc 操作 SD/eMMC 查看分区、读写存储
fatload / ext4load 从文件系统加载文件到内存 从 SD/eMMC 读镜像
md 查看内存内容 调试内存、寄存器、镜像
reset 复位开发板 重启板子

什么是环境变量?

环境变量就是 U-Boot 的 配置表。
U-Boot 启动时不需要重新编译,只要修改环境变量,就能改变启动行为。

常见环境变量:

环境变量 作用
bootcmd 自动启动时执行的命令,相当于“自动启动脚本”
bootargs 传给内核的启动参数,决定串口、根分区、启动方式
bootdelay 启动倒计时时间,超过时间就自动执行 bootcmd
ipaddr 开发板 IP 地址
serverip TFTP/NFS 服务器 IP 地址
ethaddr 网卡 MAC 地址

比如执行:

printenv

就能看到当前所有环境变量。

执行:

setenv bootargs 'console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait'

可以临时修改内核启动参数。

但只执行 setenv,重启后会恢复。
必须再执行:

saveenv

才会把环境变量写入 eMMC 或 Flash,永久保存。


什么是启动参数?

启动参数就是 U-Boot 传给内核的一张指令单,通常由 bootargs 提供。

例如:

console=ttyS0,115200 root=/dev/mmcblk0p2 rw rootwait

含义是:

  • console=ttyS0,115200:内核日志和终端走串口;
  • root=/dev/mmcblk0p2:根文件系统在 eMMC/SD 的第 2 个分区;
  • rw:以读写方式挂载;
  • rootwait:等待存储设备准备好再挂载根分区。

如果 bootargs 写错,内核就可能报:

VFS: Cannot open root device

因为它不知道根文件系统在哪里。


一句话理解

U-Boot 是内核启动前的“开机管家”,它的最终目的是把硬件准备好、把内核和 DTB 加载到内存、把 bootargs 传给内核,然后启动内核。环境变量是它的配置表,bootcmd 决定它自动做什么,bootargs 决定内核怎么启动。