赞
踩
基于Android10.0的源码分析Android启动的Zygote进程
Zygote这个词的字面意思是“受精卵”,因而可以孕育出一个新生命。正如其所示Android中大多数应用进程和系统进程都是Zygote来生成的。 那么Zygote是如何启动的,也是由init解析rc脚本时启动。早期Android版本zygote命令直接写在init.rc中,但是随着硬件不断升级换代,Android系统不的不面对32位和64位机器同时存在情况,因为对zygote启动也需要根据不同情况区分对待:
- /system/core/rootdir/init.rc
-
- 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
-
-
根据ro.zygote的具体值,我们需要加载不同的zygote的rc脚本,例如:
init.zygote32.rc
init.zygote32_64.rc
init.zygote64.rc
init.zygote64_32.rc
我们以init.zygote64.rc为例子,相关代码如下:
- 1 service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
- 2 class main
- 3 priority -20
- 4 user root
- 5 group root readproc reserved_disk
- 6 socket zygote stream 660 root system
- 7 socket usap_pool_primary stream 660 root system
- 8 onrestart write /sys/android_power/request_state wake
- 9 onrestart write /sys/power/state on
- 10 onrestart restart audioserver
- 11 onrestart restart cameraserver
- 12 onrestart restart media
- 13 onrestart restart netd
- 14 onrestart restart wificond
- 15 writepid /dev/cpuset/foreground/tasks
从该段脚本看出:
服务名(Servicename): zygote
路径(Path): /system/bin/app_process64
参数(Arguments): -Xzygote /system/bin --start-system-server
Zygote所属的class为main,而不是core。从路径可以看出,它所在程序名叫“app_process64”。通过--zygote参数,app_process可以识别出用户是否需要启动zygote,我们来看下app_process是什么?源码路径frameworks/base/cmds/ ,先看它的Android.mk
-
- 1 LOCAL_PATH:= $(call my-dir)
- 2
- 3 app_process_common_shared_libs := \
- 4 libandroid_runtime \
- 5 libbinder \
- 6 libcutils \
- 7 libdl \
- 8 libhidlbase \
- 9 liblog \
- 10 libnativeloader \
- 11 libutils \
- 12
- 13 # This is a list of libraries that need to be included in order to avoid
- 14 # bad apps. This prevents a library from having a mismatch when resolving
- 15 # new/delete from an app shared library.
- 16 # See b/21032018 for more details.
- 17 app_process_common_shared_libs += \
- 18 libwilhelm \
- 19
- 20 app_process_common_static_libs := \
- 21 libsigchain \
- 22
- 23 app_process_src_files := \
- 24 app_main.cpp \
-
-
- ......
-
-
- 45 LOCAL_MODULE:= app_process
- 46 LOCAL_MULTILIB := both
- 47 LOCAL_MODULE_STEM_32 := app_process32
- 48 LOCAL_MODULE_STEM_64 := app_process64
上述就是Multilib(64位和32位系统)的一个编译脚本范例。其中LOCAL_MULTLIB用于希望针对的硬件架构平台。
分析一下函数app_process的主函数实现:
- int main(int argc,char* const argv) {
- .....
-
- 257 bool zygote = false;
- 258 bool startSystemServer = false;
- 259 bool application = false;
- 260 String8 niceName;
- 261 String8 className;
- 262
- 263 ++i; // Skip unused "parent dir" argument.
- 264 while (i < argc) {
- 265 const char* arg = argv[i++];
- 266 if (strcmp(arg, "--zygote") == 0) {
- 267 zygote = true;
- 268 niceName = ZYGOTE_NICE_NAME;
- 269 } else if (strcmp(arg, "--start-system-server") == 0) {
- 270 startSystemServer = true;
- 271 } else if (strcmp(arg, "--application") == 0) {
- 272 application = true;
- 273 } else if (strncmp(arg, "--nice-name=", 12) == 0) {
- 274 niceName.setTo(arg + 12);
- 275 } else if (strncmp(arg, "--", 2) != 0) {
- 276 className.setTo(arg);
- 277 break;
- 278 } else {
- 279 --i;
- 280 break;
- 281 }
- 282 }
-
- .....
-
- 335 if (zygote) {
- 336 runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
- 337 } else if (className) {
- 338 runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
- 339 } else {
- 340 fprintf(stderr, "Error: no class name or --zygote supplied.\n");
- 341 app_usage();
- 342 LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
- 343 }
- }
这个函数解析了启动app_process时传入参数:
--zygote : 表示当前进程用于承载zygote 。
--start-system-server : 是否需要驱动system_server 。
--application:启动进入独立的程序模式。
--nice-name:此进程的 “别名” 。
整一个场景中,init.rc 指定了--zygote选项,所以app_process接下来启动ZygoteInit,并且传入了“start-system-server”。之后ZygoteInit会运行Java虚拟机上,这是因为runtime就是AndroidRuntime,我们看下AndroidRuntime核心start代码
frameworks/base/core/jni/AndroidRuntime.cpp
- void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
-
- ......
-
- if (startVm(&mJavaVM, &env, zygote) != 0) {
- return;
- }
- onVmCreated(env);
对于虚拟机具体启动和运行过程,本章略过 。
那么虚拟及启动成功后,并进入ZygoteInit的执行中:
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
- try {
- ......
-
- boolean startSystemServer = false;
- String zygoteSocketName = "zygote";
- String abiList = null;
- boolean enableLazyPreload = false;
- for (int i = 1; i < argv.length; i++) {
- if ("start-system-server".equals(argv[i])) {
- startSystemServer = true;
- } else if ("--enable-lazy-preload".equals(argv[i])) {
- enableLazyPreload = true;
- } else if (argv[i].startsWith(ABI_LIST_ARG)) {
- abiList = argv[i].substring(ABI_LIST_ARG.length());
- } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
- zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
- } else {
- throw new RuntimeException("Unknown command line argument: " + argv[i]);
- }
- }
-
-
- if (abiList == null) {
- throw new RuntimeException("No ABI list supplied.");
- }
-
-
- // In such cases, we will preload things prior to our first fork.
- if (!enableLazyPreload) {
- // 预加载各类资源
- preload(bootTimingsTraceLog);
-
- }
-
-
-
- Zygote.initNativeState(isPrimaryZygote);
-
- ZygoteHooks.stopZygoteNoThreadCreation();
-
- // 注册一个Socket
- zygoteServer = new ZygoteServer(isPrimaryZygote);
-
- if (startSystemServer) {
- Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
-
- if (r != null) {
- r.run();
- return;
- }
- }
-
- Log.i(TAG, "Accepting command socket connections");
-
- // The select loop returns early in the child process after a fork and
- // loops forever in the zygote.
- caller = zygoteServer.runSelectLoop(abiList);
- } catch (Throwable ex) {
- Log.e(TAG, "System zygote died with exception", ex);
- throw ex;
- } finally {
- if (zygoteServer != null) {
- zygoteServer.closeServerSocket();
- }
- }
我们可以看到ZygoteInit主函数主要完成以下几项工作:
1. 注册一个socket
2. 预加载各类资源
包括:
preloadClasses();
cacheNonBootClasspathClassLoaders();
preloadResources();
nativePreloadAppProcessHALs();
maybePreloadGraphicsDriver();
preloadSharedLibraries();
preloadTextResources();
WebViewFactory.prepareWebViewInZygote();
已preloadClasses为例子,他负责加载和初始化常用的一些calsses,这个记录都是在framework/base/tools/preload/WritePreloadClassFile.java生成的 。
因为app_aprocess的调用带有“--start-system-server”,那么此时就会通过forkSystemServer函数来启动System Server。
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
- private static Runnable forkSystemServer(String abiList, String socketName,
- 725 ZygoteServer zygoteServer) {
- String args[] = {
- 754 "--setuid=1000",
- 755 "--setgid=1000",
- 756 "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
- 757 + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
- 758 "--capabilities=" + capabilities + "," + capabilities,
- 759 "--nice-name=system_server",
- 760 "--runtime-args",
- 761 "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
- 762 "com.android.server.SystemServer",
- 763 };
- 764 ZygoteArguments parsedArgs = null;
- 765
- 766 int pid;
- 767
- 768 try {
- 769 parsedArgs = new ZygoteArguments(args);
- 770 Zygote.applyDebuggerSystemProperty(parsedArgs);
- 771 Zygote.applyInvokeWithSystemProperty(parsedArgs);
- 772
- 773 boolean profileSystemServer = SystemProperties.getBoolean(
- 774 "dalvik.vm.profilesystemserver", false);
- 775 if (profileSystemServer) {
- 776 parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
- 777 }
- 778
- 779 /* Request to fork the system server process */
- 780 pid = Zygote.forkSystemServer(
- 781 parsedArgs.mUid, parsedArgs.mGid,
- 782 parsedArgs.mGids,
- 783 parsedArgs.mRuntimeFlags,
- 784 null,
- 785 parsedArgs.mPermittedCapabilities,
- 786 parsedArgs.mEffectiveCapabilities);
- 787 } catch (IllegalArgumentException ex) {
- 788 throw new RuntimeException(ex);
- 789 }
- 790
- 791 /* For child process */
- 792 if (pid == 0) {
- 793 if (hasSecondZygote(abiList)) {
- 794 waitForSecondaryZygote(socketName);
- 795 }
- 796
- 797 zygoteServer.closeServerSocket();
- 798 return handleSystemServerProcess(parsedArgs);
- 799 }
- 800
- 801 return null;
- }
上述的代码又出现了fork流程--forkSytemServer在利用内部UNIX的fork机制来创建一个新进程。
随后在执行过程中通过handleSystemServerProcess来启动各种支撑系统运行的System Server 。
我们来分析一下Zygote的工作做一个分析,forkSystemServer中并没有为父进程专门开辟一个代码分支,返回很正常Runnable后,返回到了ZygoteInit函数的 runSelectLoop ,我们可以看到这是一个死循环 ,除非Zygote退出或者异常才会跳出循环。
我们从runSelectLoop函数的
- Runnable runSelectLoop(String abiList) {
- ArrayList<FileDescriptor> socketFDs = new ArrayList<FileDescriptor>();
- ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
-
- socketFDs.add(mZygoteSocket.getFileDescriptor());
- peers.add(null);
获取到前面的ZygoteServer创建的Server Socket文件描述符,他会被添加到ArrayList<FileDescriptor>类型的fds中。
当有客户端的数据需要处理时候,完成具体工作是processOneCommand 函数
/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
- fd = null;
- 266
- 267 pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
- 268 parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
- 269 parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
- 270 parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mTargetSdkVersion);
- 271
- 272 try {
- 273 if (pid == 0) {
- 274 // in child
- 275 zygoteServer.setForkChild();
- 276
- 277 zygoteServer.closeServerSocket();
- 278 IoUtils.closeQuietly(serverPipeFd);
- 279 serverPipeFd = null;
- 280
- 281 return handleChildProc(parsedArgs, descriptors, childPipeFd,
- 282 parsedArgs.mStartChildZygote);
- 283 } else {
- 284 // In the parent. A pid < 0 indicates a failure and will be handled in
- 285 // handleParentProc.
- 286 IoUtils.closeQuietly(childPipeFd);
- 287 childPipeFd = null;
- 288 handleParentProc(pid, descriptors, serverPipeFd);
- 289 return null;
- 290 }
zygote需要为每个新启动的应用程序生成独立的进程。. 不过没有直接用fork来完成,而是调用了forkAndSpecialize函数,新进程运行应用程序本身代码,这些工作在函数 handleChildProc函数中进行。
我们跟一下forkAndSpecialize函数:
- public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
- 235 int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
- 236 int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
- 237 int targetSdkVersion) {
- 238 ZygoteHooks.preFork();
- 239 // Resets nice priority for zygote process.
- 240 resetNicePriority();
- 241 int pid = nativeForkAndSpecialize(
- 242 uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
- 243 fdsToIgnore, startChildZygote, instructionSet, appDataDir);
- 244 // Enable tracing as soon as possible for the child process.
- 245 if (pid == 0) {
- 246 Zygote.disableExecuteOnly(targetSdkVersion);
- 247 Trace.setTracingEnabled(true, runtimeFlags);
- 248
- 249 // Note that this event ends at the end of handleChildProc,
- 250 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
- 251 }
- 252 ZygoteHooks.postForkCommon();
- 253 return pid;
- 254 }
处理分为3个阶段:preFork 、 nativeForkAndSpecialize 、postForkCommon
从以上的分析可以得知,Zygote进程启动中承担的主要职责如下:
参考:
书籍: 深入理解Android内核设计思想 第2版(上册)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。