Android O: zygote进程分析

本篇博客主要结合Android 8.0的代码,回顾一下zygote进程的流程。


一、解析init.rc
在分析init进程时,我们知道init进程启动后,
会解析init.rc文件,然后创建和加载service字段指定的进程。
zygote进程就是以这种方式,被init进程加载的。

在system/core/rootdir/init.rc的开始部分,可以看到:

.............
//${ro.zygote}由厂商定义,与平台相关
import /init.${ro.zygote}.rc
.............

我们可以看出在不同的平台(32、64及64_32)上,init.rc将包含不同的zygote.rc文件。
在system/core/rootdir目录下,有init.zygote32_64.rc、init.zyote64.rc、
init.zyote32.rc、init.zygote64_32.rc。
不同的zygote.rc内容大致相同,主要区别体现在启动的是32位,还是64位的进程。
init.zygote32_64.rc和init.zygote64_32.rc会启动两个进程,且存在主次之分。

我们看看比较主流的init.zygote64.rc:

//启动的进程地址为/system/bin/app_process64
//参数为-Xzygote /system/bin --zygote --start-system-server
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
    class main
    priority -20
    user root
    group root readproc
    //会创建一个zygote socket,便于指定权限
    socket zygote stream 660 root system

    //解析service时, 构造了onrestart action对应的一系列command
    //当service被reap时,会执行onrestart对应的command
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart netd
    onrestart restart wificond
    writepid /dev/cpuset/foreground/tasks

在之前的博客中,我们分析过init进程的启动。
init进程启动的最后,会产生”late-init”事件。
对应于init.rc文件的内容类似于:

..........
on late-init
    ........
    # Now we can start zygote for devices with file based encryption
    trigger zygote-start 
    ........
..........

进一步触发了zygote-start事件后,就会启动zygote进程了。
对应的init.rc文件类似于:

on zygote-start && property:ro.crypto.state=unencrypted
    # A/B update verifier that marks a successful boot.
    exec_start update_verifier_nonencrypted
    start netd
    //start对应的映射关系定义于system/core/init/builtins.cpp中
    //调用start对应的处理函数,启动名为zygote的服务
    //即传入前文init.zygote.rc中定义的参数
    start zygote
    start zygote_secondary

关键字start对应的处理函数为do_start,
定义于builtins.cpp中:

static int do_start(const std::vector<std::string>& args) {
    //找到zygote service对应信息
    Service* svc = ServiceManager::GetInstance().FindServiceByName(args[1]);
    if (!svc) {
        LOG(ERROR) << "do_start: Service " << args[1] << " not found";
        return -1;
    }

    //启动对应的进程
    if (!svc->Start())
        return -1;
    return 0;
}

最后,我们来看看service.cpp中定义Start函数:

bool Service::Start() {
    ............
    pid_t pid = -1;
    if (namespace_flags_) {
        pid = clone(nullptr, nullptr, namespace_flags_ | SIGCHLD, nullptr);
    } else {
        //从init进程中,fork出zygote进程
        pid = fork();
    }

    if (pid == 0) {
        ..........
        //当前fork的子进程替换为app_process
        if (execve(strs[0], (char**) &strs[0], (char**) ENV) < 0) {
            PLOG(ERROR) << "cannot execve('" << strs[0] << "')";
        }
        .........
    }
    ........

}

二、app_process的main函数
从init.zygote64.rc可以看出,zygote64启动文件的地址为app_process64。

app_process对应的代码定义在frameworks/base/cmds/app_process中,
我们来看看对应的Android.mk:

............
app_process_src_files := \
    app_main.cpp \
............
LOCAL_MODULE:= app_process
LOCAL_MULTILIB := both
LOCAL_MODULE_STEM_32 := app_process32
LOCAL_MODULE_STEM_64 := app_process64
............

可以看出,无论平台的版本是什么,都是该目录对应的代码来处理。

接下来我们就看看app_process对应的main函数,
该函数定义于app_main.cpp中。

int main(int argc, char* const argv[])
{
    //log相关代码
    ........

    //AppRuntime定义于app_main.cpp中,继承自AndroidRuntime
    //就是对Android运行环境的一种抽象,类似于java虚拟机对Java程序的作用
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    ..........
    int i;
    //找到解析参数的起点
    for (i = 0; i < argc; i++) {
        ......
    }

    // Parse runtime arguments.  Stop at first unrecognized option.
    // 从这里其实可以看出,通过app_main可以启动zygote、system-server及普通apk进程
    // 这个可以通过init.rc来配置
    bool zygote = false;
    bool startSystemServer = false;
    bool application = 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值