/etc/init.d/rcS 启动脚本 BusyBox init 的系统初始化
rcS 的角色
当 BusyBox init 启动后,第一件事就是执行 inittab 中标记为 sysinit 的 action。通常这个 action 的 process 指向 /etc/init.d/rcS——一个 Shell 脚本,负责完成系统的实际初始化工作。
rcS 不是 BusyBox 自带的文件,是项目自定义的。BusyBox init 只负责执行它,rcS 内部写什么脚本逻辑完全由你来定。
基本 rcS 结构
#!/bin/sh
# /etc/init.d/rcS
# BusyBox init 启动脚本
# 挂载虚拟文件系统
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs devtmpfs /dev
mount -t tmpfs tmpfs /tmp
# 创建设备节点(如果 devtmpfs 没有自动创建)
if [ ! -e /dev/console ]; then
mknod /dev/console c 5 1
fi
if [ ! -e /dev/null ]; then
mknod /dev/null c 1 3
fi
# 设置主机名
hostname "my-device"
# 设置时钟(如果有硬件时钟)
if [ -e /dev/rtc0 ]; then
hwclock -s
fi
# 设置时区(可选)
export TZ=CST-8
# 设置 PATH
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
# 激活 swap
swapon -a
# 启动应用守护进程
# (也可以在 inittab 里用 respawn 启动)
# 执行额外的启动脚本
for script in /etc/rc.d/S*; do
[ -x "$script" ] && "$script" start
done
echo "System boot complete."
典型初始化步骤详解
1. 挂载虚拟文件系统
# proc:进程信息接口
mount -t proc proc /proc
# sysfs:硬件和内核信息
mount -t sysfs sysfs /sys
# devtmpfs:自动管理设备节点
mount -t devtmpfs devtmpfs /dev
# tmpfs:内存盘,用于 /tmp /run /var/lock 等
mount -t tmpfs -o size=32M tmpfs /tmp
mount -t tmpfs tmpfs /run
mount -t tmpfs tmpfs /var/lock
# cgroup(如果系统支持)
mount -t tmpfs tmpfs /sys/fs/cgroup
这些虚拟文件系统的挂载顺序很重要——某些后续步骤依赖前面的。
2. 挂载根文件系统为可写
# 如果根文件系统是以只读方式挂载的(很多嵌入式设备为了保护 Flash)
# 需要重新挂载为读写
mount -o remount,rw /
# 或者如果是单独的数据分区
mount -o noatime /dev/sda2 /data
noatime 选项对闪存设备特别重要——它禁用文件访问时间的自动更新,减少不必要的写入次数,延长 Flash 寿命。
3. 设置网络
# 设置 IP(静态)
ifconfig eth0 192.168.1.100 netmask 255.255.255.0 up
# 设置网关
route add default gw 192.168.1.1
# 设置 DNS(写入 resolv.conf)
echo "nameserver 8.8.8.8" > /etc/resolv.conf
# 或者用 DHCP 自动获取
# udhcpc -i eth0
4. 加载内核模块
# 简单方式:insmod 逐个加载(注意依赖顺序)
insmod /lib/modules/mydriver.ko
# 或者把模块名写进 /etc/modules 文件,用脚本遍历
if [ -f /etc/modules ]; then
while read mod; do
[ -n "$mod" ] && modprobe "$mod"
done < /etc/modules
fi
很多嵌入式项目直接把驱动编译进内核(built-in),这一步就可以省了。
5. 启动守护进程
有两种方式启动守护进程:
方式一:在 rcS 里直接启动
# 直接 fork 到后台
/usr/sbin/my-daemon &
方式二:在 inittab 里用 respawn(更推荐,崩溃自动重启)
# 在 /etc/inittab 里
mydaemon::respawn:/usr/sbin/my-daemon
关机脚本 rcK
对称地,关机时需要清理。inittab 的 shutdown action 可以指向 rcK:
::shutdown:/etc/init.d/rcK
rcK 负责:
- 停止应用守护进程
- 卸载非根文件系统
- 卸载虚拟文件系统(/proc /sys 等内核会自动清理)
- 执行 sync 刷盘
#!/bin/sh
# /etc/init.d/rcK
# 停止应用
for script in /etc/rc.d/K*; do
[ -x "$script" ] && "$script" stop
done
# 刷盘
sync
# 卸载(除了根和 proc/sys)
umount -a -r