U-Boot 与内核启动参数 bootargs
bootargs 是 U-Boot 传给 Linux kernel 的命令行参数。它不决定 U-Boot 自己怎么运行,而是决定 Linux 启动后如何选择 console、rootfs、日志级别以及一些内核行为。
如果你有 Linux 使用经验,可以把 bootargs 理解成 kernel 的启动命令行。它不是 Shell 命令,也不会由 U-Boot 逐个解释。U-Boot 只是把这串文本交给 Linux,真正解释这些参数的是 Linux kernel。
1. 查看当前 bootargs
# [U-Boot]
printenv bootargs
如果变量不存在,说明当前启动流程可能会在脚本中动态生成,或者使用 Standard Boot 从配置文件读取参数。
你还可以直接输出:
# [U-Boot]
echo ${bootargs}
如果输出为空,不一定表示不能启动。有些启动方式会从 extlinux.conf 的 append 行读取参数,或者在执行启动脚本时才设置 bootargs。
2. 最小可用参数
对于 QEMU ARM64 virt,一个常见的最小参数是:
# [U-Boot]
setenv bootargs "console=ttyAMA0"
console=ttyAMA0 告诉 Linux 把内核日志输出到 ARM PL011 串口。没有正 确的 console 参数时,Linux 可能已经启动了,但你在终端看不到输出。
console 参数为什么排第一
启动调试时,你最需要的是日志。没有 console 输出,你不知道 Linux 是没启动、启动早期崩溃,还是已经进入用户空间。因此本教程会反复把 console= 放在最小参数里。
QEMU ARM64 virt 常用 ttyAMA0。真实开发板可能是:
ttyS0ttyS2ttyFIQ0ttymxc0ttySTM0
具体名称取决于 Linux 串口驱动和设备树。不要把 U-Boot 的 serial 设备名直接写成 Linux console 名称。
如果 rootfs 在 virtio block 的第二个分区,可以写:
# [U-Boot]
setenv bootargs "console=ttyAMA0 root=/dev/vda2 rw rootwait"
其中:
root=/dev/vda2:Linux 根文件系统设备。rw:以可读写方式挂载。rootwait:等待 root 设备出现。
bootargs 中的设备名是 Linux 视角,不是 U-Boot 视角。U-Boot 中的 mmc 0:2 到 Linux 里可能是 /dev/mmcblk0p2;QEMU virtio block 常见为 /dev/vda2。
3. root 参数怎么选
root= 告诉 Linux 挂载哪个设备作为根文件系统。常见写法包括:
root=/dev/vda2
root=/dev/mmcblk0p2
root=PARTUUID=<partition-uuid>
root=UUID=<filesystem-uuid>
root=/dev/nfs
设备名方式直观,但可能受枚举顺序影响。UUID 或 PARTUUID 更稳定,但你需要在制作镜像时知道对应值。NFS root 则用于网络根文件系统,通常还需要 nfsroot= 和 ip= 参数。
初学阶段可以先使用设备名,等你理解启动链后再学习 UUID/PARTUUID。
4. 使用 initramfs 时的参数
如果你使用 initramfs,通常可以暂时不指定 root=,让内核直接进入 initramfs 中的 /init:
# [U-Boot]
setenv bootargs "console=ttyAMA0"
如果 initramfs 中没有 /init,Linux 会报错,常见信息类似 No working init found。这时问题不在 U-Boot,而在 initramfs 内容。
如果你既传了 initramfs,又设置了 root=,Linux 可能会先进入 initramfs,再由 initramfs 中的脚本挂载真正 rootfs。这是很多发行版的常见流程。不要简单认为“有 initramfs 就一定不需要 root 参数”。