[关闭]
@guhuizaifeiyang 2017-09-04T10:12:42.000000Z 字数 14400 阅读 1809

Android系统进程Zygote启动过程分析

开关机流程


我们知道,Android系统是基于Linux内核的,而在linux系统中,所有的进程都是init进程的子孙进程,也就是说,所有的进程都是直接或者间接地由init进程fork出来的。Zygote进程也不例外,它是在系统启动的过程,由init进程创建的。在系统启动脚本system/core/rootdir/init.rc文件中,我们可以看到启动Zygote进程的脚本命令(MSM8937平台启动Zygote进程的脚本命令放在system/core/rootdir/init.zygote64.rc):

  1. service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
  2. class main
  3. socket zygote stream 660 root system
  4. onrestart write /sys/android_power/request_state wake
  5. onrestart write /sys/power/state on
  6. onrestart restart audioserver
  7. onrestart restart cameraserver
  8. onrestart restart media
  9. onrestart restart netd
  10. writepid /dev/cpuset/foreground/tasks
  1. // 详见frameworks/base/cmds/app_process/app_main.cpp:
  2. // arguments :
  3. //
  4. // --zygote : Start in zygote mode
  5. // --start-system-server : Start the system server.
  6. // --application : Start in application (stand alone, non zygote) mode.
  7. // --nice-name : The nice name for this process.

最后的一系列onrestart关键字表示这个zygote进程重启时需要执行的命令。

关于init.rc文件的更多信息,请参考system/core/init/readme.txt文件。

了解了这个信息之后,我们就知道Zygote进程要执行的程序便是system/bin/app_process了,它的源代码位于frameworks/base/cmds/app_process/app_main.cpp文件中,入口函数是main。在继续分析Zygote进程启动的过程之前,我们先来看看它的启动序列图:

Zygote.bmp-2614.5kB

Step 1. app_main.cpp

这个函数定义在frameworks/base/cmds/app_process/app_main.cpp文件中:

  1. int main(int argc, char* const argv[])
  2. {
  3. ...
  4. // 1. 隐式创建一个AppRuntime对象:runtime
  5. AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
  6. // Process command line arguments
  7. // ignore argv[0]
  8. argc--;
  9. argv++;
  10. int i;
  11. for (i = 0; i < argc; i++) {
  12. if (argv[i][0] != '-') {
  13. break;
  14. }
  15. if (argv[i][1] == '-' && argv[i][2] == 0) {
  16. ++i; // Skip --.
  17. break;
  18. }
  19. runtime.addOption(strdup(argv[i]));
  20. }
  21. // Parse runtime arguments. Stop at first unrecognized option.
  22. bool zygote = false;
  23. bool startSystemServer = false;
  24. bool application = false;
  25. String8 niceName;
  26. String8 className;
  27. // 2. 处理输入参数
  28. ++i; // Skip unused "parent dir" argument.
  29. while (i < argc) {
  30. const char* arg = argv[i++];
  31. if (strcmp(arg, "--zygote") == 0) {
  32. zygote = true;
  33. niceName = ZYGOTE_NICE_NAME;
  34. } else if (strcmp(arg, "--start-system-server") == 0) {
  35. startSystemServer = true;
  36. } else if (strcmp(arg, "--application") == 0) {
  37. application = true;
  38. } else if (strncmp(arg, "--nice-name=", 12) == 0) {
  39. niceName.setTo(arg + 12);
  40. } else if (strncmp(arg, "--", 2) != 0) {
  41. className.setTo(arg);
  42. break;
  43. } else {
  44. --i;
  45. break;
  46. }
  47. }
  48. ...
  49. if (zygote) {
  50. // 3. 最终走到这里
  51. runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
  52. } else if (className) {
  53. runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
  54. } else {
  55. fprintf(stderr, "Error: no class name or --zygote supplied.\n");
  56. app_usage();
  57. LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
  58. return 10;
  59. }
  60. }

AppRuntime
AppRuntime继承了AndroidRuntime

  1. class AppRuntime : public AndroidRuntime
  2. {
  3. ......
  4. };

由于AppRuntime没有实现自己的start函数,它继承了父类AndroidRuntime的start函数,因此,最终会执行AndroidRuntime类的start函数

Step 2. AndroidRuntime.start

