构建根文件系统启动(1)

                a、挂接根文件系统

内核怎样启动第一个应用程序

         b、启动应用程序

1、打开设备

 if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)   

  printk(KERN_WARNING "Warning: unable to open an initial console.\n");

 (void) sys_dup(0);          复制

(void) sys_dup(0);            复制

"/dev/console" 里面为标准输入输出错误,printf 、scanf、err()  终端 现在为串口0

    if (execute_command) {
        run_init_process(execute_command);
        printk(KERN_WARNING "Failed to execute %s.  Attempting "
                    "defaults...\n", execute_command);
    }
    run_init_process("/sbin/init");
    run_init_process("/etc/init");
    run_init_process("/bin/init");
    run_init_process("/bin/sh");

 

2、通过run_init_process启动应用程序具体哪一个依次优先考虑(执行后一去不复返):

a、命令行init = xxxxxxxxxxxxxxx(u-boot传过来的参数)

b、/sbin/init

c、............

d、.............

f、.............

 

构建根文件系统

busybox        ls  cp  cd ........

lrwxrwxrwx    1 1000     1000            7 Jan  6  2010 /bin/ls -> busybox

lrwxrwxrwx    1 1000     1000            7 Jan  6  2010 /bin/cp -> busybox

执行ls cp其实就是执行 busybox应用程序

lrwxrwxrwx    1 1000     1000           14 Jan  6  2010 /sbin/init -> ../bin/busybox

u-boot:启动内核

内核:启动应用程序 --》先启动 /abin/init -->启动客户程序

      1、配置文件

init程序 {   2、解析配置文件

      3、执行应用程序

busybox        --》 init_main 

           parse_inittab

             file = fopen(INITTAB, "r");   //打开配置文件/etc/inittab

             new_init_action    //1、创建一个init_action结构,填充

                          //2、把这个结构放入init_action_list链表

           run_actions(SYSINIT);

             waitfor(a, 0);        //执行程序,等待它执行完毕

                run(a);       //创建process子进程

                waitpid(runpid, &status, 0);   //等待它结束

             delete_init_action(a);  //在init_action_list链表内删除

           run_actions(WAIT);

              waitfor(a, 0);        //执行程序,等待它执行完毕

                run(a);       //创建process子进程

                waitpid(runpid, &status, 0);   //等待它结束

             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);

                         打印\nPlease press Enter to activate this console.

                         等待回车

                         创建子进程
                   }

                  

               wpid = wait(NULL);    //等待子进程退出

               while (wpid > 0) {

                  a->pid = 0;      //退出后,就设置pid=0

              }

           }

                 

配置文件:

 

a、指定程序

 

b、何时执行

 

 

 

从默认的new_init_action反推出默认的配置文件

 

#inittab格式:

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

#id =》 /dev/id 用作终端: stdin ,stdout,stderr:printf,scanf,err

#runlevels:忽略

#action:执行时机

# <action>: Valid actions include: sysinit, respawn, askfirst, wait, once,
#                                  restart, ctrlaltdel, and shutdown.

#process:脚本或应用程序

 

::CTRLALTDEL:reboot
::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

    /* 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 HUP is received */ new_init_action(RESTART, "init", ""); /* Askfirst shell on tty1-4 */ 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); /* sysinit */ new_init_action(SYSINIT, INIT_SCRIPT, "");

 

 

 new_init_action(ASKFIRST, bb_default_login_shell, VC_2);

#define LIBBB_DEFAULT_LOGIN_SHELL      "-/bin/sh"

# define VC_2 "/dev/tty2"

 new_init_action(ASKFIRST, -/bin/sh, /dev/tty2);

 

struct init_action {
    struct init_action *next;
    int action;
    pid_t pid;
    char command[INIT_BUFFS_SIZE];
    char terminal[CONSOLE_NAME_SIZE];
};

 

static void new_init_action(int action, const char *command, const char *cons)
{
    struct init_action *new_action, *a, *last;

    if (strcmp(cons, bb_dev_null) == 0 && (action & ASKFIRST))
        return;

    /* Append to the end of the list */
    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 = action;
            return; 
        }
        last = a;
    }
 
    new_action = xzalloc(sizeof(struct init_action));
    if (last) {
        last->next = new_action;
    } else {
        init_action_list = new_action;
    }
    strcpy(new_action->command, command);
    new_action->action = action;
    strcpy(new_action->terminal, cons);
    messageD(L_LOG | L_CONSOLE, "command='%s' action=%d tty='%s'\n",
        new_action->command, new_action->action, new_action->terminal);

 

new_init_action(int action, const char *command, const char *cons)

 

 

 

 

最小根文件系统需要

1、/dev/console      /dev/null      //如果没有设置标准输出则定位到这

2、init本身即busybox

3、/ect/inittab

4、配置文件里指定的应用程序

5、库

 

posted @ 2015-12-26 13:55  CAM&  阅读(223)  评论(0编辑  收藏  举报