当前位置: 首页 > news >正文

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

1. init是什么?

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

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

init进程的核心功能包括:

2. init的分类

嵌入式Linux系统中,init的分类,从简单到复杂,三种主流方案:BusyBox initSysVinitsystemd。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 Service After=network.target [Service] Type=simple ExecStart=/usr/local/bin/hello Restart=always RestartSec=5s User=nobody Group=nogroup StandardOutput=journal StandardError=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方案并掌握其开机自启动配置方法,是确保产品稳定可靠的关键一步。

http://www.cnnetsun.cn/news/3039656.html

相关文章:

  • APA第7版参考文献格式转换工具:3分钟解决Word引用难题的终极指南
  • 【TEE从入门到精通及实战】68 侧信道攻击:当Enclave的“心跳”出卖了你
  • Attu v3.0:Milvus向量数据库AI原生管理平台完整教程
  • GoLand代码审查自动化实践,用自定义Inspection规则拦截92.6%的常见Go反模式
  • 穿越RPG Maker加密屏障:探索开源解密工具的技术奥秘
  • CLion团队协作暗黑模式:如何通过自定义Live Template+Code Style同步实现10人以上项目零风格冲突
  • 科技创业孵化提质期:产业型孵化器的运营逻辑与实践
  • JTAG边界扫描与Arm TrustZone:嵌入式硬件测试与安全隔离核心技术解析
  • GoLand企业级安全配置清单:禁用远程代码执行、审计日志开启、敏感API自动拦截(内部红队验证版)
  • 厘米级无感跨镜追踪:Pixel2Geo™引擎打破镜头孤岛
  • RA8D2 MIPI CSI-2通用短包FIFO管理:从硬件原理到实战优化
  • RA8D2微控制器CAC模块:时钟精度监测与低功耗协同设计
  • FileSaver.js企业级实战指南:前端文件下载的5个高效实现方案
  • PowerToys Text Extractor:屏幕文字提取的智能化终极解决方案
  • USBHS寄存器深度解析:从TESTMODE到FIFO与中断的嵌入式USB 2.0高速通信实践
  • AI技术风暴来袭!程序员小白必看:收藏这份应对指南,抢占未来先机
  • 如何用PowerToys将Windows生产力提升300%的完整指南
  • RA8T2 DMA控制器深度解析:DMSBS/DMDBS寄存器与重复块传输模式实战
  • 网盘直链下载助手完整指南:如何绕过客户端限制直接下载文件
  • 瑞萨RA8T2 MFWD错误中断配置:从硬件事件到软件可观测性的关键
  • 如何快速上手英雄联盟皮肤修改器:R3nzSkin终极使用指南
  • I3C总线协议详解:从CCC命令到寄存器配置与实战调试
  • IntelliJ IDEA Java项目初始化失败全链路诊断(2024最新版JDK 17/21兼容性雷区实录)
  • 八大网盘直链下载助手完整教程:免费获取真实下载链接的终极解决方案
  • RA8P1以太网控制器错误与中断机制:从寄存器到高可靠嵌入式网络驱动实践
  • DMA描述符队列与LINKFIX表:嵌入式网络控制器高效数据传输的核心机制
  • 解锁9大网盘全速下载:LinkSwift开源工具终极指南
  • RA8P1 I2C唤醒与仲裁机制:低功耗与多主通信的实战解析
  • 嵌入式2D图形引擎核心优化:光栅化与纹理映射技术详解
  • IDEA默认端口8000/8080/63342总被占?资深JetBrains认证专家曝光5大系统级抢占源及永久规避方案