zoukankan      html  css  js  c++  java
  • 《构建根文件系统(一)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.
    ");
    

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

      因此当我们删除根文件系统里面得内容,然后再启动内核,就会打印上面得消息,因为找不到/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
    ",
                    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...
    ", 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"。最后都没找到就会打印信息。

        

  • 相关阅读:
    maven工程下 读取resource下配置文件
    js生成二维码以及点击下载二维码
    RGB颜色值与十六进制颜色码对照表
    用Java实现给图片添加文字
    CryptoAPI与openssl数字签名与验证交互
    CryptoAPI与openssl RSA非对称加密解密(PKCS1 PADDING)交互
    openssl与cryptoAPI交互AES加密解密
    JAVA解析各种编码密钥对(DER、PEM、openssh公钥)
    Java与.NET兼容的RSA密钥持久化方法
    .NET导入openssl生成的公钥之BEGIN RSA PUBLIC KEY
  • 原文地址:https://www.cnblogs.com/zhuangquan/p/11557550.html
Copyright © 2011-2022 走看看