《构建根文件系统(一)init_post内核启动第一个应用程序》

1.init_post启动应用程序

  在内核经过一系列得初始化以及挂载了根文件系统后,最后就是运行第一个应用程序。

    if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
        printk(KERN_WARNING "Warning: unable to open an initial console.\n");

  打开dev/console控制台设备(串口0),使用户能输入信息, /dev/console即成为kernel_init进程的标准输入源(文件描述符0),打开失败则打印Warning: unable to open an initial console.\n   

  因此当我们删除根文件系统里面得内容,然后再启动内核,就会打印上面得消息,因为找不到/dev/console

 

 

   虽然根文件系统挂载上了,但是找不到里面得相关内容。

 

    (void) sys_dup(0);
    (void) sys_dup(0);

  sys_dup()的主要工作就是用来“复制”一个打开的文件号,使两个文件号都指向同一个文件。

  所以这里复制了上面打开的/dev/console。这样就使得这个控制台有三个文件文件描述符:标准输入、标准输出、标准错误。

 

    if (ramdisk_execute_command) {
        run_init_process(ramdisk_execute_command);
        printk(KERN_WARNING "Failed to execute %s\n",
                ramdisk_execute_command);
    }

  通过对ramdisk_execute_command全局搜索发现,ramdisk_execute_command = str;

static int __init rdinit_setup(char *str)
{
    unsigned int i;

    ramdisk_execute_command = str;
    /* See "auto" comment in init_setup */
    for (i = 1; i < MAX_INIT_ARGS; i++)
        argv_init[i] = NULL;
    return 1;
}
__setup("rdinit=", rdinit_setup);

  __setup的结构在之前已经解释过了,最后拆解完,会将rdinit=后面的字符串作为参数传递进去并赋给ramdisk_execute_command。

 

    if (execute_command) {
        run_init_process(execute_command);
        printk(KERN_WARNING "Failed to execute %s.  Attempting "
                    "defaults...\n", execute_command);
    }

  这个和上面的一样,查找后

static int __init init_setup(char *str)
{
    unsigned int i;

    execute_command = str;
    /*
     * In case LILO is going to boot us with default command line,
     * it prepends "auto" before the whole cmdline which makes
     * the shell think it should execute a script with such name.
     * So we ignore all arguments entered _before_ init=... [MJ]
     */
    for (i = 1; i < MAX_INIT_ARGS; i++)
        argv_init[i] = NULL;
    return 1;
}
__setup("init=", init_setup);

  所以当我们在bootarg中设置了init=linuxrc的时候,就会将linuxrc以传址的方式传给execute_command。

  然后运行run_init_process(“linuxrc”);程序就一去不复还的启动应用程序。

 

    run_init_process("/sbin/init");
    run_init_process("/etc/init");
    run_init_process("/bin/init");
    run_init_process("/bin/sh");

    panic("No init found.  Try passing init= option to kernel.");

  如果没有设置bootarg参数,init_post会启动默认的应用程序。"/sbin/init"    "/etc/init"    "/bin/init"    "/bin/sh"。最后都没找到就会打印信息。

 

    

posted @ 2019-09-20 15:34  一个不知道干嘛的小萌新  阅读(536)  评论(0编辑  收藏  举报