busybox init进程分析
2015-08-24 18:01
309 查看
busybox init进程分析
参考文献 http://blog.chinaunix.net/uid-20788636-id-1841289.html
一. Busybox启动流程分析
init进程是由内核启动的第一个也是惟一的一个用户进程,它根据配置文件决定启动哪些程序,比如执行某些脚本,启动shell,运行用户指定的程序等。init进程是后续所有进程的发起者,比如init进程启动/bin/sh程序后,才能够在控制台上输入各种命令。
init进程的执行程序通常是sbin/init,上面讲述的init进程的作用只不过是/sbin/init这个程序的功能。在嵌入式领域,通常使用Busybox集成的init程序.嵌入式根目录下的bin,sbin和usr目录以及linuxc通常就是Busybox。
1、在kernel/init/main.c的init函数中有如下代码:
if(execute_command)
execve(execute_command,argv_init,envp_init);
execve("/sbin/init",argv_init,envp_init);
bootloader会传给内核的main函数 init=/linuxrc这个参数,于是就会执行下面的这句
execute_command = "linuxrc",busybox中_install目录下的linuxrc是Busybox的一个软链接,指向/bin/busybox,而/sbin/init也是/bin/busybox的符号链接,因此这个linxrc基本没有实际的意义只是一个连接作用。我们可以重写linuxrc,添加自己的一些初始化的东西。这样就可以把Linux内核中的init程序和Busybox中的init程序结合起来了。
2、Busybox init进程启动流程
Busybox是目标板系统上执行的第一个应用程序,当调用Busybox它会执行Busybox自身的init进程。
Busybox initt 程序对应的代码在init/init.c文件中。
二. Busybox调用init.c文件里init_main()函数
#define LIBBB_DEFAULT_LOGIN_SHELL "-/bin/sh" //这些是定义,下面有用到
extern const char bb_default_login_shell[];
/* "/bin/sh" */
# define CURRENT_VC "/dev/tty0"
# define VC_1 "/dev/tty1"
# define VC_2 "/dev/tty2"
# define VC_3 "/dev/tty3"
# define VC_4 "/dev/tty4"
# define VC_5 "/dev/tty5"
#define INIT_SCRIPT "/etc/init.d/rcS" /* Default sysinit script. */
{
parse_inittab()
{
parser_t *parser= config_open2("/etc/inittab", fopen_for_read);//打开配置文件/etc/inittab
①if (parser == NULL)
#endif
{ ... } //默认配置,看下面解说
②new_init_action() // 作用: 1.创建一个init_action结构,填充参数
2.把这个结构放入init_action_list链表*/
}
run_actions(SYSINIT);
waitfor(run(a)); //执行应用程序,等待它执行完毕,并创建process子进程
delete_init_action(a); //在init_action_list里删除
run_actions(WAIT);
waitfor(run(a)); //执行应用程序,等待它执行完毕,并创建process子进程
delete_init_action(a); //在init_action_list里删除
run_actions(ONCE);
run(a); //创建process子进程
delete_init_action(a); //在init_action_list里删除
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区别:打印Please press Enter to activate this console
等待回车
创建子进程
wpid = wait(NULL); //等待进程结束
while (wpid > 0) {
a->pid = 0; //退出后,就设置pid=0;
}
}
}
①从默认的new_init.d_action反推出默认的配置文件, 如下
if (parser == NULL)
#endif
{
/* 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 QUIT is received */
new_init_action(RESTART, "init", "");
/* Askfirst shell on tty1-4 */
new_init_action(ASKFIRST, bb_default_login_shell, "");
//TODO: VC_1 instead of ""? "" is console -> ctty problems -> angry users
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;
}
以上把new_init_action()变为:
//按这个格式 :<id>:<runlevels>:<action>:<process>
::CTRLALTDEL:reboot //id=terminal=cons
::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
②static void new_init_action(uint8_t action_type, const char *command, const char *cons)//函数原型
调用 new_init_action(ASKFIRST, bb_default_login_shell, VC_2) = new_init_action(ASKFIRST,"-/bin/sh","/dev/tty2" )
//init_action结构体
struct init_action {
struct init_action *next;
pid_t pid;
4000
//进程号
uint8_t action_type;
char terminal[CONSOLE_NAME_SIZE]; //终端
char command[COMMAND_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 */
if ((strcmp(a->command, command) == 0)
&& (strcmp(a->terminal, cons) == 0)
) {
a->action_type = action_type;
return;
}
last = a;
}
inittab文件里代码的格式:
<id>:<runlevels>:<action>:<process>
Id =>/dev/id //用作终端terminal:stdin,stdout,stderr:printf,scanf,err
Runlevels : 可忽略
Action :执行时机 :Valid actions include :sysinit,respawd,askfirst,wait,once,restart,ctrialtdel,and shutdown.
Process :应用程序和脚本
最小根文件系统需要的项:
① /dev/console /dev/null
②init本身,即busybox
③/etc/inittab
④配置文件中的制定程序
⑤库
参考文献 http://blog.chinaunix.net/uid-20788636-id-1841289.html
一. Busybox启动流程分析
init进程是由内核启动的第一个也是惟一的一个用户进程,它根据配置文件决定启动哪些程序,比如执行某些脚本,启动shell,运行用户指定的程序等。init进程是后续所有进程的发起者,比如init进程启动/bin/sh程序后,才能够在控制台上输入各种命令。
init进程的执行程序通常是sbin/init,上面讲述的init进程的作用只不过是/sbin/init这个程序的功能。在嵌入式领域,通常使用Busybox集成的init程序.嵌入式根目录下的bin,sbin和usr目录以及linuxc通常就是Busybox。
1、在kernel/init/main.c的init函数中有如下代码:
if(execute_command)
execve(execute_command,argv_init,envp_init);
execve("/sbin/init",argv_init,envp_init);
bootloader会传给内核的main函数 init=/linuxrc这个参数,于是就会执行下面的这句
execute_command = "linuxrc",busybox中_install目录下的linuxrc是Busybox的一个软链接,指向/bin/busybox,而/sbin/init也是/bin/busybox的符号链接,因此这个linxrc基本没有实际的意义只是一个连接作用。我们可以重写linuxrc,添加自己的一些初始化的东西。这样就可以把Linux内核中的init程序和Busybox中的init程序结合起来了。
2、Busybox init进程启动流程
Busybox是目标板系统上执行的第一个应用程序,当调用Busybox它会执行Busybox自身的init进程。
Busybox initt 程序对应的代码在init/init.c文件中。
二. Busybox调用init.c文件里init_main()函数
#define LIBBB_DEFAULT_LOGIN_SHELL "-/bin/sh" //这些是定义,下面有用到
extern const char bb_default_login_shell[];
/* "/bin/sh" */
# define CURRENT_VC "/dev/tty0"
# define VC_1 "/dev/tty1"
# define VC_2 "/dev/tty2"
# define VC_3 "/dev/tty3"
# define VC_4 "/dev/tty4"
# define VC_5 "/dev/tty5"
#define INIT_SCRIPT "/etc/init.d/rcS" /* Default sysinit script. */
{
parse_inittab()
{
parser_t *parser= config_open2("/etc/inittab", fopen_for_read);//打开配置文件/etc/inittab
①if (parser == NULL)
#endif
{ ... } //默认配置,看下面解说
②new_init_action() // 作用: 1.创建一个init_action结构,填充参数
2.把这个结构放入init_action_list链表*/
}
run_actions(SYSINIT);
waitfor(run(a)); //执行应用程序,等待它执行完毕,并创建process子进程
delete_init_action(a); //在init_action_list里删除
run_actions(WAIT);
waitfor(run(a)); //执行应用程序,等待它执行完毕,并创建process子进程
delete_init_action(a); //在init_action_list里删除
run_actions(ONCE);
run(a); //创建process子进程
delete_init_action(a); //在init_action_list里删除
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区别:打印Please press Enter to activate this console
等待回车
创建子进程
wpid = wait(NULL); //等待进程结束
while (wpid > 0) {
a->pid = 0; //退出后,就设置pid=0;
}
}
}
①从默认的new_init.d_action反推出默认的配置文件, 如下
if (parser == NULL)
#endif
{
/* 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 QUIT is received */
new_init_action(RESTART, "init", "");
/* Askfirst shell on tty1-4 */
new_init_action(ASKFIRST, bb_default_login_shell, "");
//TODO: VC_1 instead of ""? "" is console -> ctty problems -> angry users
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;
}
以上把new_init_action()变为:
//按这个格式 :<id>:<runlevels>:<action>:<process>
::CTRLALTDEL:reboot //id=terminal=cons
::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
②static void new_init_action(uint8_t action_type, const char *command, const char *cons)//函数原型
调用 new_init_action(ASKFIRST, bb_default_login_shell, VC_2) = new_init_action(ASKFIRST,"-/bin/sh","/dev/tty2" )
//init_action结构体
struct init_action {
struct init_action *next;
pid_t pid;
4000
//进程号
uint8_t action_type;
char terminal[CONSOLE_NAME_SIZE]; //终端
char command[COMMAND_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 */
if ((strcmp(a->command, command) == 0)
&& (strcmp(a->terminal, cons) == 0)
) {
a->action_type = action_type;
return;
}
last = a;
}
inittab文件里代码的格式:
<id>:<runlevels>:<action>:<process>
Id =>/dev/id //用作终端terminal:stdin,stdout,stderr:printf,scanf,err
Runlevels : 可忽略
Action :执行时机 :Valid actions include :sysinit,respawd,askfirst,wait,once,restart,ctrialtdel,and shutdown.
Process :应用程序和脚本
最小根文件系统需要的项:
① /dev/console /dev/null
②init本身,即busybox
③/etc/inittab
④配置文件中的制定程序
⑤库
相关文章推荐
- U-Boot源码分析及移植-fs2410
- QEMU上运行BusyBox详解
- 极度简约,最小 Linux 发行版 Tiny Core Linux 7.1 发布
- 在 Android 模拟器中安装 busybox
- android手机安装busybox步骤
- 编译busybox出现cannot find -lcrypt错误
- U-BOOT源码分析及移植
- Busybox的安装步骤
- U-Boot启动过程--详细版的完全分析(二)
- U-Boot-2009-03移植笔记(移植准备)
- U-Boot-2009-03移植笔记(点亮第一展灯)
- U_boot 的 bootcmd 和bootargs参数详解
- U-Boot移植全程指导
- u-boot1.1.6-undefined reference to "raise"
- 为omap3530使用BusyBox构建linux文件系统及添加telnet服务
- 09课01节 u-boot-1.1.16编译补丁;
- Android移植busybox
- u-boot模仿
- 自定义u-boot启动logo的方法
- 2440 u-boot编译