• Android——init可执行程序


    init进程是Android启动后,系统执行的第一个名称为init的可执行程序。

    功能:

    • 设备管理
    • 解析启动脚本init.rc
    • 执行启动脚本中的基本功能
    • 执行启动脚本中的各种服务

    代码路径:system/core/init

    编译结果生成一个可执行文件:init

    1.main{}

    int main(int argc, char **argv)
    {
        int device_fd = -1;
        int property_set_fd = -1;
        int signal_recv_fd = -1;
        int keychord_fd = -1;
        int fd_count;
        int s[2];
        int fd;
        struct sigaction act;
        char tmp[PROP_VALUE_MAX];
        struct pollfd ufds[4];
        char *tmpdev;
        char* debuggable;

        act.sa_handler = sigchld_handler;
        act.sa_flags = SA_NOCLDSTOP;
        act.sa_mask = 0;
        act.sa_restorer = NULL;
        sigaction(SIGCHLD, &act, 0);

       
        umask(0);

           
        mkdir("/dev", 0755);                    //创建文件系统的基本目录
        mkdir("/proc", 0755);
        mkdir("/sys", 0755);

        mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755");
        mkdir("/dev/pts", 0755);
        mkdir("/dev/socket", 0755);
        mount("devpts", "/dev/pts", "devpts", 0, NULL);
        mount("proc", "/proc", "proc", 0, NULL);
        mount("sysfs", "/sys", "sysfs", 0, NULL);

           
        open_devnull_stdio();             //打开3个文件:输入,输入,错误
        log_init();                       //初始化log
        
        INFO("reading config file ");
        parse_config_file("/init.rc");        //处理初始化脚本,获取内核命令行参数

       
        qemu_init();
        import_kernel_cmdline(0);             //初始化驱动设备,创建文件系统节点

        get_hardware_name();
        snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);
        parse_config_file(tmp);

        action_for_each_trigger("early-init", action_add_queue_tail);
        drain_action_queue();

        INFO("device init ");
        device_fd = device_init();              //属性相关处理和启动logo

        if (emmc_boot){
            action_for_each_trigger("emmc", action_add_queue_tail);
            drain_action_queue();
        }else{
            action_for_each_trigger("nand", action_add_queue_tail);
            drain_action_queue();
        }

        property_init();
       
        // only listen for keychords if ro.debuggable is true
        keychord_fd = open_keychord();

        if (console[0]) {
            snprintf(tmp, sizeof(tmp), "/dev/%s", console);
            console_name = strdup(tmp);
        }

        fd = open(console_name, O_RDWR);
        if (fd >= 0)
            have_console = 1;
        close(fd);

        if( load_565rle_image(INIT_IMAGE_FILE) ) {        //
        fd = open("/dev/tty0", O_WRONLY);
        if (fd >= 0) {
            const char *msg;
                msg = " "

            " "
            " "
            " "
            " "
            " "
            " "  // console is 40 cols x 30 lines
            " "
            " "
            " "
            " "
            " "
            " "
            " "
            "             A N D R O I D ";
            write(fd, msg, strlen(msg));
            close(fd);
        }



        }

        if (qemu[0])
            import_kernel_cmdline(1);

        if (!strcmp(bootmode,"factory"))
            property_set("ro.factorytest", "1");
        else if (!strcmp(bootmode,"factory2"))
            property_set("ro.factorytest", "2");
        else
            property_set("ro.factorytest", "0");

        property_set("ro.serialno", serialno[0] ? serialno : "");
        property_set("ro.bootmode", bootmode[0] ? bootmode : "unknown");
        property_set("ro.baseband", baseband[0] ? baseband : "unknown");
        property_set("ro.carrier", carrier[0] ? carrier : "unknown");
        property_set("ro.bootloader", bootloader[0] ? bootloader : "unknown");

        property_set("ro.hardware", hardware);
        snprintf(tmp, PROP_VALUE_MAX, "%d", revision);
        property_set("ro.revision", tmp);
        property_set("ro.emmc",emmc_boot ? "1" : "0");

           
        action_for_each_trigger("init", action_add_queue_tail);
        drain_action_queue();
        
        {
        ERROR("pmd processing! ");
        system("/system/bin/pmd");
        ERROR("pmd exit! ");
        // }    
           
        property_set_fd = start_property_service();

       
        if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0) {
            signal_fd = s[0];
            signal_recv_fd = s[1];
            fcntl(s[0], F_SETFD, FD_CLOEXEC);
            fcntl(s[0], F_SETFL, O_NONBLOCK);
            fcntl(s[1], F_SETFD, FD_CLOEXEC);
            fcntl(s[1], F_SETFL, O_NONBLOCK);
        }

       
        if ((device_fd < 0) ||
            (property_set_fd < 0) ||
            (signal_recv_fd < 0)) {
            ERROR("init startup failure ");
            return 1;
        }

       
        if (battchg_pause) {
            action_for_each_trigger("boot-pause", action_add_queue_tail);
            drain_action_queue();
        }

       
        action_for_each_trigger("early-boot", action_add_queue_tail);
        action_for_each_trigger("boot", action_add_queue_tail);
        drain_action_queue();

           
        queue_all_property_triggers();
        drain_action_queue();

              
        property_triggers_enabled = 1;    

        ufds[0].fd = device_fd;                 //初始化struct pollfd ufds[4]
        ufds[0].events = POLLIN;
        ufds[1].fd = property_set_fd;
        ufds[1].events = POLLIN;
        ufds[2].fd = signal_recv_fd;
        ufds[2].events = POLLIN;
        fd_count = 3;

        if (keychord_fd > 0) {
            ufds[3].fd = keychord_fd;
            ufds[3].events = POLLIN;
            fd_count++;
        } else {
            ufds[3].events = 0;
            ufds[3].revents = 0;
        }

    #if BOOTCHART
        bootchart_count = bootchart_init();
        if (bootchart_count < 0) {
            ERROR("bootcharting init failure ");
        } else if (bootchart_count > 0) {
            NOTICE("bootcharting started (period=%d ms) ", bootchart_count*BOOTCHART_POLLING_MS);
        } else {
            NOTICE("bootcharting ignored ");
        }
    #endif

        for(;;) {                                         //进入循环,处理ufds[4]的事件
            int nr, i, timeout = -1;

            for (i = 0; i < fd_count; i++)
                ufds[i].revents = 0;

            drain_action_queue();
            restart_processes();

            if (process_needs_restart) {
                timeout = (process_needs_restart - gettime()) * 1000;
                if (timeout < 0)
                    timeout = 0;
            }

    #if BOOTCHART
            if (bootchart_count > 0) {
                if (timeout < 0 || timeout > BOOTCHART_POLLING_MS)
                    timeout = BOOTCHART_POLLING_MS;
                if (bootchart_step() < 0 || --bootchart_count == 0) {
                    bootchart_finish();
                    bootchart_count = 0;
                }
            }
    #endif
            nr = poll(ufds, fd_count, timeout);
            if (nr <= 0)
                continue;

            if (ufds[2].revents == POLLIN) {
               
                read(signal_recv_fd, tmp, sizeof(tmp));
                while (!wait_for_one_process(0))
                    ;
                continue;
            }

            if (ufds[0].revents == POLLIN)
                handle_device_fd(device_fd);

            if (ufds[1].revents == POLLIN)
                handle_property_set_fd(property_set_fd);
            if (ufds[3].revents == POLLIN)
                handle_keychord(keychord_fd);
        }

        return 0;
    }

  • 相关阅读:
    SecureCRT 迁移到新环境,配置导出
    Git 常用操作
    Java 性能分析工具 Asyncprofiler
    冒号语法
    后台乱码转中文
    js讲解视频
    下载指定版本的loader.调整文件夹结构
    react大型数据渲染列表
    git拉取报错
    记录一个排序表格的插件
  • 原文地址:https://www.cnblogs.com/senior-engineer/p/4848837.html
Copyright © 2020-2023  润新知