马生殖解剖图:分析busybox中init程序的运行过程| Linux交流区
来源:百度文库 编辑:偶看新闻 时间:2024/05/21 22:20:01
移植uboot的目的是启动内核,启动内核的目的是运行应用程序,从内核的启动流程中可以知道内核启动的第一个应用程序就是busybox里的/sbin/init进程!
但是我们的最终目的不是启动init进程,而是运行客户的程序!
那么init进程是如何选择性的运行客户的程序呢?我们猜测init进程肯定需要:
(1) 读取一个配置文件
(2) 解析该配置文件
(3) 根据配置文件执行客户的程序
下面我们来阅读busybox中init程序的源码,在init.c中的init_main()中:
1.首先是设置信号
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.初始化/dev/console
console_init();
3.解析配置文件
if (argc > 1
&& (!strcmp(argv[1], "single") || !strcmp(argv[1], "-s") || LONE_CHAR(argv[1], '1'))
) {
} else {
parse_inittab();
}
内核启动/sbin/init是没有传如何参数,所以进入parse_inittab()函数,
我们进入到该函数:
file = fopen(INITTAB, "r");
#define INITTAB "/etc/inittab"
由此可以知道init进程读取的配置文件就是/etc/inittab,busybox中的inittab文件中规定了/etc/inittab内容的填写格式如下:
:::
Id:id会加上一个/dev前缀作为一个控制终端(stdin,stdout,stderr)
Runlevel:忽略
Action:执行的时机,包括SYSINIT,WAIT,ONCE, RESPAWN,ASKFIRST等
Process:要执行的应用程序或者脚本
继续分析parse_inittab():
if (file == NULL)
{
new_init_action(CTRLALTDEL, "reboot", ""); new_init_action(SHUTDOWN, "umount -a -r", "");
new_init_action(RESTART, "init", "");
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);
new_init_action(SYSINIT, INIT_SCRIPT, "");
return;
#if ENABLE_FEATURE_USE_INITTAB
}
如果配置文件/etc/inittab不存在的话则执行if语句,也就是说如果没/etc/inittab的话init进程会直接调用new_init_action来构造默认配置项,根据if语句里的内容,我们可以反推出等效的/etc/inittab的内容如下:
::CTRLALTDEL:reboot
::SHUTDOWN:umount -a –r
::RESTART:init
::ASKFIRST:-/bin/ah
tty2:: ASKFIRST:-/bin/sh
tty3:: ASKFIRST:-/bin/sh
tty4:: ASKFIRST:-/bin/sh
::SYSINIT:/etc/init.d/rcS
继续分析parse_inittab():
后面就是对配置文件/etc/inittab里的内容里的解析了,如#则视作注释等等,最后就调用new_init_action(a->action, command, id);将/etc/inittab里的每一条配置项做成一个init_action结构体并添加到具有相同执行时机的init_action_list中去。说到底解析/etc/inittab这个配置文件就是为了把各配置项添加到对应的init_action_list中去。
这样parse_inittab()这个函数就结束了,我们继续看init_main()这个函数:
4.开始运行parse_inittab()帮我们添加到init_action_list中的程序或脚本:
run_actions(SYSINIT);
run_actions(WAIT);
run_actions(ONCE);
while (1)
{
run_actions(RESPAWN);
run_actions(ASKFIRST);
}
run_actions为运行一类程序或脚本,这里的一类就是按照执行时机来分类的。由上面这段代码我们就可以看出执行时机的优先级了:SYSINIT> WAIT> ONCE> RESPAWN> ASKFIRST,具体的可以继续分析源码
但是我们的最终目的不是启动init进程,而是运行客户的程序!
那么init进程是如何选择性的运行客户的程序呢?我们猜测init进程肯定需要:
(1) 读取一个配置文件
(2) 解析该配置文件
(3) 根据配置文件执行客户的程序
下面我们来阅读busybox中init程序的源码,在init.c中的init_main()中:
1.首先是设置信号
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.初始化/dev/console
console_init();
3.解析配置文件
if (argc > 1
&& (!strcmp(argv[1], "single") || !strcmp(argv[1], "-s") || LONE_CHAR(argv[1], '1'))
) {
} else {
parse_inittab();
}
内核启动/sbin/init是没有传如何参数,所以进入parse_inittab()函数,
我们进入到该函数:
file = fopen(INITTAB, "r");
#define INITTAB "/etc/inittab"
由此可以知道init进程读取的配置文件就是/etc/inittab,busybox中的inittab文件中规定了/etc/inittab内容的填写格式如下:
Id:id会加上一个/dev前缀作为一个控制终端(stdin,stdout,stderr)
Runlevel:忽略
Action:执行的时机,包括SYSINIT,WAIT,ONCE, RESPAWN,ASKFIRST等
Process:要执行的应用程序或者脚本
继续分析parse_inittab():
if (file == NULL)
{
new_init_action(CTRLALTDEL, "reboot", ""); new_init_action(SHUTDOWN, "umount -a -r", "");
new_init_action(RESTART, "init", "");
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);
new_init_action(SYSINIT, INIT_SCRIPT, "");
return;
#if ENABLE_FEATURE_USE_INITTAB
}
如果配置文件/etc/inittab不存在的话则执行if语句,也就是说如果没/etc/inittab的话init进程会直接调用new_init_action来构造默认配置项,根据if语句里的内容,我们可以反推出等效的/etc/inittab的内容如下:
::CTRLALTDEL:reboot
::SHUTDOWN:umount -a –r
::RESTART:init
::ASKFIRST:-/bin/ah
tty2:: ASKFIRST:-/bin/sh
tty3:: ASKFIRST:-/bin/sh
tty4:: ASKFIRST:-/bin/sh
::SYSINIT:/etc/init.d/rcS
继续分析parse_inittab():
后面就是对配置文件/etc/inittab里的内容里的解析了,如#则视作注释等等,最后就调用new_init_action(a->action, command, id);将/etc/inittab里的每一条配置项做成一个init_action结构体并添加到具有相同执行时机的init_action_list中去。说到底解析/etc/inittab这个配置文件就是为了把各配置项添加到对应的init_action_list中去。
这样parse_inittab()这个函数就结束了,我们继续看init_main()这个函数:
4.开始运行parse_inittab()帮我们添加到init_action_list中的程序或脚本:
run_actions(SYSINIT);
run_actions(WAIT);
run_actions(ONCE);
while (1)
{
run_actions(RESPAWN);
run_actions(ASKFIRST);
}
run_actions为运行一类程序或脚本,这里的一类就是按照执行时机来分类的。由上面这段代码我们就可以看出执行时机的优先级了:SYSINIT> WAIT> ONCE> RESPAWN> ASKFIRST,具体的可以继续分析源码
INIT进程是Linux系统中运行的第一个进程
分析以下程序的运行结果.
UNIX中init的用途和意义?
怎样用C++编写分配一块内存的程序init。
如何删除XP”开始”运行中曾经打开过的程序???
如何查找出刚刚运行过的程序?
什么程序可查出过去运行过的程序~~~
VB中判断要运行的程序是否运行
程序运行中问题
程序正在运行中
分析下我的程序是否中病毒?
在appman的运行程序中运行哪些程序是正常的?
在运行中能运行哪些程序?
如何隐藏运行中程序
关于VF中LOAD和INIT事件的区别……
VC++中如何创建脱离OS运行的程序
如何在win2000中禁止某些程序的自动运行?
等如关掉计算机中自动运行的程序?
如何要VB运行的程序中禁用键盘
可以在Windows环境中运行的程序编程软件?
关于在2000中运行XP程序的问题
怎样刚刚创建的文件夹中运行程序???
drjava上编好的程序可以在JCreator中运行
能否检测局域网中电脑的运行程序