Android init进程分析

  Android init进程是Linux系统中用户空间的第一个进程,在Android里也是如此。在Android中init进程主要负责两大块内容,分别是:

  1. 创建几个关键进程,如zygote。
  2. 提供property service服务管理Android各种属性。

一、init分析

首先是init.c文件入口函数是其main函数
[–>init.c]

int main(int argc, char **argv)
{
//一些准备工作,如
mkdir("/dev/socket", 0755);
mount("devpts", "/dev/pts", "devpts", 0, NULL);
......
//初始化相关属性
property_init();
......
//获取系统信息
get_hardware_name(hardware, &revision);
......
//解析配置文件
init_parse_config_file("/init.rc");
......
//early-init,init阶段
action_for_each_trigger("early-init", action_add_queue_tail);
action_for_each_trigger("init", action_add_queue_tail);
......
//early-init,init阶段
 for(;;) {
        ......
        //执行相关命令,重启已死去的进程
        execute_one_command();
        restart_processes();
        ......
}
}

init.c可总结为一下几点:

  1. 初始化设备。如某些文件的创建与挂在,property_init()相关属性的初始化,设备信息的获取等工作。
  2. 分析配置文件init.rc。
  3. 执行一些动作,zygote就是在某个动作中完成创建的。
  4. 进入无线循环,等待一些事的发生。

二、init.rc配置文件解析

在init.c中调用了init_parse_config_file(“/init.rc”)函数来解析配置文件,函数代码如下
[–>init_parser.c]

int init_parse_config_file(const char *fn)
{
    char *data;
    data = read_file(fn, 0);
    if (!data) return -1;
    //主要是调用 parse_config进行解析
    parse_config(fn, data);
    DUMP();
    return 0;
}
......
static void parse_config(const char *fn, char *s)
{
......
 for (;;) {
        switch (next_token(&state)) {
        ......
         case T_NEWLINE:
            state.line++;
            if (nargs) {
                int kw = lookup_keyword(args[0]);
                if (kw_is(kw, SECTION)) {
                    state.parse_line(&state, 0, 0);
                    //解析配置文件中的section
                    parse_new_section(&state, kw, nargs, args);
                } else {
                    state.parse_line(&state, nargs, args);
                }
                nargs = 0;
            }
            break;
            ......
        }
}

一个section就是init.rc文件中的一个service如
[–>init.rc]

......
service servicemanager /system/bin/servicemanager
    class core
    user system
    group system
    critical
    onrestart restart healthd
    onrestart restart zygote
    onrestart restart media
    onrestart restart surfaceflinger
    onrestart restart drm
......

解析section 的入口函数为parse_new_section
[–>init_parser.c]

static void parse_new_section(struct parse_state *state, int kw,
                       int nargs, char **args)
{
......
switch(kw) {
    case K_service:
        state->context = parse_service(state, nargs, args);
        if (state->context) {
            state->parse_line = parse_line_service;
            return;
        }
        break;
......
}

然后在调用parse_service和parse_line_service对init.rc进行解析,parse_service用来搭建一个struct service结构体框架,parse_line_service用来对框架进行填充。

三、启动zygote

[–>init.c]

void service_start(struct service *svc, const char *dynamic_args)
{
.....
pid = fork();//创建一个子进程来处理后面的事
if (pid == 0) {
.....
 if (!dynamic_args) {
            //通过execve命令/system/bin/app_process命令,但实质为调用app_main.c下的main函数
            if (execve(svc->args[0], (char**) svc->args, (char**) ENV) < 0) {
            .....
          }
        }
.....
}
}

四、属性服务

init.c里对主要是对属性服务进行了初始化,建立了一种服务器客服端的通信架构,在初始化属性服务的时候会建立一块共享内存,客户端则通过这块共享内存来读取属性,但设置属性则是通过客服端与服务器的socket通信,然后服务器端根据socket信息以及客户端的权限来设置相应的属性。相应的函数如下(具体过程就不再详解)
[–>property_service.c]

static int init_property_area(void)
{
//初始化共享内存
}

[–>system_properties.c]

int _system_properties_init(void)
{
//客服端获取共享内存
}

[–>property_service.c]

void start_property_service(void)
{
//启动属性服务器
}

void handle_property_set_fd()
{
//处理socket消息
}

int property_set(const char *name, const char *value)
{
//设置属性
}

[–>properties.c]

//客户端发送属性请求
int property_set(const char *key, const char *value)
{
    return __system_property_set(key, value);
}

本文只是很粗很泛的介绍了一下init.c进程,其中遗漏了大量东西,以及可能有许多错误的地方,希望以后能有机会来改进。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值