Android Zygote 启动流程

admin 2023年7月9日11:43:11评论12 views字数 4506阅读15分1秒阅读模式

Android系统包含netdservicemanagersurfaceflingerzygotemediainstalldbootanimation 等基本服务,具体作用请看下图。


Android Zygote 启动流程

Android 系统基本服务

二、虚拟机创建和第一个Java 程序引导

为了让APK在不同的虚拟机都可以运行,Google 采取了适配器模式,在让虚拟机运行之前先执行 dexopt ,即将dex文件优化成odex 文件,可以让虚拟机更加优化的执行。

ART虚拟机中,dexopt 将dex文件优化成二进制格式的问题,从而可以让ART虚拟机执行。dexopt会调用dex2oat 进行优化,dex2oat 的任务是将原来的dex文件进行预翻译,从而可以加快app运行的时间,但是由于某些app比较复杂,所以优化的时间就比较长。
优化是以dex文件中的Method方法为单位,dex2oat 在优化时候,会根据需求优化一定量的Method,即不是所有的Method都回翻译成oat模式。

Android Zygote 启动流程

虚拟机创建和第一个Java 程序引导

三、Dalvik 虚拟机基本配置

Android系统中,Dalvik 虚拟机 和ART、应用程序进程,以及运行系统的关键服务SystemServer进程都是由 Zygote进程创建孵化的。

1.Dalvik 虚拟机基本配置

Android Zygote 启动流程

Dalvik 虚拟机基本配置

四、Zygote 启动流程

1.Zygote 启动代码

Zygote 服务时通过 init.rc进程启动的,Zygote 的 classname 为main.
init.rc文件配置代码如下:

... ... 
on nonencrypted
class_start main
class_start late_start

on property:sys.init_log_level=*
loglevel ${sys.init_log_level}

... ...

详细可以参考 init.rc启动分析。
Android  init 启动流程

2.Zygote main 函数

app_main.cppZygote进程的main函数,frameworksbasecmdsapp_processapp_main.cpp

Zygote 是由 init.rc 脚本启动,在init脚本中,我们可以看到会导入import /init.${ro.zygote}.rc 脚本

# Copyright (C) 2012 The Android Open Source Project
#
# IMPORTANT: Do not create world writable files or directories.
# This is a common source of Android security bugs.
#

import /init.environ.rc
import /init.usb.rc
import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
import /init.usb.configfs.rc
... ...
import /init.${ro.zygote}.rc

... ...

在 system/core/rootdir目录下,会根据ro.zygote属性值不同,启动不同的脚本,主要包含以下四个zygote脚本。

  • 1.init.zygote32.rc 支持32为系统

  • 2.init.zygote32_64.rc

  • 3.init.zygote64.rc

  • 4.init.zygote64_32.rc

Android Zygote 启动流程

init.zygte.rc脚本

Android Zygote 启动流程

Zygote 启动流程

五、Zygote 启动分析

Android Zygote 启动流程

Zygote 启动分析

六、Zygote 创建system_server主要方法

Android Zygote 启动流程

Zygote 创建system_server主要方法

七、Zygote 创建System_server 分析

Android Zygote 启动流程

Zygote 创建System_server

八、Zygote 创建应用

Android Zygote 启动流程

Zygote 创建应用

九、Zygote 创建应用流程

Android Zygote 启动流程

Zygote 创建应用流程

十、Zygote 预加载资源

Android Zygote 启动流程

Zygote 预加载资源

Android Zygote 启动流程

preloadClasses()

Android Zygote 启动流程

preloadResources()

十一、Zygote 预加载的目的

Android Zygote 启动流程

Zygote 预加载的目的

十二、优化Zygote 启动方法:线程池

1.Zygote 启动优化

  • 1:加载类和资源是可重入操作,所以在并行模式下,不存在互斥的场景

  • 2:Android提供了ExecutorsExecutorService多线程类,因此可以使用多线程来加载类和资源。

  • 3:硬件平台最好是多核,否则加速也不明显;

Android Zygote 启动流程

线程池 优化Zygote 启动

2.Zygote 启动优化实质

使我们的进程最大限度的抢占CPU

十三、fork SystemServer

经过一系列初始化后,在ZygoteInit类中 forkSystemServer,为启动SystemServer 做准备。ZygoteInit.java代码路径如下:alpsframeworksbasecorejavacomandroidinternalosZygoteInit.java


/**
* Prepare the arguments and forks for the system server process.
*
* Returns an {@code Runnable} that provides an entrypoint into system_server code in the
* child process, and {@code null} in the parent.
*/

private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
long capabilities = posixCapabilitiesAsBits(
OsConstants.CAP_IPC_LOCK,
OsConstants.CAP_KILL,
OsConstants.CAP_NET_ADMIN,
OsConstants.CAP_NET_BIND_SERVICE,
OsConstants.CAP_NET_BROADCAST,
OsConstants.CAP_NET_RAW,
OsConstants.CAP_SYS_MODULE,
OsConstants.CAP_SYS_NICE,
OsConstants.CAP_SYS_PTRACE,
OsConstants.CAP_SYS_TIME,
OsConstants.CAP_SYS_TTY_CONFIG,
OsConstants.CAP_WAKE_ALARM,
OsConstants.CAP_BLOCK_SUSPEND
);
/* Containers run without some capabilities, so drop any caps that are not available. */
StructCapUserHeader header = new StructCapUserHeader(
OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
StructCapUserData[] data;
try {
data = Os.capget(header);
} catch (ErrnoException ex) {
throw new RuntimeException("Failed to capget()", ex);
}
capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);

/* Hardcoded command line to start the system server */
String args[] = {
"--setuid=1000",
"--setgid=1000",
/// M: [Wi-Fi Hotspot Manager] system_server add dhcp (1014) group to access
/// "/data/misc/dhcp/dnsmasq.leases"
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1014,1018,1021,1023," +
"1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;

int pid;

try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

boolean profileSystemServer = SystemProperties.getBoolean(
"dalvik.vm.profilesystemserver", false);
if (profileSystemServer) {
parsedArgs.runtimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
}

/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.runtimeFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}

/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}

zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}

return null;
}


原文始发于微信公众号(哆啦安全):Android Zygote 启动流程

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年7月9日11:43:11
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Android Zygote 启动流程https://cn-sec.com/archives/1861552.html

发表评论

匿名网友 填写信息