Init进程启动Zygote进程的过程

Android系统启动时在加载完内核之后会启动Init进程,Init进程的启动过程中会读取根目录下的脚本文件Init.rc,以便将Zygote进程启动起来。

//Android系统在加载内核之后会启动init进程,以下为Init进程的main函数
int main(int argc, char **argv)
{
   
	//解析配置文件的初始化
    init_parse_config_file("/init.rc");

    action_for_each_trigger("early-init", action_add_queue_tail);

    queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done");
   
		//逐一执行队列中的命令
        execute_one_command();
       
}

void action_for_each_trigger(const char *trigger,
                             void (*func)(struct action *act))
{
    
			//调用func指向的函数
            func(act);
    
}

void queue_builtin_action(int (*func)(int nargs, char **args), char *name)
{
   
	//命令结构体cmd的成员函数func指向函数参数func所指向的函数
    cmd->func = func;
   
}


int init_parse_config_file(const char *fn)
{
	//读取配置文件init.rc到字符串指针data
    data = read_file(fn, 0);
	
	//解析配置文件
    parse_config(fn, data);

}


static void parse_config(const char *fn, char *s)
{
   
	//解析状态结构体state的成员变量parse_lint是个函数指针,默认指向无解析操作函数parse_line_no_op,也可指向解析服务函数parse_line_service,或者解析动作函数parse_line_action
    state.parse_line = parse_line_no_op;

      
				//确定关键字
                int kw = lookup_keyword(args[0]);
               
					//调用state.parse_line指向的函数解析新的行
                    state.parse_line(&state, 0, 0);
					//解析一个新的章节
                    parse_new_section(&state, kw, nargs, args);
             
		 //递归调用init_parse_config_file来解析import的文件
         ret = init_parse_config_file(import->filename);
         
}

static void parse_new_section(struct parse_state *state, int kw,
                       int nargs, char **args)
{
   
		//解析服务
        state->context = parse_service(state, nargs, args);
       
			//解析状态结构体state的成员变量parse_line指向函数parse_line_service
            state->parse_line = parse_line_service;
          
   
		//解析加载文件部分
        parse_import(state, nargs, args);
     
}

static void parse_line_service(struct parse_state *state, int nargs, char **args)
{
    
		//调用函数kw_func
        cmd->func = kw_func(kw);

}

static void parse_line_action(struct parse_state* state, int nargs, char **args)
{
   
	//调用函数kw_func
    cmd->func = kw_func(kw);
   
}

int do_class_start(int nargs, char **args)
{
        /* Starting a class does not start services
         * which are explicitly disabled.  They must
         * be started individually.
         */
    service_for_each_class(args[1], service_start_if_not_disabled);

}

void service_for_each_class(const char *classname,
                            void (*func)(struct service *svc))
{
    
	//func指向service_start_if_not_disabled
            func(svc);
        
}

//参数dynamic_args用来描述服务的动态参数列表,相对于脚本文件init.rc中配置的静态启动参数而言
void service_start(struct service *svc, const char *dynamic_args)
{
   
	//fork创建子进程
    pid = fork();

    if (pid == 0) {
		//在新创建的子进程中返回
 
			//创建socket
			int s = create_socket(si->name, socket_type,
                                  si->perm, si->uid, si->gid, si->socketcon ?: scon);
          
				//将创建socket返回的fd发布到系统中
                publish_socket(si->name, s);
          

			//如果动态参数为空,直接执行新程序/system/bin/app_process
            if (execve(svc->args[0], (char**) svc->args, (char**) ENV) < 0) {
              
			//合并动态参数和静态参数之后加载应用程序文件/system/bin/app_process,并把数组arg_ptrs传给它
            execve(svc->args[0], (char**) arg_ptrs, (char**) ENV);
       
}

Init.rc

import /init.${ro.zygote}.rc

on nonencrypted
//启动main类型的class
    class_start main
    class_start late_start

Init.zygote32.rc

//Zygote进程以服务service的形式启动,对应的程序文件是/system/bin/app_process,后面是4个启动参数,"--start-system-server"表示Zygote启动完成后启动System进程
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    class main
    //Zygote进程内部会创建一个名称为Zygote的socket
    socket zygote stream 660 root system
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart media
    onrestart restart netd

Keywords.h

//class是一个OPTION
KEYWORD(class,       OPTION,  0, 0)
//注意class_start是COMMAND,对应的函数是do_class_start
KEYWORD(class_start, COMMAND, 1, do_class_start)
//注意service是一个SECTION
KEYWORD(service,     SECTION, 0, 0)

Init_parser.c

//第一次包含头文件"keywords.h",是为了声明函数和枚举
#include "keywords.h"

#define KEYWORD(symbol, flags, nargs, func) \
    [ K_##symbol ] = { #symbol, func, nargs + 1, flags, },

static struct {
    const char *name;
    int (*func)(int nargs, char **args);
    unsigned char nargs;
    unsigned char flags;
} keyword_info[KEYWORD_COUNT] = {
    [ K_UNKNOWN ] = { "unknown", 0, 0, 0 },
//第二次包含头文件"keywords.h",是为了利用枚举里面的变量来给数组keyword_info初始化
//注意作用域在数组keyword_info里面,
#include "keywords.h"
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值