Android启动过程详解(2)——init进程启动逻辑

本文详细介绍了Android系统启动过程中init进程的重要职责,包括文件挂载、解析和执行init.rc文件、启动服务如Zygote,以及作为守护进程的角色。init首先挂载文件系统,如tmpfs和devpts,然后解析init.rc文件,启动如Zygote等关键服务。Zygote服务的启动是通过执行/system/bin/app_process实现的。init进程作为守护进程,处理子进程的信号,例如在Zygote退出时进行重启操作,并负责属性服务的启动和管理。
摘要由CSDN通过智能技术生成

init进程是Android系统用户空间中的第一个进程,其进程号也是1,足见其重要性。所以它的责任也是重大的,概括地来说init进程主要做了以下几件事:

  1. 作为守护进程
  2. 解析和执行init.rc文件
  3. 属性服务
  4. 生成设备驱动节点

接下来文章就着init进程的源码,来一个个分析init进程的工作。首先来看看init进程的源码:

int main(int argc, char **argv)  
{  
    int fd_count = 0;  
    struct pollfd ufds[4];  
    char *tmpdev;  
    char* debuggable;  
    char tmp[32];  
    int property_set_fd_init = 0;  
    int signal_fd_init = 0;  
    int keychord_fd_init = 0;  
    bool is_charger = false;  


    //启动ueventd  
    if (!strcmp(basename(argv[0]), "ueventd"))  
        return ueventd_main(argc, argv);  


    //启动watchdogd  
    if (!strcmp(basename(argv[0]), "watchdogd"))  
        return watchdogd_main(argc, argv);  


    /* clear the umask */  
    umask(0);  


        /* Get the basic filesystem setup we need put 
         * together in the initramdisk on / and then we'll 
         * let the rc file figure out the rest. 
         */  
    //创建并挂在启动所需的文件目录  
    mkdir("/dev", 0755);  
    mkdir("/proc", 0755);  
    mkdir("/sys", 0755);  


    mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "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);  


        /* indicate that booting is in progress to background fw loaders, etc */  
    close(open("/dev/.booting", O_WRONLY | O_CREAT, 0000));//检测/dev/.booting文件是否可读写和创建  


        /* We must have some place other than / to create the 
         * device nodes for kmsg and null, otherwise we won't 
         * be able to remount / read-only later on. 
         * Now that tmpfs is mounted on /dev, we can actually 
         * talk to the outside world. 
         */  
    open_devnull_stdio();//重定向标准输入/输出/错误输出到/dev/_null_  
    klog_init();//log初始化  
    property_init();//属性服务初始化  


    //从/proc/cpuinfo中读取Hardware名,在后面的mix_hwrng_into_linux_rng_action函数中会将hardware的值设置给属性ro.hardware  
    get_hardware_name(hardware, &revision);  


    //导入并设置内核变量  
    process_kernel_cmdline();  


    //selinux相关,暂不分析  
    union selinux_callback cb;  
    cb.func_log = klog_write;  
    selinux_set_callback(SELINUX_CB_LOG, cb);  


    cb.func_audit = audit_callback;  
    selinux_set_callback(SELINUX_CB_AUDIT, cb);  


    selinux_initialize();  
    /* These directories were necessarily created before initial policy load 
     * and therefore need their security context restored to the proper value. 
     * This must happen before /dev is populated by ueventd. 
     */  
    restorecon("/dev");  
    restorecon("/dev/socket");  
    restorecon("/dev/__properties__");  
    restorecon_recursive("/sys");  


    is_charger = !strcmp(bootmode, "charger");//关机充电相关,暂不做分析  


    INFO("property init\n");  
    if (!is_charger)  
        property_load_boot_defaults();  


    INFO("reading config file\n");  
    init_parse_config_file("/init.rc");//解析init.rc配置文件  


    /* 
     * 解析完init.rc后会得到一系列的action等,下面的代码将执行处于early-init阶段的action。 
     * init将action按照执行时间段的不同分为early-init、init、early-boot、boot。 
     * 进行这样的划分是由于有些动作之间具有依赖关系,某些动作只有在其他动作完成后才能执行,所以就有了先后的区别。 
     * 具体哪些动作属于哪个阶段是在init.rc中的配置决定的 
     */  
    action_for_each_trigger("early-init", action_add_queue_tail);  


    queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done");  
    queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");  
    queue_builtin_action(keychord_init_action, "keychord_init");  
    queue_builtin_action(console_init_action, "console_init");  


    /* execute all the boot actions to get us started */  
    action_for_each_trigger("init", action_add_queue_tail);  


    /* skip mounting filesystems in charger mode */  
    if (!is_charger) {  
        action_for_each_trigger("early-fs", action_add_queue_tail);  
        action_for_each_trigger("fs", action_add_queue_tail);  
        action_for_each_trigger("post-fs", action_add_queue_tail);  
        action_for_each_trigger("post-fs-data", action_add_queue_tail);  
    }  


    /* Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random 
     * wasn't ready immediately after wait_for_coldboot_done 
     */  
    queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");  


    queue_builtin_action(property_service_init_action, "property_service_init");  
    queue_builtin_action(signal_init_action, "signal_init");  
    queue_builtin_action(check_startup_action, "check_startup");  


    if (is_charger) {  
        action_for_each_trigger("charger", action_add_queue_tail);  
    } else {  
        action_for_each_trigger("early-boot", action_add_queue_tail);  
        action_for_each_trigger("boot", action_add_queue_tail);  
    }  


        /* run all property triggers based on current state of the properties */  
    queue_builtin_action(queue_property_triggers_action, "queue_property_triggers");  




#if BOOTCHART  
    queue_builtin_action(bootchart_init_action, 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值