制作根文件系统之Busybox init进程的启动过程分析
先来介绍一下什么是Busybox:它是将众多的UNIX命令集合进一个很小的可执行程序中。
在制作根文件系统之内核如何启动init进程中遗留了一个问题是/linuxrc是内核启动的第一个应用程序,那么它是什么?我们看到移植好的根文件系统环境,输入ls -al /linuxrc。可以看到:
lrwxrwxrwx Jul linuxrc -> bin/busybox
/linuxrc其实是指向Busybox的,它其实是Busybox下的一个程序,所以我们需要分析Busybox的源码来研究/linuxrc这个程序做的事情,当在移植好的根文件系统环境下输入/linuxrc可以看到:
# busybox linuxrc
init started: BusyBox v1.7.0 (-- :: CST)
starting pid , tty '': '/etc/init.d/rcS' Please press Enter to activate this console.
这就是执行linuxrc程序之后出现的界面,现在还不确定/linuxrc是Busybox下哪个文件,我们搜索“init started”,在busybox-1.7.0\init\Init.c中找到了它
message(MAYBE_CONSOLE | L_LOG, "init started: %s", bb_banner);
我们看到调用它的是init_main函数,接下去就是分析这个函数,init_main函数的功能大概可以概括为
1、设置处理信号函数
2、读取配置文件、解析配置文件
3、根据配置文件执行用户的程序或脚本
下面分别介绍
1、设置处理信号函数,restart, ctrlaltdel, and shutdown是一些按键事件,这些处理函数在接收到按下相关按键的信号后,进行处理
signal(SIGHUP, exec_signal);
signal(SIGQUIT, exec_signal);
signal(SIGUSR1, shutdown_signal);
signal(SIGUSR2, shutdown_signal);
signal(SIGINT, ctrlaltdel_signal);
signal(SIGTERM, shutdown_signal);
signal(SIGCONT, cont_handler);
signal(SIGSTOP, stop_handler);
signal(SIGTSTP, stop_handler);
2、读取和解析配置文件,先看一下配置文件的格式,文档位于example/inittab中
# inittab的格式为:
# <id>:<runlevels>:<action>:<process>
# id => /dev/id,用作终端:stdin、stdout、stderr:printf、scanf、err
# runlevels:忽略
# action :执行时机Valid actions include: sysinit, respawn, askfirst, wait, once,
restart, ctrlaltdel, and shutdown.
# process :应用程序或脚本
接着回到init_main函数,看到
parse_inittab();//解析inittab参数
找到parse_inittab函数,位于busybox-1.7.0\init\Init.c中
static void parse_inittab(void)
{
...
...
file = fopen(INITTAB, "r");//以只读方式打开/etc/inittab
...
while (fgets(buf, INIT_BUFFS_SIZE, file) != NULL) {
...
for (a = actions; a->name != ; a++) {
if (strcmp(a->name, action) == ) {
if (*id != '\0') {
if (strncmp(id, "/dev/", ) == )//去掉开头的/dev/
id += ;
strcpy(tmpConsole, "/dev/");
safe_strncpy(tmpConsole + , id,
sizeof(tmpConsole) - );
id = tmpConsole;
}
new_init_action(a->action, command, id);//创建一个init_action结构,以解析出来的参数填充它,然后将这个结构放入init_action_list链表
break;
}
}
...
}
}
这个函数的功能解释为打开/etc/inittab文件然后处理它,这个文件是以配置文件的格式存放的。看到函数最后会创建一个init_action结构,这个结构就是将配置文件里的内容一个个取出来,然后放在里面。最后链接到init_action_list链表中
struct init_action {
struct init_action *next;
int action;
pid_t pid;//进程号 by andy
char command[INIT_BUFFS_SIZE];//要执行的脚本命令
char terminal[CONSOLE_NAME_SIZE];//终端
};
这里再举个例子,下面是某个配置文件。以第一个为例子。action为askfirst执行时机;command为执行的命令或脚本为-/bin/sh;terminal为使用的中断为console
console::askfirst:-/bin/sh
::sysinit:/etc/init.d/rcS
3、根据配置文件执行用户的程序或脚本
接着看到,每个执行时机执行的内容,以下均为简写。
busybox-> init_main
parse_inittab
file = fopen(INITTAB, "r");//打开配置文件/etc/inittab
new_init_action //a、创建一个init_action结构,填充
//b、将这个结构放入init_action_list链表
run_actions(SYSINIT);
waitfor(a, ); //执行应用程序,等待它执行完毕
run(a) //创建process子进程
waitpid(runpid, &status, );//等待它结束
delete_init_action(a);//在init_action_list链表里删除
run_actions(WAIT);
waitfor(a, ); //执行应用程序,等待它执行完毕
run(a) //创建process子进程
waitpid(runpid, &status, );//等待它结束
delete_init_action(a);//在init_action_list链表里删除
run_actions(ONCE);
run(a); //创建process子进程
delete_init_action(a);//在init_action_list链表里删除
while() {
run_actions(RESPAWN);
if (a->pid == ) {
a->pid = run(a);
}
run_actions(ASKFIRST);
if (a->pid == ) {
a->pid = run(a);
打印:Please press Enter to activate this console.
等待回车
创建子进程
}
wpid = wait(NULL);//等待子进程退出
while (wpid > ) {
a->pid = ;//退出后就设置pid=0
}
其余三个restart, ctrlaltdel, and shutdown执行时机在按下按键的时候发生事件
}
大致总结一下每个执行时机:
SYSINIT:第一个执行,创建子进程,等待进程结束,将它从init_action_list链表里删除
WAIT:第二个执行,创建子进程,等待进程结束,将它从init_action_list链表里删除
ONCE:第三个执行,创建子进程,将它从init_action_list链表里删除
RESPAWN:循环执行
ASKFIRST:循环执行,打印:Please press Enter to activate this console,等待回车后,创建子程序-/bin/sh,就不再返回了
restart, ctrlaltdel, and shutdown:在按键按下的时候随时执行
这样就分析完了Busybox的init程序,ASKFIRST时机相关的脚本或命令执行以后,因为脚本有-/bin/sh,所以最终会进入sh进程。它位于shell\Ash.c下的ash_main函数,这个函数就不分析了。到这里从uboot开始一直到根文件系统下的第一个用户程序全部分析完成。
制作根文件系统之Busybox init进程的启动过程分析的更多相关文章
- 第4阶段——制作根文件系统之分析init进程(2)
本节目标: (1) 了解busybox(init进程和命令都放在busybox中) (2) 创建SI工程,分析busybox源码来知道init进程做了哪些事情 (3) 分析busybox中init进 ...
- 制作根文件系统之内核如何启动init进程
start_kernel其实也是内核的一个进程,它占用了进程号0,start_kernel的内容简写如下: asmlinkage void __init start_kernel(void) //内核 ...
- 利用busybox制作根文件系统
实际项目中可以使用Buildroot制作根文件系统 1.busybox源码下载及配置 https://busybox.net/downloads/ 1.1.修改Makefile (1) ARCH = ...
- 使用BusyBox制作根文件系统【转】
本文转载自:http://www.cnblogs.com/lidabo/p/5300180.html 1.BusyBox简介 BusyBox 是很多标准 Linux 工具的一个单个可执行实现.Busy ...
- 使用BusyBox制作根文件系统
1.BusyBox简介 BusyBox 是很多标准 Linux 工具的一个单个可执行实现.BusyBox 包含了一些简单的工具,例如 cat 和 echo,还包含了一些更大.更复杂的工具,例如 gre ...
- 通过busybox制作根文件系统
通过busybox制作根文件系统可以自定义选项,在制作的根文件系统中添加需要的命令,指定生成的根文件系统到相应的目录下. 一. 根文件系统的获取方式--->官网: https://busybox ...
- 通过busybox制作根文件系统详细过程
我在之前的uboot通过NFS挂载ubuntu根文件系统中也有实现过根文件系统的制作,那只是在ubuntu官网已经做好的根文件基础上安装一些自己所需的软解而已.而使用busybox制作根文件系统可以自 ...
- 使用Busybox-1.2.0制作根文件系统
使用Busybox-1.2.0制作根文件系统 cross-3.3.2 make-3.8.1 STEP 1: 创建根文件系统目录,主要包括以下目录/bin,/etc,/dev,/mnt,/sbin,/u ...
- 根文件系统及Busybox简介
转:http://blog.csdn.net/wqc02/article/details/8930184 1.根文件系统简介...2 2.Busybox简介...2 2.1Busybox简介...2 ...
随机推荐
- 通过AI自学习,Google让Pixel 3的人像模式更优秀
通过AI自学习,Google让Pixel 3的人像模式更优秀 Link: https://news.cnblogs.com/n/613720/ 虽然双摄手机已经在市场上普及,其所带来的人像模式.多倍变 ...
- MySQL 各种主流 SQLServer 迁移到 MySQL 工具对比
原地址:https://www.cnblogs.com/overblue/p/5796887.html Mss2sql:这个比较好用
- k8s operator
https://coreos.com/blog/introducing-operators.html Site Reliability Engineer(SRE)是通过编写软件来运行应用程序的人员. ...
- 我的第一篇博客之js的XXXX年XX月XX日 星期[日一-六] [上下]午 XX时:XX分
<!DOCTYPE html> <html> <head> <title>test</title> ...
- linux下WIFI的AP搜索、连接方法
wpa_supplicant -Dwext -ieth1 -c/etc/wpa_supplicant.conf &wpa_cli save_configwpa_cli reconfigure ...
- numpy 矩阵变换 reshape ravel flatten
1. 两者的区别在于返回拷贝(copy)还是返回视图(view),numpy.flatten()返回一份拷贝,对拷贝所做的修改不会影响(reflects)原始矩阵,而numpy.ravel()返回的是 ...
- java中excel导入\导出工具类
1.导入工具 package com.linrain.jcs.test; import jxl.Cell; import jxl.Sheet; import jxl.Workbook; import ...
- 仿造mongodb的存储方式存一些假数据
//存入数据 $data = json_encode($row); // 过滤 $data = addslashes($data); //读取数据 $falseData = stripslashes( ...
- php使用redis扩展以及安装redis(linux下)
一,安装redis 1,下载redis包:wget http://download.redis.io/releases/redis-2.8.9.tar.gz 2,解压redis包后,进入redis-2 ...
- 筛素数 poj 2739
题目链接:https://vjudge.net/problem/POJ-2739 输入一个数字n,判断有没有一段连续的素数之和大于n,如果有,计算总共有几种. 思路:用素数筛法求出10000以内的素数 ...