BusyBox 中文文档 下载 App

/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 负责:

  1. 停止应用守护进程
  2. 卸载非根文件系统
  3. 卸载虚拟文件系统(/proc /sys 等内核会自动清理)
  4. 执行 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