可以把 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 决定内核怎么启动。