构建根文件系统之init进程分析
busybox是ls、cp等命令的集合。
执行ls时,实际上是执行了busybox ls
执行cp时,实际上是执行了busybox cp
分析init程序之前,再让我们回想一下我们的目标:u-boot启动内核,内核启动应用程序,内核是怎样启动应用程序呢,内核启动了init进程,位于/sbin/init中。我们最终的目的是启动客户程序,也就是说假如你是做手机的,希望启动一个手机的程序,假如是做监控的,那么就启动一个监控的程序的。客户各有不同,但都使用了linux系统,那么怎样加以区分呢?
init程序中应该有这样的内容:
读取配置文件,指定后面要执行的应用程序;
解析配置文件;
根据配置文件,执行用户的程序;
busybox ->init_main
parse_inittab();
file = fopen(INITTAB, "r");//#define INITTAB "/etc/inittab" 打开配置文件/etc/inittab
new_init_action(a->action, command, id); a.创建一个init_action的结构,并填充;
b.将init_action这个结构放入init_action_list链表中;
run_actions(SYSINIT);
static void run_actions(int action)
{
struct init_action *a, *tmp;
waitfor(a, 0); 执行应用程序,等待它执行完毕
run(a); 创建process子进程
wpid = waitpid(runpid, &status, 0); 等待它结束
delete_init_action(a); 在init_action_list链表中删除a
}
run_actions(WAIT)
static void run_actions(int action)
{
struct init_action *a, *tmp;
waitfor(a, 0); 执行应用程序,等待它执行完毕
run(a); 创建process子进程
wpid = waitpid(runpid, &status, 0); 等待它结束
delete_init_action(a); 在init_action_list链表中删除a
}
run_actions(ONCE)
run(a); 创建process子进程
delete_init_action(a); 不会等待结束,就在init_action_list链表中删除a
while(1){
run_actions(RESPAWN)
if (a->pid == 0) {
a->pid = run(a);
}
run_actions(ASKFIRST);
if (a->pid == 0) {
a->pid = run(a);
}
wpid = wait(NULL);//等待子进程退出
while (wpid > 0) {
a->pid = 0; //退出后,就设置pid等于0
}
}
在/etc/inittab文件控制下,init进程的行为总结如下:
a.在系统启动前期,init进程首先启动<action>为sysinit、wait、once的三类子进程;
b.在系统正常运行期间,init进程首先启动<action>为respawn、askfirst的两类子进程,并监视它们,发现某个子进程退出时重新启动它
c.在系统退出时,执行<action>为shutdown、restart、ctrlaltdel的三类子进程(之一或全部)
最小的根文件系统:
/dev/console /dev/null在busybox init程序中,还会检查这个设备是否可以打开,如果不能打开则使用/dev/null
init来源于busybox
/etc/inittab
配置文件中指定的应用程序
c库
假设没有配置文件,从默认的new_init_action中退出配置文件:
#inittab的格式:
#<id>:<runlevels>:<action>:<process>
#id=>/dev/id,最终用作终端。stdin、stdout、stderr
#runlevels:完全可以忽略 <runlevels>: The runlevels field is completely ignored
#action:执行时机
<action>: sysinit, respawn, askfirst, wait, once,
restart, ctrlaltdel, and shutdown.
#process:应用程序或脚本
/* Reboot on Ctrl-Alt-Del */
new_init_action(CTRLALTDEL, "reboot", "");
推出 ::CTRLALTDEL:reboot
/* Umount all filesystems on halt/reboot */
new_init_action(SHUTDOWN, "umount -a -r", "");
推出 ::SHUTDOWN:umount -a -r
/* Prepare to restart init when a HUP is received */
new_init_action(RESTART, "init", "");
推出: ::RESTART:init
/* Askfirst shell on tty1-4 */
new_init_action(ASKFIRST, bb_default_login_shell, "");
new_init_action(ASKFIRST, bb_default_login_shell, VC_2);
new_init_action(ASKFIRST, bb_default_login_shell, VC_3);
new_init_action(ASKFIRST, bb_default_login_shell, VC_4);
依次推出 ::askfirst:-/bin/sh
/dev/tty2::askfirst:-/bin/sh
/dev/tty3::askfirst:-/bin/sh
/dev/tty4::askfirst:-/bin/sh
/* sysinit */
new_init_action(SYSINIT, INIT_SCRIPT, "");
#define INIT_SCRIPT "/etc/init.d/rcS"
推出 ::sysinit:/etc/init.d/rcS
以new_init_action(ASKFIRST, bb_default_login_shell, VC_2);为例进行分析:
#define LIBBB_DEFAULT_LOGIN_SHELL "-/bin/sh" ,
# define VC_2 "/dev/tty2"因此new_init_action(ASKFIRST, bb_default_login_shell, VC_2)变为
new_init_action(ASKFIRST, "-/bin/sh" , "/dev/tty2")
static void new_init_action(int action, const char *command, const char *cons)这个函数里面有个结构体init_action ,看一下这个结构体中的成员:
struct init_action {
struct init_action *next;
int action; 执行时机
pid_t pid;
char command[INIT_BUFFS_SIZE];应用程序或脚本
char terminal[CONSOLE_NAME_SIZE];终端
};
因此可以推断new_init_action这个函数做了这几件事:
a.创建一个init_action的结构,并填充;
b.将init_action这个结构放入init_action_list链表中;
构建根文件系统之init进程分析的更多相关文章
- 根文件系统之init
title: 根文件系统之init tag: arm date: 2018-11-12 18:53:23 --- 引入 在Kernel源码分析中,了解到init_post是在挂载根文件系统之后执行应用 ...
- linux2.6.30.4内核移植(5)——构建根文件系统(yaffs文件系统格式的镜像)
一.首先编译并安装BusyBox 这里使用的交叉编译器还是3.4.5. 注意:编译内核.编译BusyBox以及编译文件系统中的所有应用程序的交叉编译器要使用同一个版本. 1.获取BusyBox源码 下 ...
- Busybox构建根文件系统和制作Ramdisk
定制根文件系统的方法很多,最常用的是使用BusyBox来构建定制根文件系统.它集成压缩了Linux的许多工具和命令,可以使用户迅速方便地建立一套相对完整.功能丰富的文件系统,其中包括大量常用的应用 ...
- 使用busybox构建根文件系统
当我们在Qemu上运行起来自己编译的内核之后,需要使用busybox构建一个文件系统,将此文件系统挂载上去就可以使用busybox提供的各种命令了. 1.编译安装busybox 源码下载地址:http ...
- android init进程分析 init脚本解析和处理
(懒人近期想起我还有csdn好久没打理了.这个android init躺在我的草稿箱中快5年了.略微改改发出来吧) RC文件格式 rc文件是linux中常见的启动载入阶段运行的文件.rc是run co ...
- 韦东山笔记之用busybox构建根文件系统
1 百度搜索busybox进入busybox官网(https://busybox.net/)作者:恒久力行 QQ:624668529 点击左侧DownloadSource下载最新稳定版的busybo ...
- android init进程分析 ueventd
转自:http://blog.csdn.net/freshui/article/details/2132299 (懒人最近想起我还有csdn好久没打理了,这个Android init躺在我的草稿箱中快 ...
- 构建根文件系统之busybox
配置busybox 首先将busybox的压缩包放入服务器进行解压缩: busybox集合了几百个命令,在一般的系统中并不需要全部使用.可以通过配置busybox来选择这些命令.定制某些命令的功能(选 ...
- 第4阶段——制作根文件系统之编译配置安装busybox(3)
在上一节分析出制作一个最小的根文件系统至少需要: (1)/dev/console(终端控制台, 提供标准输入.标准输出以及标准错误) /dev/null (为空的话就是/dev/null, 所有写到 ...
随机推荐
- Pwnable-leg
Download : http://pwnable.kr/bin/leg.c Download :http://pwnable.kr/bin/leg.asm 友链 https://blog.csdn. ...
- 经典损失函数:交叉熵(附tensorflow)
每次都是看了就忘,看了就忘,从今天开始,细节开始,推一遍交叉熵. 我的第一篇CSDN,献给你们(有错欢迎指出啊). 一.什么是交叉熵 交叉熵是一个信息论中的概念,它原来是用来估算平均编码长度的.给定两 ...
- 判断101-200之间有多少个素数,并输出所有素数,方法:用一个数分别去除2到sqrt(这个数),如果能被整除, 则表明此数不是素数,反之是素数。
<?php$sum=0;for($i=101;$i<=200;$i++){ for($j=2;$j<=sqrt($i);$j++) { if($i%$j==0 ...
- NOIP2007 奖学金 结构体排序
是结构体排序的练习题,可供选手们巩固结构体排序的一些相关内容. 关于结构体排序 1.结构体定义 struct student { int num,a,b,c,sum; }p[]; 2.结构体初始化 ; ...
- Semantic 3D
Semantic 3D 这个数据级别的训练集有一个小BUG,是这个neugasse_station1_xyz_intensity_rgb.7z, 解压之后的名字是station1_xyz_intens ...
- Codeforces Round #596 (Div. 2, based on Technocup 2020 Elimination Round 2) C. p-binary 水题
C. p-binary Vasya will fancy any number as long as it is an integer power of two. Petya, on the othe ...
- Educational Codeforces Round 69 (Rated for Div. 2) D. Yet Another Subarray Problem 背包dp
D. Yet Another Subarray Problem You are given an array \(a_1, a_2, \dots , a_n\) and two integers \( ...
- Ubuntu 安装git及git命令
1.检查git是否已经安装,输入git version命令即可,如果没有显示版本号表示没有安装git 2.安装git sudo apt-get install git 3.配置git全局环境git c ...
- 【Java并发专题之二】Java线程基础
使用线程更好的提高资源利用率,但也会带来上下文切换的消耗,频繁的内核态和用户态的切换消耗,如果代码设计不好,可能弊大于利. 一.线程 进程是分配资源的最小单位,线程是程序执行的最小单位:线程是依附于进 ...
- npm ERR! Cannot read property 'resolve' of undefined
一 .有可能是版本过低,或者软件损坏,重新安装一下试试 地址