【嵌入式Linux基础】启动初始化程序--init程序
文章目录
- 内核启动后
- 初始化程序简介
- BusyBox init
- Buildroot init 脚本
- 后记
内核启动后
内核引导代码在initramfs中通过内核命令行中的root=指定的文件系统中去寻找根系统文件,并执行一个相应的程序。在默认情况下,对于initramfs这个程序是/init,对于常规文件系统,是/sbin/init程序。init程序具有root权限,且因为它是第一个运行的进程,所以其进程ID(PID)是1。如果init程序未能启动,则内核将会崩溃。
init程序是所有其他进程的祖先。在这里,通过pstree命令可以看出,在大部分版本中,init通常是psmisc包中的一部分:
# pstree -gn init(1)-+-syslogd(63)|-klogd(66)|-dropbear(99)`-sh(100)---pstree(109)
init程序的任务是接管系统并使之运行。它和运行shell脚本的shell命令一样简单。
- 在启动阶段,它启动守护进程,配置系统参数,以及负责让系统进入工作状态所需要做的配置操作。
- 作为可选项,它可以启动其他守护进程,如在终端上的getty守护进程,该进程允许登录shell。
- 接收那些因为直接父进程被终止,以及线程组中没有其他进程而形成的孤儿进程。
- 它通过捕捉信号SIGCHLD并收集其返回值以防止它们成为僵尸进程,对init的直接子进程的终止进行响应。
- 作为一个可选项,它重新启动那些已经终止的守护进程。
- 它处理系统关机。
换句话说,init管理着系统从开机到关机的整个生命周期。
初始化程序简介
在嵌入式设备中,你最有可能遇到三个初始化程序是BusyBox init、System V init 和 systemd。Buildroot默认只构建BusyBox init,你也可以选择构建所有三个初始化程序。Yocto项目默认构建System V init,当然其他两种也可以选择。
类别 | Busy Box init | System V init | systemd |
---|---|---|---|
复杂性 | 低 | 中 | 高 |
启动速度 | 快 | 慢 | 中 |
所需shell | ash | ash 或 bash | 无 |
可执行程序数量 | 0 | 4 | 50(构建系统时的配置 |
支持的C库 | 任意 | 任意 | glibc |
大小(MB) | 0 | 0.1 | 34(构建系统时的配置 |
systemd的50个可执行程序、34MB的大小都是基于Buildroot的配置。
一般来说,从BusyBox init到 systemd,灵活性和复杂性都会逐渐增加。
BusyBox init
BusyBox 的 init 程序最小,它使用配置文件/etc/inittab
来定义规则,在系统启动阶段控制程序启动,在关机阶段控制程序终止。通常情况下,实际工作是由shell脚本来完成的,而按照惯例,脚本会放置在/etc/init.d
目录下。
init 首先会读取配置文件/etc/inittab
。配置文件包含了一个需要运行的程序列表,一行一个,格式如下:
<id>::<action>:<program>
- id:指令所针对的控制终端
- action:运行该指令的条件,将在下面的段落展示
- program:待运行的程序
运行该指令的条件(action
字段)的可填写的内容:
- sysinit:在其他所有类型的操作之前,当初始化开始时,运行程序。
- respawn:运行指定程序,如果程序终止则重新启动。
- askfirst:与respawn相同,但是这个会向控制台输出“Please press Enter to activate this console”,并在按下Enter键时运行该程序。它用于在终端上启动一个交互式shell,且不提示输入用户名或密码。
- once:运行指定程序,如果该程序终止,不会尝试重新启动它。
- wait:运行指定程序,并等待其完成。
- restart:当init接收到信号SIGHUP时,这表明其应该重新载入inittab文件,此时运行指定程序。
- ctrlaltdel:当init接收到信号SIGINT时运行指定程序,这通常是由于用户在控制台按下了 Ctrl+Alt+Del 组合按键。
- shutdown:当init关闭时运行指定程序。
这是一个完整的实际使用的inittab
文件
# /etc/inittab
#
# Copyright (C) 2001 Erik Andersen <andersen@codepoet.org>
#
# Note: BusyBox init doesn't support runlevels. The runlevels field is
# completely ignored by BusyBox init. If you want runlevels, use
# sysvinit.
#
# Format for each entry: <id>:<runlevels>:<action>:<process>
#
# id == tty to run on, or empty for /dev/console
# runlevels == ignored
# action == one of sysinit, respawn, askfirst, wait, and once
# process == program to run# Startup the system
::sysinit:/bin/mount -t proc proc /proc
::sysinit:/bin/mount -o remount,rw /
::sysinit:/bin/mkdir -p /dev/pts
::sysinit:/bin/mkdir -p /dev/shm
::sysinit:/bin/mount -a 2>/dev/null
::sysinit:/bin/hostname -F /etc/hostname
# now run any rc scripts
::respawn:-/bin/sh
::sysinit:/etc/init.d/rcS# Put a getty on the serial port
#ttyFIQ0::respawn:/sbin/getty -L ttyFIQ0 0 vt100 # GENERIC_SERIAL# Stuff to do for the 3-finger salute
#::ctrlaltdel:/sbin/reboot# Stuff to do before rebooting
::shutdown:/etc/init.d/rcK
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r
/etc/inittab
文件中<action>
字段的意义
action名称 | 执行条件 | 说明 |
---|---|---|
sysinit | 系统启动后最先执行 | 只执行一次,init进程等待它结束后才继续执行其他动作 |
wait | 系统执行完sysinit进程后 | 只执行一次,init进程等待它结束才继续执行其他动作 |
once | 系统执行完wait进程后 | 只执行一次,init进程不等待它结束 |
respawn | 启动完once进程后 | init进程检测发现子进程退出时,重新启动它 |
askfirst | 启动完respawn进程后 | 与respawn进程类型,不过init进程先输出“Please press Enter to activate this console”,等用户输入回车键之后才启动子进程。 |
shutdown | 当系统关机时执行 | 即重启、关闭系统命令时 |
restart | BusyBox中配置了CONFIG_FEATURE_USE_INITTAB,并且init进程接收到SIGHUP信号时 | 先重新读取、解析/etc/inittab文件,再执行restart程序 |
ctrlaltdel | 按下 Ctrl+Alt+Del 组合键时 |
以下是一个小例子,包括挂载的 proc 和 sysfs ,以及在串行接口运行 shell:
null::sysinit:/bin/mount -t proc proc /proc
null::sysinit:/bin/mount -t sysfs sysfs /sys
console::askfirst:-/bin/sh
对于简单的项目,比如你只想启动少量的守护进程,或者是在串口终端启动一个登录shell,手写一个脚本也很容易。这种情况下,如果你创建一个简单的定制的嵌入式Linux是很合适的。然而,你会发现随着需要配置的事情不断增加,手写一个init脚本很快就会变得非常难以维护。
Buildroot init 脚本
多年以来,Buildroot有效使用了BusyBox 的init程序。Buildroot在/etc/init.d
目录中有两个脚本,名为 rcS
和 rcK
。第一个脚本 rcS 在开机时运行,并从一个大写S加两位数字开始遍历所有的脚步,并按数字顺序运行,这就是开始脚本。rcK 脚本在关机时运行,从一个大写K 加两位数字开始遍历所有的脚本,并按数字顺序运行,这就是结束脚本。
以上的做法也是存在的,实际上更多做法是在目录/etc/init.d
里面只有众多的S开头的启动脚本,在S开头的脚本里面通过传入的参数start
或者stop
来执行开机时的操作逻辑或者关机时的操作逻辑。
一个典型实际使用的rcS脚本:
#!/bin/sh# Start all init scripts in /etc/init.d
# executing them in numerical order.
#
for i in /etc/init.d/S??* ;do# Ignore dangling symlinks (if any).[ ! -f "$i" ] && continuecase "$i" in*.sh)# Source shell script for speed.(trap - INT QUIT TSTPset start. $i);;*)# No sh extension, so fork subprocess.$i start;;esac
done
一个典型实际使用的rcK脚本:
#!/bin/sh# Stop all init scripts in /etc/init.d
# executing them in reversed numerical order.
#
for i in $(ls -r /etc/init.d/S??*) ;do# Ignore dangling symlinks (if any).[ ! -f "$i" ] && continuecase "$i" in*.sh)# Source shell script for speed.(trap - INT QUIT TSTPset stop. $i);;*)# No sh extension, so fork subprocess.$i stop;;esac
done
一个典型实际使用的S开头的用于alsa系统启动的脚本:
S04alsa.sh
#!/bin/sh
#case "$1" instart)if [ -f "/etc/asound.state" ];thenalsactl restore -f /etc/asound.statefi#enable spkecho 1 > /proc/rp_power/spk_onecho 0 > /proc/rp_power/spk_mute;;stop)echo "not stop function";;*)echo "Usage: $0 {start|stop}"exit 1;;
esac
在操作系统中,一般系统的服务都是以后台进程的方式存在,而且都会常驻系统中,直到关机才结束。这类服务也称Daemon,在Linux系统中就包含许多的Daemon。判断Daemon最简单的方法就是从名称上看。多数的Daemon都是由服务名称加上d。例如,在Linux操作系统中HTTP服务的Deamon就是httpd。
通过这一套机制,Buildroot包能够很容易地提供自己的开始脚本和结束脚本,并利用两个数字编号影响这些脚本的运行顺序,使其按照应有的顺序执行,从而使系统成为可扩展的。
后记
其他的init程序比如:System V init 和 systemd,笔者也没有使用过,有兴趣可以去看《嵌入式Linux编程》【Chris Simmonds】这本书的【第9章 启动初始化程序】的9.4和9.5小节。
相关文章:

【嵌入式Linux基础】启动初始化程序--init程序
文章目录 内核启动后初始化程序简介BusyBox initBuildroot init 脚本 后记 内核启动后 内核引导代码在initramfs中通过内核命令行中的root指定的文件系统中去寻找根系统文件,并执行一个相应的程序。在默认情况下,对于initramfs这个程序是/init࿰…...

基于Java实现农产品交易平台的设计与实现_kaic
【摘要】农业是我国国民经济的重要组成部分,随着信息化的普及,4G网络、光纤以及5G网络也日益完善,农业信息化的发展成为了必然。同时,由于本年疫情原因,导致农作物积压销售,甚至腐烂造成不必要的浪费&#…...

视频转换、视频压缩、录屏等工具合集:迅捷视频工具箱
这是一款功能强大的视频处理软件,提供了多种视频处理功能。可以使用该软件进行视频剪辑、视频转换、音频转换、视频录像、视频压缩、字幕贴图等多种操作。软件界面简洁易用,操作方便,可以满足各种视频处理需求。 基本功能 视频压缩ÿ…...

理解时序数据库的时间线
在当今数据爆炸的时代,时序数据已经成为企业和组织中不可或缺的一部分。它们包括了从传感器、监控设备、日志记录系统和金融交易等多种来源的大量数据,这些数据按照时间顺序排列,记录了各种事件和活动的发生和变化。时序数据的分析和处理对于…...

音视频技术开发周刊 | 295
每周一期,纵览音视频技术领域的干货。 新闻投稿:contributelivevideostack.com。 微软炸通Windows与ChatGPT全家桶!人手一个Copilot,AI宇宙降临 三位OpenAI掌舵人亲自撰文:我们应该如何治理超级智能? OpenA…...

15稳压二级管
目录 一、基本原理 二、I-V特性 三、工作原理 四、参数 1、Vz 2、Zzt和Zzk 3、IrVr 4、VfIf 5、Pd 五、应用 1、示例1 2、串联应用 3、钳位电路 六、动态电阻 一、基本原理 稳压二极管或“击穿二极管”(有时也称为齐纳二极管)基本上与标准PN结二极管相同…...
一些零零碎碎的记录
Questions1. 用户访问多网址服务器同一个IP是怎么回事 Q:用户访问服务器的同一个IP不同网址,服务器是如何区分的A: 在 HTTP 协议中,客户端通过发送请求报文来向服务器请求资源。每个 HTTP 请求都包含一个 HTTP 头部,其中包括了一些关键信息&…...

MyBatis - Spring Boot 集成 MyBatis
文章目录 1.版本要求2.导入依赖3.自动配置2.可配置项 MyBatis-Spring-Boot-Starter 可以帮助你更快地在 Spring Boot 之上构建 MyBatis 应用。通过使用该模块我们能够快速实现以下目的: 构建单体应用程序将几乎不需要样板配置使用更少的 XML 配置 1.版本要求 MyB…...

常见开源协议介绍
开源协议是指开放源代码软件的使用、修改和分发的规则。开源协议的出现,使得开发者可以在保护自己的知识产权的同时,也可以让其他人使用、修改和分发自己的代码。本文将介绍几种常见的开源协议。 一、GPL协议 GPL(GNU General Public Licens…...

第十九章行为型模式—中介者模式
文章目录 中介者模式解决的问题结构实例存在的问题适用场景 中介者模式和代理模式的区别代理模式中介模式桥接模式总结 行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务,它涉及算法…...

AKStream部署1:ZLMediaKit流媒体服务器(win)
环境准备: windows10/11 visual stadio 2022(.net 6) cmake 3.22.0 git bash 没讲究直接下最新的 ffmpeg : ffmpeg-5.1.2-full_build VLC播放器:VLC media player ZLMediaKit:gitee地址 1、安装上述软件 例ffmpeg下载解压至某自定…...

【Redis】Redis 中地理位置功能 Geospatial 了解一下?
文章目录 前言一、Geospatial Indexes 的数据结构二、常用命令三、实用场景示例1. 找出某一经纬度周围的餐馆2. 按照距离排序查询景点 四、在实际开发中,需要注意以下几点: 前言 Geospatial Indexes 是 Redis 提供的一种数据结构,用于存储和…...

Qt Qml 实现键鼠长时间未操作锁屏
文章目录 摘要实现思路键盘鼠标监控百度到的方法我的自己方法 最后 关键字: Qt、 Qml、 QInputEvent 、 QStandardItem、 eventFilter 摘要 今日需求: 项目中需要实时检测用户是否长时间为操作键盘和鼠标,如果超过预设时间未操作键盘和…...

常用的数字高程模型(DEM)数据介绍,附免费下载
常用的数字高程模型(DEM)数据: ETOPO(1.8千米) ETOPO是一种地形高程数据,由NGDC美国地球物理中心发布,与大多数高程数据不同的是,它还包含海底地形数据。 SRTM15(450…...

字节跳动面试挂在2面,复盘后,决定二战.....
先说下我基本情况,本科不是计算机专业,现在是学通信,然后做图像处理,可能面试官看我不是科班出身没有问太多计算机相关的问题,因为第一次找工作,字节的游戏专场又是最早开始的,就投递了…...

简述熔断、限流、降级
高并发场景指的是在大量用户同时访问服务时,服务能够保持稳定和高效运行的能力。 常用的解决高并发场景下服务不可用问题的技术手段包括熔断、限流和降级: - 熔断:当服务的错误率超过一定阈值时,熔断器会自动断开服务的调用&…...

Maven 工具
Maven 工具 Maven简介Maven 基础概念创建 Maven项目依赖配置生命周期与插件分模块开发聚合和继承聚合继承聚合与继承的区别 属性版本管理多环境配置与应用私服 Maven简介 Maven 本质是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型(POM…...

iptables扩展匹配条件
文章目录 1. multiport模块2. iprange模块3. string模块4. time模块5. icmp模块6. connlimit模块7. limit模块8.tcp扩展模块9.state模块10 Iptables自定义链1.1 为什么要使用自定义链1.2 创建自定义链1.3 引用自定义链1.4 重命名自定义链1.5 删除自定义链 1. multiport模块 常…...

直播录音时准备一副监听耳机,实现所听即所得,丁一号G800S上手
有些朋友在录视频还有开在线会议的时候,都会遇到一个奇怪的问题,就是自己用麦克风收音的时候,自己的耳机和别人的耳机听到的效果不一样,像是音色、清晰度不好,或者是缺少伴奏以及背景音嘈杂等,这时候我们就…...

回归测试最小化(贪心算法,帕累托支配)
回归测试最小化(贪心算法,帕累托支配) 介绍 有时我们不能只是重新运行我们的测试(例如,当我们 换界面)。 回归测试可能很昂贵: (1)一些公司通宵运行回归测试套件。 (2) 对于嵌入式系统,我们可能必须测试正在使用的软件࿰…...

Python系列模块之标准库shutil详解
感谢点赞和关注 ,每天进步一点点!加油! 目录 一、shutil介绍 二 、使用详解 2.1 复制函数 2.1.1 shutil.copy 2.1.2 shutil.copy2 2.1.3 shutil.copyfile 2.1.4 shutil.copytree 2.2 移动文件 2.2.1 shutil.move 2.3 删除文件 2.3…...

pb如何播放Flash
---- Flash动画不仅包含动画,还可有声音、超文本连接,同时由于它是矢量格式文件,生成的这种包含动画、声音等的文件(*.swf)很小,非常适 合在网络上传输使用,因而在当前Web网页技术中得到很快发展。本文讨论在PowerBuilder6.5数据库编程中用Flash4提供的控件"Swflas…...

独立成分分析ICA
独立成分分析 ICA 1. 算法原理简介2.源信号与混合信号的差异2.1 独立性 Independence2.2 高斯性 Normality2.3 复杂性 Complexity 3.非高斯性的度量3.1 峭度 Kurtosis 参考文献 blind source separation (BSS) 1. 算法原理简介 mixing得到signal mixture过程: x 1…...

从零开始之如何在React Native中使用导航
好的,让我们开始学习如何在React Native中使用导航。 安装React Navigation 首先,你需要安装React Navigation库。在项目文件夹中打开终端窗口,并运行以下命令: npm install react-navigation/native 或者 yarn add react-nav…...

RAW、RGB 、YUV三种图像格式理解
文章目录 1. 背景2. 相关概念2.1 颜色与色彩空间2.2 RAW图像2.3 RGB图像2.4 YUV图像 3. 分类简图 RAW、RGB 、YUV三种图像格式理解 1. 背景 在工作中,经常听到用来描述图像格式的RAW,RGB与YUV,但一直没有系统的进行了解,处于局部认…...

关于对【mysql存储过程】的理解与简述
【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://blog.csdn.net/m0_69908381/article/details/130857854 出自【进步*于辰的博客】 【存储过程】这个知识点,我在大二下期学习【mys…...

贪吃蛇游戏的制作记录
关于蛇的实现代码 #include "snake.h" #include "globalvar.h" #include <graphics.h> int fangXiang 1;//方向 0 右 1 上 2 左 3 下 int snakeHang[100] { 10,11,12,13,14 };//蛇 每节所在行 int snakeLie[100] { 10,10,10,10,10 };//蛇 每节所…...

Go基础入门
Go是一种现代的、高效的、开源的编程语言,由Google开发。它的语法简洁、易于学习和使用,支持并发编程,特别适合构建网络应用和分布式系统。本篇文章将介绍Go语言的基础语法和常用特性,帮助初学者快速入门。 一、Go语言的基础语法…...

JavaScript教程(二)
BOM浏览器对象模型 什么是BOM BOM(Browser Object Model)即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是 window;BOM由一系列相关的对象构成,并且每个对象都提供了很多方…...

设计模式之代理模式
代理模式的定义是:为其他对象提供一种代理以控制对这个对象的访问。 因为代理类与服务类实现同样的接口,所以代理类能代替服务类提供给客户端。当客户端使用代理类时,代理类能对请求进行处理(例如增加访问控制、缓存请求结果、隐…...