ARM-Linux移植之(三)——init进程启动流程分析

 

我们通常使用Busybox来构建根文件系统的必要的应用程序。Busybox通过传入的参数来决定执行何种操作。当init进程启动时,实际上调用的是Busybox的init_main()函数,下面我们来分析这个函数,看init进程究竟是怎样一个流程。我分析的Busybox源码是1.7.0版本的,其他版本会略有不同。部分代码省略我们只看关键性代码。

 

首先看init_main函数

 

01.int init_main(int argc, char **argv);  
02.int init_main(int argc, char **argv)  
03.{  
04.    ……………………………..  
05.    ……………………………..  
06.    //初始化控制台  
07.    console_init();  
08.    ………………………………  
09.  
10.    if (argc > 1  
11.     && (!strcmp(argv[1], "single") || !strcmp(argv[1], "-s") || LONE_CHAR(argv[1], '1'))  
12.    ) {  
13.        new_init_action(RESPAWN, bb_default_login_shell, "");  
14.    } else {  
15.        //因为我们启动的init进程没有任何参数,所有argc==1,执行的是这一句  
16.        parse_inittab();  
17.    }  
18.    …………………………………………  
19.    …………………………………………  
20.    run_actions(SYSINIT);   //运行inittab配置文件中acthion为SYSINIT的进程  
21.    run_actions(WAIT);  //运行inittab配置文件中action为WAIT的进程  
22.  
23.  
24.    run_actions(ONCE);  //运行inittba配置文件中action为ONCE的进程  
25.    ………………………………………………  
26.    while (1) {  
27.        /*  
28.        运行inittab配置文件中action为RESPAWN和ASKFIRST的进程,一旦退出则重新启动  
29.        */  
30.        run_actions(RESPAWN);     
31.        run_actions(ASKFIRST);  
32.  
33.        wpid = wait(NULL);  
34.        while (wpid > 0) {  
35.                    a->pid = 0;  
36.            }  
37.            wpid = waitpid(-1, NULL, WNOHANG);  
38.          
39.    }  
40.}  


 

parse_inittab实际上对/etc/inittab文件里面的配置进行解释,如果没有,则设置一些默认设置。

我们先来看看这个inittab这个文件里面的配置格式,这个在busybox文件里面的inittab文件里面有说明

<id>:<runlevels>:<action>:<process>

id表示输出输入设备,这个不需要设置,因为/etc/console已经设为标准输入输出了,如不设置,则从控制台输入输出。

runlevels 这个参数完全忽略

action 运行时机,它表示inittab解释后的运行顺序,它有sysinit, respawn, askfirst, wait, once,restart, ctrlaltdel, andshutdown.这个值可选择。

process 就是要启动的进程。

 

下面来看prase_inittab这个函数

01.static void parse_inittab(void)  
02.{  
03.…………………………………………………  
04.…………………………………………………  
05.  
06.    /*INITTAB是一个宏 #define INITTAB      "/etc/inittab"     
07.    可以看得出来它打开了/etc/inittab这个文件*/  
08.  
09.    file = fopen(INITTAB, "r");  
10.  
11.    //如果没有这个文件,则调用new_init_action进行一些默认的操作  
12.    if (file == NULL) {  
13.        new_init_action(CTRLALTDEL, "reboot", "");  
14.        new_init_action(SHUTDOWN, "umount -a -r", "");  
15.        if (ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "swapoff -a", "");  
16.        new_init_action(RESTART, "init", "");  
17.        new_init_action(ASKFIRST, bb_default_login_shell, "");  
18.        new_init_action(ASKFIRST, bb_default_login_shell, VC_2);  
19.        new_init_action(ASKFIRST, bb_default_login_shell, VC_3);  
20.        new_init_action(ASKFIRST, bb_default_login_shell, VC_4);                         new_init_action(SYSINIT, INIT_SCRIPT, "");  
21.  
22.        return;  
23.    }  
24.    …………………………………………………  
25.…………………………………………………  
26.        /*果inittab文件里面有内容就将里面的内容一行一行读出来,然后调用new_init_action进行操作*/  
27.    while (fgets(buf, INIT_BUFFS_SIZE, file) != NULL) {  
28.        /* Ok, now process it */  
29.        for (a = actions; a->name != 0; a++) {  
30.            if (strcmp(a->name, action) == 0) {  
31.                if (*id != '\0') {  
32.                    if (strncmp(id, "/dev/", 5) == 0)  
33.                        id += 5;  
34.                    strcpy(tmpConsole, "/dev/");  
35.                    safe_strncpy(tmpConsole + 5, id,  
36.                        sizeof(tmpConsole) - 5);  
37.                    id = tmpConsole;  
38.                }  
39.                new_init_action(a->action, command, id);  
40.                break;  
41.            }  
42.        }  
43.    …………………………………………………  
44.…………………………………………………  
45.    }  
46.    fclose(file);  
47.}  


 

这个new_init_action函数,它实际上是将inittab里面的action相同的操作串成一个链表。

下面我们再来分析init_main执行prase_inittab之后执行的操作

可以看出init_main执行prase_initab对inittab文件里面的配置进行解释之后,会先执行运行时机为SYSINIT的进程,让执行WAIT时机的,接着是ONCE的,然后在一个while(1)函数里面运行RESPAWN和ASKFIRST时机的,一旦这两个时机里面的进程被杀死,就会把他们的pid赋为0,然后跳到while(1)函数的开始处又去启动他们。所有说运行时机为RESPAWN和ASKFIRST的进程永远无法杀死,除非reboot或者shutdown。

 

下面我们来总结一下init进程的启动过程
1.初始化控制台
2.解释inittab
3.执行inittab运行时机为SYSINIT的进程
4.执行inittab运行时机为WAIT的进程
5.执行inittab运行时机为ONCE的进程
6.执行inittab运行时机为RESPAWN和ASKFRIST的进程,有退出的则重新执行。


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值