• Android 8.0系统启动流程_init(一)


    前言

    本系列主要介绍Android8.0系统启动过程中涉及到的init、Zygote、SystemServer和Launcher。

    一、init启动前准备

    init进程是Android系统的第一个进程,其进程号为1,该进程启动后,主要处理一些重要的初始化工作,比如创建Zygote和各种属性服务。在电源按键按下后,经历如下几个步骤后,便开始引入init进程:

    1. 启动电源及系统:电源按下后,引导芯片开始将固化在ROM中的BootLoader加载至RAM中,并执行该程序;
    2. 引导程序BootLoader:引导程序BootLoader是在Android操作系统开始运行前,执行的一个小程序,其主要作用是把系统OS拉起来并运行;
    3. Linux内核启动:内核启动时,设置缓存、被保护存储器、计划列表和加载驱动等,完成设置后,它首先在系统文件中寻找init.rc文件,并启动init进程
    4. init进程启动:init进程做的工作比较多,主要是用来初始化和启动属性服务,也用来启动Zygote进程。

    二、init进程的入口函数

    在Linux内核加载完成后,开始查找init.rc文件,并启动init进程,其主要代码如下:

    int main(int argc, char** argv) {
    	...
        bool is_first_stage = (getenv("INIT_SECOND_STAGE") == nullptr);
        if (is_first_stage) {
            boot_clock::time_point start_time = boot_clock::now();
    
            //清理 umask.
            umask(0);
    
     		//创建和挂载启动所需的文件目录
            mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
            mkdir("/dev/pts", 0755);
            mkdir("/dev/socket", 0755);
            mount("devpts", "/dev/pts", "devpts", 0, NULL);
            #define MAKE_STR(x) __STRING(x)
            mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
            // Don't expose the raw commandline to unprivileged processes.
            chmod("/proc/cmdline", 0440);
            gid_t groups[] = { AID_READPROC };
            setgroups(arraysize(groups), groups);
            mount("sysfs", "/sys", "sysfs", 0, NULL);
            mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);
            mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11));
            mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8));
            mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9));
    
    	 	// 初始化Kernel日志
            InitKernelLogging(argv);
            ...
        }
        ...
    	//属性服务初始化
        property_init();//01
    	...
      	//创建epoll句柄
        epoll_fd = epoll_create1(EPOLL_CLOEXEC);
    
       ...
    
    	//设置子进程的信号处理函数,如果子进程(Zygote进程)异常退出,init进程会调用该函数中设定的信号函数来进行处理
        signal_handler_init();//02
    
    	//导入默认的环境变量
        property_load_boot_defaults();
        export_oem_lock_status();
    	//启动属性服务
        start_property_service();//03
        set_usb_controller();
        ...
    
        if (bootscript.empty()) {
       	 	//解析init.rc配置文件
            parser.ParseConfig("/init.rc");
            parser.set_is_system_etc_init_loaded(
                    parser.ParseConfig("/system/etc/init"));
            parser.set_is_vendor_etc_init_loaded(
                    parser.ParseConfig("/vendor/etc/init"));
            parser.set_is_odm_etc_init_loaded(parser.ParseConfig("/odm/etc/init"));
        } else {
            parser.ParseConfig(bootscript);
            parser.set_is_system_etc_init_loaded(true);
            parser.set_is_vendor_etc_init_loaded(true);
            parser.set_is_odm_etc_init_loaded(true);
        }
        ...
        while (true) {
            // By default, sleep until something happens.
            int epoll_timeout_ms = -1;
    
            if (!(waiting_for_prop || ServiceManager::GetInstance().IsWaitingForExec())) {
                am.ExecuteOneCommand();
            }
            if (!(waiting_for_prop || ServiceManager::GetInstance().IsWaitingForExec())) {
            	//重启死去的进程
                restart_processes();//05
    
                // If there's a process that needs restarting, wake up in time for that.
                if (process_needs_restart_at != 0) {
                    epoll_timeout_ms = (process_needs_restart_at - time(nullptr)) * 1000;
                    if (epoll_timeout_ms < 0) epoll_timeout_ms = 0;
                }
    
                // If there's more work to do, wake up again immediately.
                if (am.HasMoreCommands()) epoll_timeout_ms = 0;
            }
    
            epoll_event ev;
            int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, epoll_timeout_ms));
            if (nr == -1) {
                PLOG(ERROR) << "epoll_wait failed";
            } else if (nr == 1) {
                ((void (*)()) ev.data.ptr)();
            }
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96

    该流程分析如下:

    1. 挂载文件:通过设置umask值,屏蔽一些权限后,开始挂载和创建所需的文件;
    2. 属性服务:通过property_init()属性服务初始化,调用start_property_service()启动属性服务;
    3. 子进程的处理函数: signal_handler_init()主要作用是防止出现僵尸进程,子进程在暂停和终止后,会发出SIGCHLD的信号,signal_handler_init()接收到该信号后,会对该进程进行回收处理,防止占用系统进程资源;
    4. 解析init.rc配置:在8.0中对init.rc文件进行了拆分,可查看system\core\rootdir目录,包括:
      init.zygote32.rc:Zygote对应的执行程序是app_process(纯32位模式);
      init.zygote64.rc:Zygote对应的执行程序是app_process64(纯64位模式);
      init.zygote32_64.rc:启动两个Zygote进程( zygote 和 zygote_secondary),对应的执行程序是app_process32(主模式)和app_process64;
      init.zygote64_32.rc:启动两个Zygote进程( zygote 和 zygote_secondary),对应的执行程序是app_process64(主模式)和app_process32。

    三、init函数解析

    /system/core/rootdir/init.rc

    init.rc是一个非常重要的配置文件,它是由Android初始化语言(Android Init Language)编写的脚本,这种语言主要包含5种类型语句:Action、Command、Service、Option和Import。init.rc的配置代码如下所示:

    
    
    • 1
  • 相关阅读:
    cgroups v1简介
    【计算机组成】实模式/保护模式下地址分段(基段地址+偏移地址)的原因
    【C++入门指南】C如何过渡到C++?祖师爷究竟对C++做了什么?
    如何破解滑动验证码?
    SpringBoot 统一响应返回格式格式 数组
    第六天 脚本与动画系统
    《论文阅读》常识感知的提示用于可控的同情对话生成 2023 AAAI
    05、SpringBoot 集成 RocketMQ
    智慧社区+物联网解决方案
    【4 进程与线程】
  • 原文地址:https://blog.csdn.net/abc6368765/article/details/125508539