busybox init进程分析

本人喜欢用代码+伪代码的方式写笔记。文中的花括号可能是方便记录而已。

如:

hw_get_module(LED_HARDWARE_MODULE_ID, (const hw_module_t**)&module)
{
    问:怎么获得模块信息的?
    答:hardware\libhardware\Hardware.c

    ...........

}

原创分析, 转载请注明出处:http://www.cnblogs.com/langlang/

作者email: [email protected]

 

busybox- 1.18. 5 分析
文件  init.c
int init_main( int argc UNUSED_PARAM,  char **argv)
{
     // 填充链表init_action_list
    parse_inittab();
    原型:new_init_action(uint8_t action_type,  const  char *command,  const  char *cons)
    {
         // 读取文件 /etc/inittab
        parser_t *parser = config_open2( " /etc/inittab ", fopen_for_read);
         // 假如 /etc/inittab不存在
         if (parser == NULL)
        {
            new_init_action(CTRLALTDEL,  " reboot """);
            原型 new_init_action(uint8_t action_type,  const  char *command,  const  char *cons)
            {
                 struct init_action *a, **nextp;
                {
                    注 :  struct init_action {
                                 struct init_action *next;       // 链表指针
                                pid_t pid;                     // 线程ID
                                uint8_t action_type;         //  action的类型  ①
                                 char terminal[CONSOLE_NAME_SIZE];    // 运行该command的终端  (*cons)
                                 char command[COMMAND_SIZE];          // command字段用来指定要执行命令(含路径),包括命令行选项。
                            };
                }
                nextp = &init_action_list;
                
                假如init_action_list不为空
                {
                    比较查找
                }
                假如为空
                {
                    a = xzalloc( sizeof(*a));
                }
                a->action_type = action_type;
                safe_strncpy(a->command, command,  sizeof(a->command));
                safe_strncpy(a->terminal, cons,  sizeof(a->terminal));
            }
            ..........
        }
         else
        {
             // 分析
            new_init_action( 1 << action, token[ 3], tty);
        }
    }

     /*  Now run everything that needs to be run  */
     /*  First run the sysinit command  */
    run_actions(SYSINIT);
    原型: void run_actions( int action_type)
    {
         struct init_action *a;
         for (a = init_action_list; a; a = a->next) {
             if (!(a->action_type & action_type))
                 continue// 继续查找

             if (a->action_type & (SYSINIT | WAIT | ONCE | CTRLALTDEL | SHUTDOWN)) {
                pid_t pid = run(a);  // 执行
                {
                    创建进程
                     // ASKFIRST类型需要等待回车
                     if (BB_MMU && (a->action_type & ASKFIRST)) {
                         static  const  char press_enter[] ALIGN1 =
                             " \nPlease press Enter to activate this console.  ";
                         char c;
                         // 输出
                        dbg_message(L_LOG,  " waiting for enter to start '%s' "
                         " (pid %d, tty '%s')\n ",a->command, getpid(), a->terminal);
                        full_write(STDOUT_FILENO, press_enter,  sizeof(press_enter) -  1);
                         while (safe_read(STDIN_FILENO, &c,  1) ==  1 && c !=  ' \n ')
                             continue// 等待回车
                    }
                }
                 if (a->action_type & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN))
                    waitfor(pid);  // 待它的command执行完,再继续执行。
            }
             if (a->action_type & (RESPAWN | ASKFIRST)) {
                 /*  Only run stuff with pid == 0. If pid != 0,
                * it is already running
                
*/
                 if (a->pid ==  0)
                    a->pid = run(a);  // init则不会等待它执行完
            }
        }
    }
    check_delayed_sigs();
     /*  Next run anything that wants to block  */
    run_actions(WAIT);
    check_delayed_sigs();
     /*  Next run anything to be run only once  */
    run_actions(ONCE);
     while ( 1) {
         /*  (Re)run the respawn/askfirst stuff  */
        run_actions(RESPAWN | ASKFIRST);
        maybe_WNOHANG |= check_delayed_sigs();
         /*  Don't consume all CPU time - sleep a bit  */
        sleep( 1);
        maybe_WNOHANG |= check_delayed_sigs();
    
    }
}

① action_type
/*  为init提供初始化命令脚本的路径  */
#define SYSINIT     0x01
/*  告诉init必须等到相应的进程执行完成之后才能继续执行  */
#define WAIT        0x02
/*  仅执行相应的进程一次,而且不会等待它执行完成  */
#define ONCE        0x04
/*  每当相应的进程终止执行时,重新启动该进程  */
#define RESPAWN     0x08
/*   类似respawn,主要用途是减少系统上执行的终端应用程序的数量。
它将会促使init在控制台上显示
“Please press Enter to active this console”的信息,
并在重新启动进程之前等待用户按下“enter”键  
*/
#define ASKFIRST    0x10
/*  当按下Ctrl+Alt+Delete组合键时,执行相应的进程  */
#define CTRLALTDEL  0x20
/*  当系统关机时,执行相应的进程   */
#define SHUTDOWN    0x40
/*  当init重新启动时,执行相应的进程,通常此处所执行的进程就是init本身   */

#define RESTART     0x80 

你可能感兴趣的:(init)