本文主要是介绍根文件系统init进程分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
U-boot:启动内核
内核 :启动应用程序
内核启动的第一个应用程序是/sbin/init,启动的最终目的是启动其他的应用程序。
init程序 (1)读取配置文件
(2)解析配置文件
(3)执行应用程序(根据配置文件)
配置文件:(1)指定应用程序(2)什么时候执行
busybody->init_main (init进程本身就是busybox)
parse_inittab() 解析配置文件
file = fopen(INITTAB, "r") 打开配置文件,#define INITTAB "/etc/inittab",配置文件一般都放在/etc目录下
new_init_action 如果配置文件不存在,则执行默认的配置项
new_init_action:(1)创建一个init_action结构、填充
(2)把这个结构放入init_action_list链表
run_actions(SYSINIT);
waitfor(a, 0); 执行应用程序,等待它执行完毕
run(a) 创建process子进程
waitpid(runpid, &status, 0); 等待它结束
delete_init_action(a); 在init_action_list链表里删除
run_actions(WAIT);
waitfor(a, 0); 执行应用程序,等待它执行完毕
run(a) 创建process子进程
waitpid(runpid, &status, 0); 等待它结束
delete_init_action(a); 在init_action_list链表里删除
run_actions(ONCE);
run(a);
delete_init_action(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);
RESPAWN与ASKFIRST区别
(1)打印:Please press Enter to activate this console.
(2)等待回车
创建进程
}
/* Wait for a child process to exit */
wpid = wait(NULL); 等待子进程退出
while (wpid > 0) {
a->pid = 0; 退出后,就设置pid=0
}
inittab格式:
<id>:<runlevels>:<action>:<process>
<id> => /dev/id(加一个/dev前缀),用作终端:stdin,stdout,stderr
<runlevels> 可以完全忽略
<action> 指示何时执行
<process> 应用程序或脚本
static void new_init_action(int action, const char *command, const char *cons)
struct init_action {
struct init_action *next;
int action;
pid_t pid;
char command[INIT_BUFFS_SIZE];
char terminal[CONSOLE_NAME_SIZE];
};
for (a = last = init_action_list; a; a = a->next) {
/* don't enter action if it's already in the list,
* but do overwrite existing actions */ 如果原来链表中已经有了这个action,则覆盖它
if ((strcmp(a->command, command) == 0)
&& (strcmp(a->terminal, cons) == 0)
) {
a->action = action;
return;
}
last = a;
}
如果没有这个action则创建它:
new_action = xzalloc(sizeof(struct init_action));分配内存
if (last) {
last->next = new_action;
} else {
init_action_list = new_action;
}
strcpy(new_action->command, command);
new_action->action = action;
strcpy(new_action->terminal, cons);
new_init_action(ASKFIRST, bb_default_login_shell, VC_2);
bb_default_login_shell #define LIBBB_DEFAULT_LOGIN_SHELL "-/bin/sh"
VC_2 # define VC_2 "/dev/tty2"
new_init_action(ASKFIRST, "-/bin/sh", "/dev/tty2");
如果配置文件不存在,则执行默认的配置项
file = fopen(INITTAB, "r");
if (file == NULL) {
/* No inittab file -- set up some default behavior */
/* Reboot on Ctrl-Alt-Del */
new_init_action(CTRLALTDEL, "reboot", "");
/* Umount all filesystems on halt/reboot */
new_init_action(SHUTDOWN, "umount -a -r", "");
/* Swapoff on halt/reboot */
if (ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "swapoff -a", "");
/* Prepare to restart init when a HUP is received */
new_init_action(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);
/* sysinit */
new_init_action(SYSINIT, INIT_SCRIPT, "");
return;
}
inittab格式:
<id>:<runlevels>:<action>:<process>
<action>: Valid actions include: sysinit, respawn, askfirst, wait, once,
# restart, ctrlaltdel, and shutdown.
从默认的new_init_action反推出默认的配置文件:
::ctrlaltdel:reboot
::shutdown:umount -a -r
::restart:init
::askfirst:-/bin/sh
tty2::askfirst:-/bin/sh
tty3::askfirst:-/bin/sh
tty4::askfirst:-/bin/sh
::sysinit:/etc/init.d/rcs
最小根文件系统:
(1)/dev/console /dev/null
(2)/init=>busybox init本身就是busybox
(3)/etc/inittab 配置文件
(4)配置文件指定的应用程序
(5)库
这篇关于根文件系统init进程分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!