BusyBox 中文文档 下载 App

kernel boot 参数 init 怎么传递 BusyBox init 或直接 shell

什么是内核启动参数

Linux 内核的 boot command line 是一段字符串,由 bootloader(GRUB、U-Boot、UEFI)在启动时传给内核。内核解析其中的各种 key=value 参数来决定行为——包括用什么方式挂载根文件系统、用什么程序作为第一个用户态进程(PID 1)。

关键参数:

参数说明
init=/path/to/program指定 PID 1 执行的程序路径
initrd=/path/to/archive指定 initramfs 归档文件位置
root=/dev/xxx指定根分区设备号
rootfstype=ext4指定根文件系统类型
ro / rw根文件系统初始只读/读写
console=ttyS0,115200内核消息输出到哪里
panic=Nkernel panic 后 N 秒自动重启(0=死等)

init= 参数的三种用法

方式一:跳过 init 直接进 shell(调试用)

init=/bin/sh

内核启动后直接以 /bin/sh(BusyBox ash 或 hush)作为 PID 1。没有 inittab、没有 rcS,拿到 shell 后需要手动挂载 proc/sys/dev:

# shell 启动后手动初始化
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs devtmpfs /dev
mount -o remount,rw /

这个方式在系统出问题(inittab 写错、rcS 挂掉)时用来救援特别方便——绕过了正常的 init 流程直接进 shell 修。

方式二:指定 BusyBox 二进制(推荐)

init=/busybox init

或者更简单(因为 BusyBox 支持 argv[0] 分发):

init=/init

内核启动时把 /init 作为 PID 1。如果 /init 是指向 busybox 的符号链接(/init -> busybox),那么 BusyBox 会被调用成 "init",执行 BusyBox init 逻辑——读取 /etc/inittab,执行 rcS,respawn 登录 shell 等。

make install 默认就会在 CONFIG_PREFIX/ 下创建 sbin/init -> busybox。

方式三:启动你的自定义程序

init=/usr/local/bin/my-daemon

内核启动后直接运行你的程序作为 PID 1,完全跳过 BusyBox init 或 shell。这在只运行单一应用的嵌入式设备上有用——比如工业控制器只跑一个主控程序。你的程序需要自己处理信号(SIGTERM 时优雅退出),并决定是否启动其他进程。

initrd vs initramfs

方式格式说明
initrdcpio.gz传统方式,内核解压后放到临时文件系统
initramfscpio.gz现代方式,解压到 rootfs,与根文件系统合并

两者对用户态代码完全透明——你只要把 BusyBox 和根文件系统结构打包成 cpio.gz,内核会自动处理。initrd= 和 initramfs= 参数最终效果是一样的(现代内核都用 initramfs)。

典型 bootloader 配置

U-Boot(嵌入式 ARM 设备最常见的 bootloader):

# 设置启动参数
setenv bootargs 'console=ttyS0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 init=/init'
# 加载内核
fatload mmc 0:1 0x20800000 uImage
# 加载 initramfs(如果用)
fatload mmc 0:1 0x21800000 initramfs.cpio.gz
# 启动
bootm 0x20800000 0x21800000

GRUB(x86 服务器/虚拟机):

menuentry "BusyBox system" {
  linux (hd0,1)/boot/bzImage root=/dev/sda1 ro init=/init
  initrd (hd0,1)/boot/initramfs.cpio.gz
}

QEMU(开发测试):

qemu-system-x86_64 \
  -kernel bzImage \
  -initrd initramfs.cpio.gz \
  -append "console=ttyS0 init=/init" \
  -nographic

调试内核启动参数

如果系统启动失败,最简单的调试方法是给 bootargs 加 init=/bin/sh,绕过所有 init 流程直接进 shell,然后逐步排查:

# 拿到 shell 后
ls -la /etc/inittab        # 文件在不在?
cat /etc/inittab          # 格式对不对?
busybox init              # 手动触发 init,看报错

加 panic=1 也有用——kernel panic 后 1 秒自动重启(而不是卡在那里),配合串口控制台可以快速看到 panic 信息。