这个函数定义在frameworks/base/core/jni/AndroidRuntime.cpp文件中:

  1. void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
  2. {
  3. ALOGD(">>>>>> START %s uid %d <<<<<<\n",
  4. className != NULL ? className : "(unknown)", getuid());
  5. // 1. 启动SystemServer
  6. static const String8 startSystemServer("start-system-server");
  7. // 2. 调用函数startReg注册JNI方法
  8. /*
  9. * Register android functions.
  10. */
  11. if (startReg(env) < 0) {
  12. ALOGE("Unable to register all android natives\n");
  13. return;
  14. }
  15. /*
  16. * We want to call main() with a String array with arguments in it.
  17. * At present we have two arguments, the class name and an option string.
  18. * Create an array to hold them.
  19. */
  20. jclass stringClass;
  21. jobjectArray strArray;
  22. jstring classNameStr;
  23. stringClass = env->FindClass("java/lang/String");
  24. assert(stringClass != NULL);
  25. strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
  26. assert(strArray != NULL);
  27. classNameStr = env->NewStringUTF(className);
  28. assert(classNameStr != NULL);
  29. env->SetObjectArrayElement(strArray, 0, classNameStr);
  30. for (size_t i = 0; i < options.size(); ++i) {
  31. jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
  32. assert(optionsStr != NULL);
  33. env->SetObjectArrayElement(strArray, i + 1, optionsStr);
  34. }
  35. /*
  36. * Start VM. This thread becomes the main thread of the VM, and will
  37. * not return until the VM exits.
  38. */
  39. char* slashClassName = toSlashClassName(className);
  40. jclass startClass = env->FindClass(slashClassName);
  41. if (startClass == NULL) {
  42. ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
  43. /* keep going */
  44. } else {
  45. jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
  46. "([Ljava/lang/String;)V");
  47. if (startMeth == NULL) {
  48. ALOGE("JavaVM unable to find main() in '%s'\n", className);
  49. /* keep going */
  50. } else {
  51. env->CallStaticVoidMethod(startClass, startMeth, strArray);
  52. ...
  53. }

这个函数的作用是启动Android系统运行时库,它主要做了三件事情,一是调用函数startVM启动虚拟机,二是调用函数startReg注册JNI方法,三是调用了com.android.internal.os.ZygoteInit类的main函数。

Step 3. ZygoteInit.main

这个函数定义在frameworks/base/core/Java/com/android/internal/os/ZygoteInit.java文件中:

  1. public static void main(String argv[]) {
  2. ...
  3. // 1. 调用registerZygoteSocket函数创建了一个socket接口,用来和ActivityManagerService通讯
  4. registerZygoteSocket(socketName);
  5. // 2. 调用startSystemServer函数来启动SystemServer组件
  6. if (startSystemServer) {
  7. startSystemServer(abiList, socketName);
  8. }
  9. // 3. 调用runSelectLoopMode函数
  10. runSelectLoop(abiList);
  11. }

它主要作了三件事情,一个调用registerZygoteSocket函数创建了一个socket接口,用来和ActivityManagerService通讯,二是调用startSystemServer函数来启动SystemServer组件,三是调用runSelectLoopMode函数进入一个无限循环在前面创建的socket接口上等待ActivityManagerService请求创建新的应用程序进程。

Step 4. ZygoteInit.registerZygoteSocket

这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:

  1. public class ZygoteInit {
  2. ......
  3. /**
  4. * Registers a server socket for zygote command connections
  5. *
  6. * @throws RuntimeException when open fails
  7. */
  8. private static void registerZygoteSocket() {
  9. if (sServerSocket == null) {
  10. int fileDesc;
  11. try {
  12. String env = System.getenv(ANDROID_SOCKET_ENV);
  13. fileDesc = Integer.parseInt(env);
  14. } catch (RuntimeException ex) {
  15. ......
  16. }
  17. try {
  18. sServerSocket = new LocalServerSocket(
  19. createFileDescriptor(fileDesc));
  20. } catch (IOException ex) {
  21. .......
  22. }
  23. }
  24. }
  25. ......
  26. }

这个socket接口是通过文件描述符来创建的,这个文件描符代表的就是我们前面说的/dev/socket/zygote文件了。这个文件描述符是通过环境变量ANDROID_SOCKET_ENV得到的。

Step 5. ZygoteInit.startSystemServer

这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:

  1. private static boolean startSystemServer(String abiList, String socketName)
  2. throws MethodAndArgsCaller, RuntimeException {
  3. ...
  4. /* Hardcoded command line to start the system server */
  5. String args[] = {
  6. "--setuid=1000",
  7. "--setgid=1000",
  8. "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007,3009,3010",
  9. "--capabilities=" + capabilities + "," + capabilities,
  10. "--nice-name=system_server",
  11. "--runtime-args",
  12. "com.android.server.SystemServer",
  13. };
  14. ZygoteConnection.Arguments parsedArgs = null;
  15. int pid;
  16. try {
  17. parsedArgs = new ZygoteConnection.Arguments(args);
  18. ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
  19. ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
  20. /* Request to fork the system server process */
  21. pid = Zygote.forkSystemServer(
  22. parsedArgs.uid, parsedArgs.gid,
  23. parsedArgs.gids,
  24. parsedArgs.debugFlags,
  25. null,
  26. parsedArgs.permittedCapabilities,
  27. parsedArgs.effectiveCapabilities);
  28. } catch (IllegalArgumentException ex) {
  29. throw new RuntimeException(ex);
  30. }
  31. /* For child process */
  32. if (pid == 0) {
  33. if (hasSecondZygote(abiList)) {
  34. waitForSecondaryZygote(socketName);
  35. }
  36. handleSystemServerProcess(parsedArgs);
  37. }
  38. return true;
  39. }

这里我们可以看到,Zygote进程通过Zygote.forkSystemServer函数来创建一个新的进程来启动SystemServer组件,返回值pid等0的地方就是新的进程要执行的路径,即新创建的进程会执行handleSystemServerProcess函数。

Step 6. ZygoteInit.handleSystemServerProcess

这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:

  1. public class ZygoteInit {
  2. ......
  3. private static void handleSystemServerProcess(
  4. ZygoteConnection.Arguments parsedArgs)
  5. throws ZygoteInit.MethodAndArgsCaller {
  6. closeServerSocket();
  7. /*
  8. * Pass the remaining arguments to SystemServer.
  9. * "--nice-name=system_server com.android.server.SystemServer"
  10. */
  11. RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
  12. /* should never reach here */
  13. }
  14. ......
  15. }

由于由Zygote进程创建的子进程会继承Zygote进程在前面Step 4中创建的Socket文件描述符,而这里的子进程又不会用到它,因此,这里就调用closeServerSocket函数来关闭它。这个函数接着调用RuntimeInit.zygoteInit函数来进一步执行启动SystemServer组件的操作。

Step 7. RuntimeInit.zygoteInit

这个函数定义在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:

  1. public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
  2. throws ZygoteInit.MethodAndArgsCaller {
  3. if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
  4. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
  5. redirectLogStreams();
  6. commonInit();
  7. nativeZygoteInit();
  8. applicationInit(targetSdkVersion, argv, classLoader);
  9. }

nativeZygoteInit()是一个Native函数,实现在frameworks/base/core/jni/AndroidRuntime.cpp文件中。

Step 8. AndroidRuntime.com_android_internal_os_RuntimeInit_nativeZygoteInit

Step 9. SystemServer.main

这个函数定义在frameworks/base/services/java/com/android/server/SystemServer.java文件中:

  1. /**
  2. * The main entry point from zygote.
  3. */
  4. public static void main(String[] args) {
  5. new SystemServer().run();
  6. }
  1. private void run() {
  2. try {
  3. ...
  4. // Here we go!
  5. Slog.i(TAG, "Entered the Android system server!");
  6. ...
  7. // Initialize the system context.
  8. createSystemContext();
  9. // Create the system service manager.
  10. mSystemServiceManager = new SystemServiceManager(mSystemContext);
  11. mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
  12. LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
  13. } finally {
  14. Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
  15. }
  16. // Start services.
  17. try {
  18. Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
  19. startBootstrapServices();
  20. startCoreServices();
  21. startOtherServices();
  22. } catch (Throwable ex) {
  23. Slog.e("System", "******************************************");
  24. Slog.e("System", "************ Failure starting system services", ex);
  25. throw ex;
  26. } finally {
  27. Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
  28. }
  29. ...
  30. // Loop forever.
  31. Looper.loop();
  32. throw new RuntimeException("Main thread loop unexpectedly exited");
  33. }

里面主要涉及了是三个方法:
startBootstrapServices() 主要用于启动系统Boot级服务
startCoreServices() 主要用于启动系统核心的服务
startOtherServices() 主要用于启动一些非紧要或者是非需要及时启动的服务

Step 10. SystemServer.startBootstrapServices

  1. private void startBootstrapServices() {
  2. // 1. start Installer
  3. Installer installer = mSystemServiceManager.startService(Installer.class);
  4. // 2. start ActivityManagerService
  5. // Activity manager runs the show.
  6. mActivityManagerService = mSystemServiceManager.startService(
  7. ActivityManagerService.Lifecycle.class).getService();
  8. mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
  9. mActivityManagerService.setInstaller(installer);
  10. // 3. start PowerManagerService
  11. mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
  12. // 4. initialize power management features.
  13. mActivityManagerService.initPowerManagement();
  14. // 5. start LightsService
  15. mSystemServiceManager.startService(LightsService.class);
  16. // 6. start DisplayManagerService
  17. // starts up.
  18. mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
  19. // 7. Start the package manager.
  20. mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
  21. mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
  22. mFirstBoot = mPackageManagerService.isFirstBoot();
  23. mPackageManager = mSystemContext.getPackageManager();
  24. ...
  25. // 8. start UserManagerService
  26. mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
  27. // 9. Initialize attribute cache used to cache resources from packages.
  28. AttributeCache.init(mSystemContext);
  29. // 10. Set up the Application instance for the system process and get started.
  30. mActivityManagerService.setSystemProcess();
  31. // 11. start SensorService
  32. startSensorService();
  33. }

可见,BootstrapServices中启动了:
1. ActivityManagerService
2. PowerManagerService
3. LightsService
4. DisplayManagerService
5. UserManagerService
6. SensorService

Step 11. startCoreServices

  1. /**
  2. * Starts some essential services that are not tangled up in the bootstrap process.
  3. */
  4. private void startCoreServices() {
  5. // Tracks the battery level. Requires LightService.
  6. mSystemServiceManager.startService(BatteryService.class);
  7. // Tracks application usage stats.
  8. mSystemServiceManager.startService(UsageStatsService.class);
  9. mActivityManagerService.setUsageStatsManager(
  10. LocalServices.getService(UsageStatsManagerInternal.class));
  11. // Tracks whether the updatable WebView is in a ready state and watches for update installs.
  12. mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
  13. }

CoreServices中启动了:

  1. BatteryService
  2. UsageStatsService
  3. WebViewUpdateService

Step 12. startOtherServices

  1. try {
  2. // 1. add SchedulingPolicyService
  3. ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());
  4. // 2. start TelecomLoaderService
  5. mSystemServiceManager.startService(TelecomLoaderService.class);
  6. // 3. add telephonyRegistry
  7. telephonyRegistry = new TelephonyRegistry(context);
  8. ServiceManager.addService("telephony.registry", telephonyRegistry);
  9. if (!disableCameraService) {
  10. // 4. start CameraService
  11. mSystemServiceManager.startService(CameraService.class);
  12. }
  13. // The AccountManager must come before the ContentService
  14. // 5. start AccountManager
  15. mSystemServiceManager.startService(ACCOUNT_SERVICE_CLASS);
  16. // 6. start ContentService
  17. mSystemServiceManager.startService(CONTENT_SERVICE_CLASS);
  18. // 7. InstallSystemProviders
  19. mActivityManagerService.installSystemProviders();
  20. // 8. start VibratorService
  21. vibrator = new VibratorService(context);
  22. ServiceManager.addService("vibrator", vibrator);
  23. if (!disableConsumerIr) {
  24. // 9. start ConsumerIrService
  25. consumerIr = new ConsumerIrService(context);
  26. ServiceManager.addService(Context.CONSUMER_IR_SERVICE, consumerIr);
  27. }
  28. // 10. start AlarmManagerService
  29. mSystemServiceManager.startService(AlarmManagerService.class);
  30. // 11. init InitWatchdog
  31. final Watchdog watchdog = Watchdog.getInstance();
  32. watchdog.init(context, mActivityManagerService);
  33. // 12. start InputManagerService
  34. inputManager = new InputManagerService(context);
  35. // 13. start WindowManagerService
  36. wm = WindowManagerService.main(context, inputManager,
  37. mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
  38. !mFirstBoot, mOnlyCore);
  39. ServiceManager.addService(Context.WINDOW_SERVICE, wm);
  40. ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
  41. if (!disableVrManager) {
  42. // 14. start VrManagerService
  43. mSystemServiceManager.startService(VrManagerService.class);
  44. }
  45. mActivityManagerService.setWindowManager(wm);
  46. inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
  47. inputManager.start();
  48. // 15. start BluetoothService
  49. mSystemServiceManager.startService(BluetoothService.class);
  50. // 16. start MetricsLoggerService
  51. mSystemServiceManager.startService(MetricsLoggerService.class);
  52. // 17. start IpConnectivityMetrics
  53. mSystemServiceManager.startService(IpConnectivityMetrics.class);
  54. // 18. start PinnerService
  55. mSystemServiceManager.startService(PinnerService.class);
  56. } catch (RuntimeException e) {
  57. ...
  58. }

// TODO
可以看出,otherServices中启动了大量的Services,后续再详细分析。
1. CameraService
2. ContentService
3. AlarmManagerService
4. InputManagerService
5. WindowManagerService
6. BluetoothService
...

总结:

  1. SystemServer进程是android中一个很重要的进程由Zygote进程启动;

  2. SystemServer进程主要用于启动系统中的服务;

  3. SystemServer进程启动服务的启动函数为main函数;

  4. SystemServer进程将系统服务分为三类:boot服务,core服务和other服务,并逐步启动

  5. 当我们需要启动一个Android应用程序时,ActivityManagerService会通过Socket进程间通信机制,通知Zygote进程为这个应用程序创建一个新的进程。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注