zoukankan      html  css  js  c++  java
  • Android之 系统启动流程

    在前一篇文章"Android之 看“马达”如何贯通Android系统 (从硬件设计 --> 驱动 --> HAL --> JNI --> Framework --> Application)"中,我们谈到“马达等系统服务都是通过SystemServer启动/管理的”。本章,我们就Android的系统启动流程进行分析;也说说SystemServer到底是如何工作的。

    转载请注明出处:http://www.cnblogs.com/skywang12345/p/3405100.html

    在详细说明之后,我们先建立个整体思路:
    Kernel中启动的第一个用户进程是init程序;而init会通过解析init.rc来启动zygote服务;而zygote又会进一步的启动SystemServer。在SystemServer中,Android会启动一系列的系统服务共用户调用。整个流程大致如此。下面,我们通过源码来查看一下各个环节到底是如何运作的。


    1. kernel启动init服务

    在Linux的内核init/main.c中,启动的/init程序。源码如下:

     1 static int __init kernel_init(void * unused)
     2 {
     3 
     4     ...
     5         
     6     // “设置第一个运行程序是/init”
     7     if (!ramdisk_execute_command)
     8         ramdisk_execute_command = "/init";
     9 
    10         ...
    11 
    12     init_post();
    13     return 0;
    14 }
    15 
    16 
    17 static noinline int init_post(void)
    18     __releases(kernel_lock)
    19 {
    20 
    21     ...
    22     // 运行"/init"程序
    23     if (ramdisk_execute_command) {
    24         run_init_process(ramdisk_execute_command);
    25         printk(KERN_WARNING "Failed to execute %s
    ",
    26                 ramdisk_execute_command);
    27     }
    28 
    29     ...
    30 
    31     run_init_process("/sbin/init");
    32     run_init_process("/etc/init");
    33     run_init_process("/bin/init");
    34     run_init_process("/bin/sh");
    35 
    36     ...
    37 }

    从中,我们发现:kernel_init()中会将ramdisk_execute_command的值初始化为"/init",进而在init_post()中调用run_init_process(),从而执行"/init"程序。
    我们所说的kernel内核空间到用户空间启动的第一个init程序,实际上就是"/init"程序。

    2. init服务的定义

    2.1 init的配置文件

    Android系统中init程序对应的Android.mk所在路径:system/core/init/Android.mk。内容如下: 

     1 LOCAL_PATH:= $(call my-dir)
     2 include $(CLEAR_VARS)
     3 
     4 LOCAL_SRC_FILES:= 
     5     builtins.c 
     6     init.c 
     7     devices.c 
     8     property_service.c 
     9     util.c 
    10     parser.c 
    11     logo.c 
    12     keychords.c 
    13     signal_handler.c 
    14     init_parser.c 
    15     ueventd.c 
    16     ueventd_parser.c 
    17     watchdogd.c
    18 
    19 LOCAL_MODULE:= init
    20 
    21 include $(BUILD_EXECUTABLE)
    22 
    23 ...

    说明: 在“完整的编译Android系统” 或 “对init执行模块编译(即$ mmm system/core/init)”的时候,会在system下生产文件out/.../root/init。"/root/init"意味着init在rootfs文件系统下,而不是system文件系统下。这也意味着,init会被解压到系统的根目录,即对应/init文件!

    2.2 init的程序入口

    init程序的入口函数main()定义在system/core/init/init.c中,源码如下:

     1 int main(int argc, char **argv)
     2 {
     3 
     4     ...
     5 
     6     // 创建目录
     7     mkdir("/dev", 0755);
     8     mkdir("/proc", 0755);
     9     mkdir("/sys", 0755);
    10 
    11     mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
    12     mkdir("/dev/pts", 0755);
    13     mkdir("/dev/socket", 0755);
    14     mount("devpts", "/dev/pts", "devpts", 0, NULL);
    15     mount("proc", "/proc", "proc", 0, NULL);
    16     mount("sysfs", "/sys", "sysfs", 0, NULL);
    17 
    18     ...
    19 
    20     init_parse_config_file("/init.rc");
    21 
    22     ...
    23 }

    说明在init程序中,我们会进行一些列的初始化,包括创建目录,解析"init.rc"文件,启动相应的系统服务和守护进程等。zygote服务定义在init.rc中,它是在init中启动的。

    3. init启动解析init.rc,并启动zygote

    init.rc的路径:system/core/rootdir/init.rc。zygote在init.rc中的定义如下:

    service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server

    从中,我们知道:zygote是service名称,而/system/bin/app_process是zygote对应的进程。后面的内容是service的参数。

    4. zygote服务

    4.1 zygote服务的配置文件

    通过init.rc中zygote的定义,我们知道zygote对应是通过/system/bin/app_process是启动的。app_process对应的Android.mk的路径:frameworks/base/cmds/app_process/Android.mk。它的内容如下:

     1 LOCAL_PATH:= $(call my-dir)
     2 include $(CLEAR_VARS)
     3 
     4 LOCAL_SRC_FILES:= 
     5     app_main.cpp
     6 
     7 LOCAL_SHARED_LIBRARIES := 
     8     libcutils 
     9     libutils 
    10     libbinder 
    11     libandroid_runtime
    12 
    13 LOCAL_MODULE:= app_process
    14 
    15 include $(BUILD_EXECUTABLE)

    从中,我们知道/system/bin/app_process会执行app_main.cpp。

    4.2 zygote对应的程序app_main.app

    app_main.cpp的入口main()源码如下:

     1 int main(int argc, const char* const argv[])
     2 {
     3     // These are global variables in ProcessState.cpp
     4     mArgC = argc;
     5     mArgV = argv;
     6 
     7     mArgLen = 0;
     8     for (int i=0; i<argc; i++) {
     9         mArgLen += strlen(argv[i]) + 1;
    10     }
    11     mArgLen--;
    12 
    13     AppRuntime runtime;
    14     const char* argv0 = argv[0];
    15 
    16     // Process command line arguments
    17     // ignore argv[0]
    18     argc--;
    19     argv++;
    20 
    21     // Everything up to '--' or first non '-' arg goes to the vm
    22 
    23     int i = runtime.addVmArguments(argc, argv);
    24 
    25     // Parse runtime arguments.  Stop at first unrecognized option.
    26     bool zygote = false;
    27     bool startSystemServer = false;
    28     bool application = false;
    29     const char* parentDir = NULL;
    30     const char* niceName = NULL;
    31     const char* className = NULL;
    32     // 解析参数
    33     while (i < argc) {
    34         const char* arg = argv[i++];
    35         if (!parentDir) {
    36             parentDir = arg;
    37         } else if (strcmp(arg, "--zygote") == 0) {
    38             // 设置zygote为true
    39             zygote = true;
    40             niceName = "zygote";
    41         } else if (strcmp(arg, "--start-system-server") == 0) {
    42             // 设置startSystemServer为true
    43             startSystemServer = true;
    44         } else if (strcmp(arg, "--application") == 0) {
    45             application = true;
    46         } else if (strncmp(arg, "--nice-name=", 12) == 0) {
    47             niceName = arg + 12;
    48         } else {
    49             className = arg;
    50             break;
    51         }
    52     }
    53 
    54     if (niceName && *niceName) {
    55         setArgv0(argv0, niceName);
    56         set_process_name(niceName);
    57     }
    58 
    59     runtime.mParentDir = parentDir;
    60 
    61     if (zygote) {
    62         // 启动"com.android.internal.os.ZygoteInit"
    63         runtime.start("com.android.internal.os.ZygoteInit",
    64                 startSystemServer ? "start-system-server" : "");
    65     } else if (className) {
    66         // Remainder of args get passed to startup class main()
    67         runtime.mClassName = className;
    68         runtime.mArgC = argc - i;
    69         runtime.mArgV = argv + i;
    70         runtime.start("com.android.internal.os.RuntimeInit",
    71                 application ? "application" : "tool");
    72     } else {
    73         fprintf(stderr, "Error: no class name or --zygote supplied.
    ");
    74         app_usage();
    75         LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    76         return 10;
    77     }
    78 }

    从中,我们可以知道main()最终会调用以下代码:

    runtime.start("com.android.internal.os.ZygoteInit",
            startSystemServer ? "start-system-server" : "");

    我们接着看start()的代码。start()的源码定义在frameworks/base/core/jni/AndroidRuntime.cpp中。

    runtime是AppRuntime成员。AppRuntime定义在app_main.cpp中,声明如下:

    class AppRuntime : public AndroidRuntime {
      ...
    }

    显然AppRuntime继承于AndroidRuntime。

    4. AndroidRuntime.cpp

    start()的源码如下:

      1 void AndroidRuntime::start(const char* className, const char* options)
      2 {
      3     ALOGD("
    >>>>>> AndroidRuntime START %s <<<<<<
    ",
      4             className != NULL ? className : "(unknown)");
      5 
      6     blockSigpipe();
      7 
      8     /*
      9      * 'startSystemServer == true' means runtime is obsolete and not run from
     10      * init.rc anymore, so we print out the boot start event here.
     11      */
     12     if (strcmp(options, "start-system-server") == 0) {
     13         /* track our progress through the boot sequence */
     14         const int LOG_BOOT_PROGRESS_START = 3000;
     15         LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,
     16                        ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
     17     }
     18 
     19     const char* rootDir = getenv("ANDROID_ROOT");
     20     if (rootDir == NULL) {
     21         rootDir = "/system";
     22         if (!hasDir("/system")) {
     23             LOG_FATAL("No root directory specified, and /android does not exist.");
     24             return;
     25         }
     26         setenv("ANDROID_ROOT", rootDir, 1);
     27     }
     28 
     29     //const char* kernelHack = getenv("LD_ASSUME_KERNEL");
     30     //ALOGD("Found LD_ASSUME_KERNEL='%s'
    ", kernelHack);
     31 
     32     /* start the virtual machine */
     33     JNIEnv* env;
     34     if (startVm(&mJavaVM, &env) != 0) {
     35         return;
     36     }
     37     onVmCreated(env);
     38 
     39     /*
     40      * Register android functions.
     41      */
     42     if (startReg(env) < 0) {
     43         ALOGE("Unable to register all android natives
    ");
     44         return;
     45     }
     46 
     47     /*
     48      * We want to call main() with a String array with arguments in it.
     49      * At present we have two arguments, the class name and an option string.
     50      * Create an array to hold them.
     51      */
     52     jclass stringClass;
     53     jobjectArray strArray;
     54     jstring classNameStr;
     55     jstring optionsStr;
     56 
     57     stringClass = env->FindClass("java/lang/String");
     58     assert(stringClass != NULL);
     59     strArray = env->NewObjectArray(2, stringClass, NULL);
     60     assert(strArray != NULL);
     61     classNameStr = env->NewStringUTF(className);
     62     assert(classNameStr != NULL);
     63     env->SetObjectArrayElement(strArray, 0, classNameStr);
     64     optionsStr = env->NewStringUTF(options);
     65     env->SetObjectArrayElement(strArray, 1, optionsStr);
     66 
     67     /*
     68      * Start VM.  This thread becomes the main thread of the VM, and will
     69      * not return until the VM exits.
     70      */
     71     // 将"com.android.internal.os.ZygoteInit"转换为"com/android/internal/os/ZygoteInit"
     72     char* slashClassName = toSlashClassName(className);
     73     // 获取"com/android/internal/os/ZygoteInit"对应的class对象
     74     jclass startClass = env->FindClass(slashClassName);
     75     if (startClass == NULL) {
     76         ALOGE("JavaVM unable to locate class '%s'
    ", slashClassName);
     77         /* keep going */
     78     } else {
     79         // 找到"com/android/internal/os/ZygoteInit"中main()方法的methodID
     80         jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
     81             "([Ljava/lang/String;)V");
     82         if (startMeth == NULL) {
     83             ALOGE("JavaVM unable to find main() in '%s'
    ", className);
     84             /* keep going */
     85         } else {
     86             // 执行"com/android/internal/os/ZygoteInit"中main()方法
     87             env->CallStaticVoidMethod(startClass, startMeth, strArray);
     88 
     89 #if 0
     90             if (env->ExceptionCheck())
     91                 threadExitUncaughtException(env);
     92 #endif
     93         }
     94     }
     95     free(slashClassName);
     96 
     97     ALOGD("Shutting down VM
    ");
     98     if (mJavaVM->DetachCurrentThread() != JNI_OK)
     99         ALOGW("Warning: unable to detach main thread
    ");
    100     if (mJavaVM->DestroyJavaVM() != 0)
    101         ALOGW("Warning: VM did not shut down cleanly
    ");
    102 }
    View Code

    说明start()是通过JNI回调java层的方法,它主要的目的是执行"com/android/internal/os/ZygoteInit"中main()方法,即frameworks/base/core/java/com/android/internal/os/ZygoteInit.java中的main()函数。

    5. ZygoteInit.java

    frameworks/base/core/java/com/android/internal/os/ZygoteInit.java中的main()源码如下:

     1 public static void main(String argv[]) {
     2     try {
     3         // Start profiling the zygote initialization.
     4         SamplingProfilerIntegration.start();
     5 
     6         registerZygoteSocket();
     7         EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
     8             SystemClock.uptimeMillis());
     9         preload();
    10         EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
    11             SystemClock.uptimeMillis());
    12 
    13         // Finish profiling the zygote initialization.
    14         SamplingProfilerIntegration.writeZygoteSnapshot();
    15 
    16         // Do an initial gc to clean up after startup
    17         gc();
    18 
    19         // If requested, start system server directly from Zygote
    20         if (argv.length != 2) {
    21             throw new RuntimeException(argv[0] + USAGE_STRING);
    22         }
    23 
    24         if (argv[1].equals("start-system-server")) {
    25             // 调用startSystemServer()
    26             startSystemServer();
    27         } else if (!argv[1].equals("")) {
    28             throw new RuntimeException(argv[0] + USAGE_STRING);
    29         }
    30 
    31         Log.i(TAG, "Accepting command socket connections");
    32 
    33         if (ZYGOTE_FORK_MODE) {
    34             runForkMode();
    35         } else {
    36             runSelectLoopMode();
    37         }
    38 
    39         closeServerSocket();
    40     } catch (MethodAndArgsCaller caller) {
    41         caller.run();
    42     } catch (RuntimeException ex) {
    43         Log.e(TAG, "Zygote died with exception", ex);
    44         closeServerSocket();
    45         throw ex;
    46     }
    47 }
    View Code

    说明:main()会执行startSystemServer()来启动系统服务。

    startSystemServer()也是定义在ZygoteInit.java中,源码如下:

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

    说明
         startSystemServer()会通过Zygote.forkSystemServer()函数来创建一个新的进程来启动SystemServer组件,返回值pid等0的地方就是新的进程要执行的路径,即新创建的进程会执行handleSystemServerProcess()函数。 

    handleSystemServerProcess()也是定义在ZygoteInit.java中,源码如下:

     1 private static void handleSystemServerProcess(
     2         ZygoteConnection.Arguments parsedArgs)
     3         throws ZygoteInit.MethodAndArgsCaller {
     4 
     5     closeServerSocket();
     6 
     7     // set umask to 0077 so new files and directories will default to owner-only permissions.
     8     Libcore.os.umask(S_IRWXG | S_IRWXO);
     9 
    10     if (parsedArgs.niceName != null) {
    11         Process.setArgV0(parsedArgs.niceName);
    12     }
    13 
    14     if (parsedArgs.invokeWith != null) {
    15         WrapperInit.execApplication(parsedArgs.invokeWith,
    16                 parsedArgs.niceName, parsedArgs.targetSdkVersion,
    17                 null, parsedArgs.remainingArgs);
    18     } else {
    19         /*
    20          * Pass the remaining arguments to SystemServer.
    21          */
    22         RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
    23     }
    24 
    25     /* should never reach here */
    26 }
    View Code

    说明handleSystemServerProcess()会调用 RuntimeInit.zygoteInit()器初始化zygote。

    6. RuntimeInit.java

    zygoteInit()定义在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java中,源码如下:

     1 public static final void zygoteInit(int targetSdkVersion, String[] argv)
     2         throws ZygoteInit.MethodAndArgsCaller {
     3     if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
     4 
     5     redirectLogStreams();
     6 
     7     commonInit();
     8     nativeZygoteInit();
     9 
    10     // 通过applicationInit()启动SystemServer
    11     applicationInit(targetSdkVersion, argv);
    12 }

    说明:zygoteInit()会调用applicationInit()函数初始化应用程序SystemServer。

    applicationInit()也定义在RuntimeInit.java中,源码如下:

     1 private static void applicationInit(int targetSdkVersion, String[] argv)
     2         throws ZygoteInit.MethodAndArgsCaller {
     3     nativeSetExitWithoutCleanup(true);
     4 
     5     VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
     6     VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
     7 
     8     final Arguments args;
     9     try {
    10         args = new Arguments(argv);
    11     } catch (IllegalArgumentException ex) {
    12         Slog.e(TAG, ex.getMessage());
    13         // let the process exit
    14         return;
    15     }
    16 
    17     // invokeStaticMain()会执行SystemServer的main()方法。
    18     invokeStaticMain(args.startClass, args.startArgs);
    19 }

    说明:applicationInit()会调用invokeStaticMain()来执行SystemServer的main()方法。

    invokeStaticMain()也定义在RuntimeInit.java中,源码如下:

     1 private static void invokeStaticMain(String className, String[] argv)
     2         throws ZygoteInit.MethodAndArgsCaller {
     3     Class<?> cl;
     4 
     5     try {
     6         // 根据“反射”查找SystemServer对应的Class
     7         cl = Class.forName(className);
     8     } catch (ClassNotFoundException ex) {
     9         throw new RuntimeException(
    10                 "Missing class when invoking static main " + className,
    11                 ex);
    12     }
    13 
    14     Method m;
    15     try {
    16         // 获取SystemServer对应的main()方法
    17         m = cl.getMethod("main", new Class[] { String[].class });
    18     } catch (NoSuchMethodException ex) {
    19         throw new RuntimeException(
    20                 "Missing static main on " + className, ex);
    21     } catch (SecurityException ex) {
    22         throw new RuntimeException(
    23                 "Problem getting static main on " + className, ex);
    24     }
    25 
    26     int modifiers = m.getModifiers();
    27     if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
    28         throw new RuntimeException(
    29                 "Main method is not public and static on " + className);
    30     }
    31 
    32     // 通过ZygoteInit.MethodAndArgsCaller()执行该main()方法
    33     throw new ZygoteInit.MethodAndArgsCaller(m, argv);
    34 }

    说明
        首先,我们要搞清楚invokeStaticMain()的输入参数className,实际上它的值是"com.android.server.SystemServer"。
                  我们看从startSystemServer()方法中的args成员开始查看,在args通过ZygoteConnection.Arguments(args)解析之后得到parsedArgs对象;其中,parsedArgs.remainingArgs就是"com.android.server.SystemServer"。。
        接着,parseArgs传递给handleSystemServerProcess();
       再接着,将parsedArgs.remainingArgs,也就是"com.android.server.SystemServer"传递给了RuntimeInit.zygoteInit()。

    7. ZygoteInit.MethodAndArgsCaller

    MethodAndArgsCaller是一个实现了Runnable的类,它定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java中。源码如下:

     1 public static class MethodAndArgsCaller extends Exception
     2         implements Runnable {
     3     private final Method mMethod;
     4 
     5     private final String[] mArgs;
     6 
     7     public MethodAndArgsCaller(Method method, String[] args) {
     8         mMethod = method;
     9         mArgs = args;
    10     }
    11 
    12     public void run() {
    13         try {
    14             // 通过反射,执行方法mMethod
    15             mMethod.invoke(null, new Object[] { mArgs });
    16         } catch (IllegalAccessException ex) {
    17             throw new RuntimeException(ex);
    18         } catch (InvocationTargetException ex) {
    19             Throwable cause = ex.getCause();
    20             if (cause instanceof RuntimeException) {
    21                 throw (RuntimeException) cause;
    22             } else if (cause instanceof Error) {
    23                 throw (Error) cause;
    24             }
    25             throw new RuntimeException(ex);
    26         }
    27     }
    28 }

    说明:MethodAndArgsCaller()是个线程,它会执行方法mMethod。也就是执行"com.android.server.SystemServer"中的main()方法。
    至此,我们就启动了SystemServer了!

  • 相关阅读:
    泛型系列<9>:使用相应的泛型版本替换Hashtable
    泛型系列<2> 创建泛型类
    泛型系列<5>:链表的实现
    泛型系列<4>使用相应的泛型版本替换Stack和Queue
    泛型系列<8>:使用泛型创建只读集合
    Visual Studio统计有效代码行数
    C++11 现代C++风格的新元素(转)
    神秘海域:顶级工作室“顽皮狗”成长史(中)
    沸腾十五年TX
    为你解惑之WPF经典9问详解
  • 原文地址:https://www.cnblogs.com/skywang12345/p/3405100.html
Copyright © 2011-2022 走看看