BusyBox init /etc/inittab 配置详解
什么是 BusyBox init
Linux 内核启动完成后会把控制权交给第一个用户态进程 init(PID 1)。传统上有三个选择:
- systemd:现代发行版的默认,但体积大(需要 dbus、udev、journald 等配套),不适合嵌入式
- SysV init(init-utils):传统脚本驱动的 init,但包管理臃肿
- BusyBox init:内置在 BusyBox 二进制里,代码只有几百行,配置简单,嵌入式首选
BusyBox init 读取 /etc/inittab 来决定启动什么、怎么启动。
inittab 格式
每一行格式如下:
<id>:<runlevels>:<action>:<process>
| 字段 | 说明 |
|---|---|
| id | 唯一标识符(最多 4 字符),常用作 tty 号 |
| runlevels | 运行级别,BusyBox init 会忽略(全部等价),填 :: 即可 |
| action | 执行方式,决定什么时候运行 process |
| process | 要执行的命令(通常是 shell 命令) |
注释用 # 开头。
action 类型
BusyBox init 支持以下 action:
| action | 说明 | 典型用途 |
|---|---|---|
| sysinit | 启动时最先执行一次 | 挂载文件系统、设置 hostname、加载内核模块 |
| boot | sysinit 后在进入主循环前执行一次 | 额外的启动任务 |
| wait | 启动时同步执行一次并等待完成 | 等待某个初始化完成 |
| once | 启动时执行一次(不等) | 不关键的一次性任务 |
| respawn | 进程退出后自动重启 | 登录 shell、网络守护进程 |
| askfirst | respawn,但首次会提示按回车确认 | 救援模式、安全启动 |
| shutdown | 关机时执行 | 优雅关闭服务 |
| restart | init 重启时执行 | 清理工作 |
| ctrlaltdel | Ctrl+Alt+Del 时执行 | 通常设为 reboot |
最小 inittab 示例
这是一个能让系统跑起来的最简配置:
# /etc/inittab - 最小系统
# 启动脚本
::sysinit:/etc/init.d/rcS
# 登录 shell(3 个串口 tty)
tty1::respawn:/sbin/getty 115200 tty1
tty2::respawn:/sbin/getty 115200 tty2
ttyS0::respawn:/sbin/getty 115200 ttyS0
# Ctrl+Alt+Del 重启
::ctrlaltdel:/sbin/reboot
# 关机
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a
完整 inittab 示例(嵌入式路由器风格)
# 系统初始化
::sysinit:/etc/init.d/rcS
# 系统日志守护进程(respawn 保证崩溃后自动重启)
log::respawn:/sbin/syslogd -n -S 512000 -O /dev/null
klog::respawn:/sbin/klogd -n
# DHCP 客户端(respawn)
dhcp::respawn:/sbin/udhcpc -i eth0
# HTTP 管理界面(respawn)
httpd::respawn:/usr/sbin/httpd -p 80 -h /var/www
# 串口控制台(respawn)
ttyS0::respawn:/sbin/getty 115200 ttyS0
# 伪终端(可选)
#tty1::respawn:/sbin/getty 115200 tty1
#tty2::respawn:/sbin/getty 115200 tty2
# 关机清理
::shutdown:/etc/init.d/rcK
::ctrlaltdel:/sbin/reboot
BusyBox init 的限制
与 sysvinit 相比,BusyBox init 没有:
- 真正的运行级别切换(runlevels 字段被忽略)
- telinit 命令(无法远程切换配置)
- 复杂的依赖管理
这也是 BusyBox init 这么小的原因。大多数嵌入式设备只有一个运行级别,用 respawn 守护关键进程就够用了。
调试 inittab
修改 inittab 后,给 init 发送 HUP 信号让它重新加载:
busybox kill -HUP 1
# init 收到 HUP 会重新解析 /etc/inittab,
# 新配置的 respawn 进程会被启动,旧的不会被杀
# 想彻底重启 init(慎用,会杀掉所有子进程):
busybox kill -TERM 1
# init 收到 SIGTERM 会执行 shutdown action 然后退出
# 内核会重新启动 init