您的位置:首页 > 其它

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

④配置文件中的制定程序

⑤库
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  busybox u-boot