• 构建根文件系统启动(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. ");

     (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...
    ", 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);

                             打印 Please 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'
    ",
            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、库

  • 相关阅读:
    PHP trim() 函数
    php 计算2个日期的相差天数
    php date('Y-n-j')的和date('Y-m-d')的区别
    转移服务器
    Invalid argument supplied for foreach()解决办法
    wordpress 后台忘记密码怎么办
    qrcode js插件生成微信二维码
    thinkphp5 注释
    tp5 新增完数据,获取id
    resstFul服务文件上传下载
  • 原文地址:https://www.cnblogs.com/CZM-/p/5078011.html
Copyright © 2020-2023  润新知