当前位置:首页>Linux>嵌入式 Linux init 进程 | 深入剖析原理、自启与方案抉择

嵌入式 Linux init 进程 | 深入剖析原理、自启与方案抉择

  • 2026-10-11 06:20:54
嵌入式 Linux init 进程 | 深入剖析原理、自启与方案抉择

星标「Linux大陆」,一起进步!

1. init是什么?

init是Linux系统中的“天字一号”进程:

它的进程号(PID)恒为1,是所有其他进程的父进程。其启动流程如:

init进程的核心功能包括:

2. init的分类

嵌入式Linux系统中,init的分类,从简单到复杂,三种主流方案:BusyBox init、SysVinit和systemd。Buildroot等构建系统也明确将这三类列为可选的初始化系统。

当前系统init类型的指令:

cat /proc/1/comm

2.1 BusyBox init——轻量级选手

BusyBox init是专门为资源受限的嵌入式环境设计的最轻量级解决方案。它是Buildroot的默认init方案,对于大多数嵌入式系统而言已经足够使用。

比如,Buildroot_2019.02:

2.2 SysVinit——经典传统派

SysVinit源自AT&T在1983年发布的System V Unix系统,曾是绝大多数桌面Linux发行版采用的init方案。

2.3 systemd——现代全能型选手

systemd由Lennart Poettering主导开发,是当前Linux桌面和服务器领域最主流的init系统,已被Ubuntu、Fedora、Debian等主流发行版全面采用。

3. 各init开机自启动应用的区别

三种init方案在开机自启动应用的方式上有显著差异:

3.1 SysVinit

SysVinit的启动脚本命名规则为Sxxname(S表示Start,xx为两位数字编号,数字越小越先启动),启动过程中会按编号顺序逐个执行脚本,例如:

init进程启动之后,会对/etc/inittab文件的解释及执行。/etc/inittab文件里有什么内容如:

可以看到里面用到了两个脚本文件:

  • /etc/init.d/rcS
  • /etc/init.d/rcK

其中,可以看出/etc/init.d/rcS是在系统开机之后执行的脚本;/etc/init.d/rcK是在系统关机时执行的脚本。

下面看看/etc/init.d/rcS里面的内容:

这个rcS脚本会循环调用/etc/init.d文件夹下的以S+数字开头的脚本文件。即:

SysVinit这种机制简单直观,但随着服务数量的增长,串行启动的效率瓶颈越来越明显。

3.2 BusyBox init

BusyBox init与SysVinit程序自启动的方式大同小异。可以把 BusyBox init 看作 SysVinit 的精简子集,它们之间最核心的区别在于 SysVinit 拥有运行级别的概念,而 BusyBox init 则巧妙地绕过了它,但又能“模拟”出近乎一致的效果。

配置文件:/etc/inittab 或 /etc/init.d/rcS。通过 rcS 脚本挂载,适合一次性启动,不自动守护。通过 inittab 守护进程,自动重启保活。

自启动方式:直接编辑 inittab 或创建 S* 脚本。

3.3 systemd

systemd则截然不同:

我们只需编写一个简单的.service文件描述服务的启动命令、运行条件和其他依赖关系,然后执行systemctl enable即可设置开机自启动。启动时,systemd会解析所有Unit文件间的依赖关系,并行启动不冲突的服务,大大缩短了启动时间。自定义服务必须放在 /etc/systemd/system/ 下。

开机自启动自定义服务的例子:

1. 将程序安装到合适的位置

systemd 服务通常使用绝对路径来指定可执行文件。建议将二进制文件放在 /usr/local/bin/ 或 /opt/ 下,例如自定义一个hello程序:

sudo cp ~/hello /usr/local/bin/

同时确保文件具有可执行权限:

sudo chmod +x /usr/local/bin/hello

2. 创建 systemd 服务单元文件

在 /etc/systemd/system/ 目录下创建 hello.service:

sudo vim /etc/systemd/system/hello.service

写入以下内容:

[Unit]Description=Hello Systemd Demo ServiceAfter=network.target[Service]Type=simpleExecStart=/usr/local/bin/helloRestart=alwaysRestartSec=5sUser=nobodyGroup=nogroupStandardOutput=journalStandardError=journal[Install]WantedBy=multi-user.target

关键参数解释:

  • Type=simple:服务主进程就是 ExecStart 启动的进程。
  • ExecStart:指定要运行的程序完整路径。
  • Restart=always:无论程序因何退出(包括正常退出),都自动重启。因为我们循环中用了 sleep(10),理论上不会退出,加上 always 可以兜底。
  • User=nobody / Group=nogroup:使用低权限用户运行,降低安全风险。
  • StandardOutput=journal:将程序的标准输出重定向到 systemd 日志(journalctl)。
  • WantedBy=multi-user.target:将服务挂钩到多用户目标,实现开机自启。

注意:如果你的程序需要写文件或访问某些目录,nobody 用户可能没有权限,可以根据实际需求修改为其他普通用户(如 www-data 或你自己的用户名)。

3. 启动服务并设置开机自启

# 1. 重新加载 systemd 配置,让 systemd 识别新的服务文件sudo systemctl daemon-reload# 2. 立即启动服务(验证是否能正常运行)sudo systemctl start hello.service# 3. 查看服务状态和最近的日志sudo systemctl status hello.service

此时能看到下面的输出,且 Active 状态为 active (running),日志中已经出现了 hello systemd:

# 4. 设置开机自动启动sudo systemctl enable hello.service

执行 enable 后,systemd 会在 /etc/systemd/system/multi-user.target.wants/ 目录下创建一个指向 hello.service 的符号链接:

下次系统启动时,就会自动运行该服务。

4. 验证开机自启

重启系统:

sudo reboot

重新登录后,检查服务状态:

systemctl status hello.service

常用指令:

命令
用途
sudo systemctl start hello
立即启动服务
sudo systemctl stop hello
立即停止服务
sudo systemctl restart hello
重启服务
sudo systemctl enable hello
设置开机自启
sudo systemctl disable hello
取消开机自启
systemctl status hello
查看服务状态和最近日志
journalctl -u hello -b
查看本次启动以来服务的完整日志
journalctl -u hello -f
实时跟踪日志输出(类似 tail -f)

4. 当前主流的init方案

在桌面和服务器领域,systemd已毫无疑问地成为绝对主流。

在嵌入式Linux领域,情况则更为多元:Yocto Project虽然默认仍使用SysVinit,但已全面支持systemd切换;Buildroot默认选择BusyBox init,因为它在资源受限的嵌入式系统中最轻量、最高效。

选型建议:

此外,还有一些小众但值得关注的init方案:

4. 小结

init进程虽小(PID=1),却是整个Linux系统的“第一推动力”。从极致精简的BusyBox init,到经典稳健的SysVinit,再到功能强大的systemd,每一种方案都有其适合的应用场景。

在嵌入式系统开发中,正确选择init方案并掌握其开机自启动配置方法,是确保产品稳定可靠的关键一步。

最新文章

随机文章