结合源码探讨Android系统的启动流程

来源:互联网 发布:可牛拍照软件下载 编辑:程序博客网 时间:2024/06/10 14:48

结合源码探讨Android系统的启动流程


由于本人能力有限,所考虑或者疏忽错漏的地方或多或少应该存在。同时,Android从启动过程开始,实际上就涉及多个技术难点和多种通信机制的知识点。

基于上面两个原因,笔者会一直修改,补充,拓展此文。希望能够坚持下去,从而真正达到触类旁通。


从我们长按手机电源键,到安卓系统完全启动之间,总共经历了以下五个阶段。

第一步:启动电源以及系统启动

当电源按下,引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序到RAM,然后执行。

第二步:引导程序

引导程序是在Android操作系统开始运行前的一个小程序。引导程序是运行的第一个程序,因此它是针对特定的主板与芯片的。设备制造商要么使用很受欢迎的引导程序比如redboot、uboot、qi bootloader或者开发自己的引导程序,它不是Android操作系统的一部分。引导程序是OEM厂商或者运营商加锁和限制的地方。

 引导程序分两个阶段执行。第一个阶段,检测外部的RAM以及加载对第二阶段有用的程序;第二阶段,引导程序设置网络、内存等等。这些对于运行内核是必要的,为了达到特殊的目标,引导程序可以根据配置参数或者输入数据设置内核。

第三步:内核的启动

Android内核与桌面Linux内核启动的方式差不多。内核启动时,设置缓存、被保护存储器、计划列表,加载驱动。当内核完成系统设置,它首先在系统文件中寻找”init”文件,然后启动init进程。

第四步:init进程的启动

init是第一个进程,我们可以说它是root进程或者说有进程的父进程。init进程将进行两个主要操作,一是挂载目录,比如/sys、/dev、/proc,二是运行init.rc脚本。

 

其实第一步到第三步,可以理解为是一个Linux内核的启动的过程。从第四步开始,Android系统才可以算作是“真正”的开始启动。这也是本文所关注的重点起始的地方。先从init.rc脚本开始讲起。

.rc文件是安卓初始化语言,有特定的格式以及规则。例如:

[java] view plain copy
  1. service <name><pathname> [<argument>]*  
  2.   
  3.     <option>  
  4.   
  5.     <option>  
  6.   
  7. ...  

 如上所示,这个语法代表的是启动一个指定路径的服务。

在init.rc这个配置文件中,涉及到两个最关键的步骤:

(init.rc文件既可在源码目录/system/core/rootdir,也可在设备根目录下找到)

1.启动ServiceManager进程

[java] view plain copy
  1. service servicemanager /system/bin/servicemanager  

ServiceManager是Binder的服务管理守护进程,是Binder的核心,由其使用Binder驱动进行IPC管理,关于IPC通讯 的机制,此处暂不详述。在APP和Framework中,应用程序使用的ServiceManager.Java就是通过Proxy与这个守护进程进行的 通讯。

2. 启动Zygote进程,Zygote的中文翻译是受精卵或孵化器,顾名思义,从它开始将会衍生出Android系统中的各种子进程。

[python] view plain copy
  1. service zygote /system/bin/app_process -Xzygote/system/bin --zygote --start-system-server  

第五阶段:Zygote进程加载SystemServer进程,并启动系统服务

如果在init.rc文件中找不到这一语句,我们可以关注下init.rc文件开头的几行import代码。

[python] view plain copy
  1. import/init.environ.rc  
  2. import /init.usb.rc  
  3. import /init.${ro.hardware}.rc  
  4. import /init.${ro.zygote}.rc  //在同一目录下,可以找到类似于init.zygote32.rc的文件  
  5.                               //不同名字的zygote进程启动文件对应于不同位数的设备  
  6. import /init.trace.rc  

随便打开一个init.zygote32.rc文件,即可找到此语句

在这个步骤中,将启动zygote服务进程。Zygote进程将成为所有应用进程的孵化器。

我们来看一下app_process的代码,位置是在:

frameworks/base/cmds/app_process/app_main.cpp

C++文件的执行入口总在main()函数当中——其入口函数main在文件app_main.cpp中,接下来我们就从这个main函数入手来分析zygote的内部逻辑。

/*启动zygote的方式为service zygote /system/bin/app_process-Xzygote /system/bin --zygote --start-system-server

* 所以 argc == 5, argv中存的就是这5个参数argv[0]=="/system/bin/app_process" ,argv[1]== "-Xzygote"....

*/

[cpp] view plain copy
  1. int main(int argc, charconst argv[])  
  2. {  
  3.     if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {  
  4.         // Older kernels don't understand PR_SET_NO_NEW_PRIVS and return  
  5.         // EINVAL. Don't die on such kernels.  
  6.         if (errno != EINVAL) {  
  7.             LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno));  
  8.             return 12;  
  9.         }  
  10.     }  
  11.   
  12.     AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));  
  13.     // Process command line arguments  
  14.     // ignore argv[0]  
  15.     argc--;  
  16.     argv++;  
  17.   
  18.     // Everything up to '--' or first non '-' arg goes to the vm.  
  19.     //  
  20.     // The first argument after the VM args is the "parent dir", which  
  21.     // is currently unused.  
  22.     //  
  23.     // After the parent dir, we expect one or more the following internal  
  24.     // arguments :  
  25.     //  
  26.     // --zygote : Start in zygote mode  
  27.     // --start-system-server : Start the system server.  
  28.     // --application : Start in application (stand alone, non zygote) mode.  
  29.     // --nice-name : The nice name for this process.  
  30.     //  
  31.     // For non zygote starts, these arguments will be followed by  
  32.     // the main class name. All remaining arguments are passed to  
  33.     // the main method of this class.  
  34.     //  
  35.     // For zygote starts, all remaining arguments are passed to the zygote.  
  36.     // main function.  
  37.     //  
  38.     // Note that we must copy argument string values since we will rewrite the  
  39.     // entire argument block when we apply the nice name to argv0.  
  40.   
  41.     int i;  
  42.     for (i = 0; i < argc; i++) {  
  43.         if (argv[i][0] != '-') {  
  44.             break;  
  45.         }  
  46.         if (argv[i][1] == '-' && argv[i][2] == 0) {  
  47.             ++i; // Skip --.  
  48.             break;  
  49.         }  
  50.         runtime.addOption(strdup(argv[i]));  
  51.     }  
  52.   
  53.     // Parse runtime arguments.  Stop at first unrecognized option.  
  54.     bool zygote = false;  
  55.     bool startSystemServer = false;  
  56.     bool application = false;  
  57.     String8 niceName;  
  58.     String8 className;  
  59.   
  60.     ++i;  // Skip unused "parent dir" argument.  
  61.     while (i < argc) {  
  62.         const char* arg = argv[i++];  
  63.         if (strcmp(arg, "--zygote") == 0) { //将会走这个分支  
  64.             zygote = true;  
  65.             niceName = ZYGOTE_NICE_NAME;  
  66.         } else if (strcmp(arg, "--start-system-server") == 0) { //将会走这个分支  
  67.             startSystemServer = true;  
  68.         } else if (strcmp(arg, "--application") == 0) {  
  69.             application = true;  
  70.         } else if (strncmp(arg, "--nice-name=", 12) == 0) {  
  71.             niceName.setTo(arg + 12);  
  72.         } else if (strncmp(arg, "--", 2) != 0) { //启动zygote中的参数都不会走到这个分支,仔细思考下就知道是因为所有带"--"的参数都会先被前面的if判断分支截获  
  73.             className.setTo(arg);  
  74.             break;  
  75.         } else {  
  76.             --i;  
  77.             break;  
  78.         }  
  79.     }  
  80.   
  81.     //经历了上面的while循环后,总结下变量的赋值和变化情况:  
  82.     //boolean zygote 变为true  
  83.     //boolean startSystemServer变为true  
  84.     //boolean application依然为false  
  85.     //字符串变量niceName和className为Null   
  86.     //在这个基础上分析下面的流程就很容易了  
  87.     Vector<String8> args;  //重点关注下这个变量,它将作为接下来调用runtime.start()方法的传入参数  
  88.     if (!className.isEmpty()) {  
  89.         // We're not in zygote mode, the only argument we need to pass  
  90.         // to RuntimeInit is the application argument.  
  91.         //  
  92.         // The Remainder of args get passed to startup class main(). Make  
  93.         // copies of them before we overwrite them with the process name.  
  94.         args.add(application ? String8("application") : String8("tool"));  
  95.         runtime.setClassNameAndArgs(className, argc - i, argv + i);  
  96.     } else {  
  97.         // We're in zygote mode.  
  98.         maybeCreateDalvikCache();  
  99.   
  100.         if (startSystemServer) {  
  101.             args.add(String8("start-system-server")); //args中添加的第一个变量  
  102.         }  
  103.   
  104.         char prop[PROP_VALUE_MAX];  
  105.         if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {  
  106.             LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",  
  107.                 ABI_LIST_PROPERTY);  
  108.             return 11;  
  109.         }  
  110.   
  111.         String8 abiFlag("--abi-list=");  
  112.         abiFlag.append(prop);  
  113.         args.add(abiFlag); //args中添加的第二个变量  
  114.   
  115.         // In zygote mode, pass all remaining arguments to the zygote  
  116.         // main() method.  
  117.         for (; i < argc; ++i) {  
  118.             args.add(String8(argv[i]));  
  119.         }  
  120.     }  
  121.   
  122.     if (!niceName.isEmpty()) {  
  123.         runtime.setArgv0(niceName.string());  
  124.         set_process_name(niceName.string());  
  125.     }  
  126.   
  127.     if (zygote) {   
  128.         runtime.start("com.android.internal.os.ZygoteInit", args); //zygote为true  
  129.     } else if (className) {  
  130.         runtime.start("com.android.internal.os.RuntimeInit", args);  
  131.     } else {  
  132.         fprintf(stderr, "Error: no class name or --zygote supplied.\n");  
  133.         app_usage();  
  134.         LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");  
  135.         return 10;  
  136.     }  
  137. }  


在执行到app_process/app_main.cpp这个文件的最后,将会调用runtime.start("com.android.internal.os.ZygoteInit",args); 这个语句runtime是一个AppRuntime变量,其定义同样在/frameworks/base/cmds/app_process/app_main.cpp这个文件当中。  
[cpp] view plain copy
  1. class AppRuntime : public AndroidRuntime   
  2.    
  3.   
  4.        ......   
  5.   
  6. ;    

可以发现其继承于AndroidRuntime类。AndroidRuntime类定义在frameworks/base/core/jni/AndroidRuntime.cpp文件中。

runtime.start方法调用的正是其父类AndroidRuntime.cpp中的start方法。

 AndroidRuntime.start()方法代码如下:

[cpp] view plain copy
  1. /* 
  2.  * Start the Android runtime.  This involves starting the virtual machine 
  3.  * and calling the "static void main(String[] args)" method in the class 
  4.  * named by "className". 
  5.  * 
  6.  * Passes the main function two arguments, the class name and the specified 
  7.  * options string. 
  8.  */  
  9. void AndroidRuntime::start(const char* className, const Vector<String8>& options)  
  10. {  
  11.     ALOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n",  
  12.             className != NULL ? className : "(unknown)");  
  13.   
  14.     static const String8 startSystemServer("start-system-server");  
  15.   
  16.     /* 
  17.      * 'startSystemServer == true' means runtime is obsolete and not run from 
  18.      * init.rc anymore, so we print out the boot start event here. 
  19.      */  
  20.     for (size_t i = 0; i < options.size(); ++i) {  
  21.         if (options[i] == startSystemServer) {  
  22.            /* track our progress through the boot sequence */  
  23.            const int LOG_BOOT_PROGRESS_START = 3000;  
  24.            LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,  ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));  
  25.         }  
  26.     }  
  27.   
  28.     const char* rootDir = getenv("ANDROID_ROOT");  
  29.     if (rootDir == NULL) {  
  30.         rootDir = "/system";  
  31.         if (!hasDir("/system")) {  
  32.             LOG_FATAL("No root directory specified, and /android does not exist.");  
  33.             return;  
  34.         }  
  35.         setenv("ANDROID_ROOT", rootDir, 1);  
  36.     }  
  37.   
  38.     //const char* kernelHack = getenv("LD_ASSUME_KERNEL");  
  39.     //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);  
  40.   
  41.     /* start the virtual machine */  
  42.     JniInvocation jni_invocation;  
  43.     jni_invocation.Init(NULL);  
  44.     JNIEnv* env;  
  45.     if (startVm(&mJavaVM, &env) != 0) {   //关键步骤1,开启虚拟机  
  46.         return;  
  47.     }  
  48.     onVmCreated(env);  
  49.   
  50.     /* 
  51.      * Register android functions. //关键步骤2,注册JNI方法 
  52.      */  
  53.     if (startReg(env) < 0) {  
  54.         ALOGE("Unable to register all android natives\n");  
  55.         return;  
  56.     }  
  57.   
  58.     /* 
  59.      * We want to call main() with a String array with arguments in it. 
  60.      * At present we have two arguments, the class name and an option string. 
  61.      * Create an array to hold them. 
  62.      */  
  63.     jclass stringClass;  
  64.     jobjectArray strArray;  
  65.     jstring classNameStr;  
  66.   
  67.     stringClass = env->FindClass("java/lang/String");  
  68.     assert(stringClass != NULL);  
  69.     strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);  
  70.     assert(strArray != NULL);  
  71.     classNameStr = env->NewStringUTF(className);  
  72.     assert(classNameStr != NULL);  
  73.     env->SetObjectArrayElement(strArray, 0, classNameStr);  
  74.   
  75.     for (size_t i = 0; i < options.size(); ++i) {  
  76.         jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());  
  77.         assert(optionsStr != NULL);  
  78.         env->SetObjectArrayElement(strArray, i + 1, optionsStr);  
  79.     }  
  80.   
  81.     /* 
  82.      * Start VM.  This thread becomes the main thread of the VM, and will 
  83.      * not return until the VM exits. //关键步骤3 
  84.      */  
  85.     char* slashClassName = toSlashClassName(className);  
  86.     jclass startClass = env->FindClass(slashClassName);  
  87.     if (startClass == NULL) {  
  88.         ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);  
  89.         /* keep going */  
  90.     } else {  
  91.         jmethodID startMeth = env->GetStaticMethodID(startClass, "main",  
  92.             "([Ljava/lang/String;)V");  
  93.         if (startMeth == NULL) {  
  94.             ALOGE("JavaVM unable to find main() in '%s'\n", className);  
  95.             /* keep going */  
  96.         } else {  
  97.             env->CallStaticVoidMethod(startClass, startMeth, strArray); //调用其main方法  
  98.   
  99. #if 0  
  100.             if (env->ExceptionCheck())  
  101.                 threadExitUncaughtException(env);  
  102. #endif  
  103.         }  
  104.     }  
  105.     free(slashClassName);  
  106.   
  107.     ALOGD("Shutting down VM\n");  
  108.     if (mJavaVM->DetachCurrentThread() != JNI_OK)  
  109.         ALOGW("Warning: unable to detach main thread\n");  
  110.     if (mJavaVM->DestroyJavaVM() != 0)  
  111.         ALOGW("Warning: VM did not shut down cleanly\n");  
  112. }  
这个方法,除去一些系统启动过程中的出错处理和相关信息排查操作,总体逻辑还是比较清晰的。关注几个关键的步骤可以知道,这个方法完成了三个最重要的责任:

关键步骤1——调用函数startVM,启动虚拟机

关键步骤2——调用函数startReg注册JNI方法,以完成安卓上层和native层的交互

关键步骤3——找到className为” com.android.internal.os.ZygoteInit”的类,并调用其main方法


接着前行,步骤3中涉及到这个类定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中。找到其函数入口main方法:

[java] view plain copy
  1. public static void main(String argv[]) {  
  2.         try {  
  3.             // Start profiling the zygote initialization.  
  4.             SamplingProfilerIntegration.start();  
  5.   
  6.             boolean startSystemServer = false;  
  7.             String socketName = "zygote";  
  8.             String abiList = null;  
  9.             for (int i = 1; i < argv.length; i++) {  
  10.                 if ("start-system-server".equals(argv[i])) {  
  11.                     startSystemServer = true;  
  12.                 } else if (argv[i].startsWith(ABI_LIST_ARG)) {  
  13.                     abiList = argv[i].substring(ABI_LIST_ARG.length());  
  14.                 } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {  
  15.                     socketName = argv[i].substring(SOCKET_NAME_ARG.length());  
  16.                 } else {  
  17.                     throw new RuntimeException("Unknown command line argument: " + argv[i]);  
  18.                 }  
  19.             }  
  20.   
  21.             if (abiList == null) {  
  22.                 throw new RuntimeException("No ABI list supplied.");  
  23.             }  
  24.   
  25.             registerZygoteSocket(socketName); //关键步骤1,注册Zygote进程的套接字  
  26.             EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,  
  27.                 SystemClock.uptimeMillis());  
  28.             preload();  
  29.             EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,  
  30.                 SystemClock.uptimeMillis());  
  31.   
  32.             // Finish profiling the zygote initialization.  
  33.             SamplingProfilerIntegration.writeZygoteSnapshot();  
  34.   
  35.             // Do an initial gc to clean up after startup  
  36.             gc();  
  37.   
  38.             // Disable tracing so that forked processes do not inherit stale tracing tags from  
  39.             // Zygote.  
  40.             Trace.setTracingEnabled(false);  
  41.   
  42.             if (startSystemServer) {  
  43.                 startSystemServer(abiList, socketName);//关键步骤2,启动SystemServer  
  44.             }  
  45.   
  46.             Log.i(TAG, "Accepting command socket connections");  
  47.             runSelectLoop(abiList);//关键步骤3  
  48.   
  49.             closeServerSocket();  
  50.         } catch (MethodAndArgsCaller caller) {  
  51.             caller.run();  
  52.         } catch (RuntimeException ex) {  
  53.             Log.e(TAG, "Zygote died with exception", ex);  
  54.             closeServerSocket();  
  55.             throw ex;  
  56.         }  
  57.     }  

详细分析这四个关键步骤。

关键步骤1:——调用registerZygoteSocket函数创建了一个socket接口,用来和ActivityManagerService通讯

[java] view plain copy
  1. ZygoteInit.registerZygoteSocket():  
  2.    /** 
  3.      * Registers a server socket for zygote command connections 
  4.      * 
  5.      * @throws RuntimeException when open fails 
  6.      */  
  7.     private static void registerZygoteSocket(String socketName) {  
  8.         if (sServerSocket == null) {  
  9.             int fileDesc;  
  10.             final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName; //安卓规范套接字前缀+socket名字  
  11.             try {  
  12.                 String env = System.getenv(fullSocketName);  
  13.                 fileDesc = Integer.parseInt(env);  
  14.             } catch (RuntimeException ex) {  
  15.                 throw new RuntimeException(fullSocketName + " unset or invalid", ex);  
  16.             }  
  17.   
  18.             try {  
  19.                 sServerSocket = new LocalServerSocket(  
  20.                         createFileDescriptor(fileDesc));//创建一个文件描述符  
  21.             } catch (IOException ex) {  
  22.                 throw new RuntimeException(  
  23.                         "Error binding to local socket '" + fileDesc + "'", ex);  
  24.             }  
  25.         }  
  26.     }   

关键步骤2:——调用startSystemServer,启动SystemServer这个系统核心进程

startSystemServer方法位于同一文件ZygoteInit.java当中。

[java] view plain copy
  1. ZygoteInit.startSystemServer():  
  2.   
  3.     /** 
  4.      * Prepare the arguments and fork for the system server process. 
  5.      */  
  6.     private static boolean startSystemServer(String abiList, String socketName)  
  7.             throws MethodAndArgsCaller, RuntimeException {  
  8.         long capabilities = posixCapabilitiesAsBits(  
  9.             OsConstants.CAP_BLOCK_SUSPEND,  
  10.             OsConstants.CAP_KILL,  
  11.             OsConstants.CAP_NET_ADMIN,  
  12.             OsConstants.CAP_NET_BIND_SERVICE,  
  13.             OsConstants.CAP_NET_BROADCAST,  
  14.             OsConstants.CAP_NET_RAW,  
  15.             OsConstants.CAP_SYS_MODULE,  
  16.             OsConstants.CAP_SYS_NICE,  
  17.             OsConstants.CAP_SYS_RESOURCE,  
  18.             OsConstants.CAP_SYS_TIME,  
  19.             OsConstants.CAP_SYS_TTY_CONFIG  
  20.         );  
  21.         /* Hardcoded command line to start the system server */  
  22.         String args[] = {  
  23.             "--setuid=1000",  
  24.             "--setgid=1000",  
  25.             "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007",  
  26.             "--capabilities=" + capabilities + "," + capabilities,  
  27.             "--runtime-init",  
  28.             "--nice-name=system_server",  
  29.             "com.android.server.SystemServer",  
  30.         };  
  31.         ZygoteConnection.Arguments parsedArgs = null;  
  32.   
  33.         int pid;  
  34.   
  35.         try {  
  36.             parsedArgs = new ZygoteConnection.Arguments(args);  
  37.             ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);  
  38.             ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);  
  39.   
  40.             /* Request to fork the system server process */  
  41.             pid = Zygote.forkSystemServer( //与Android 4.4之前的版本不一样的地方  
  42.                     parsedArgs.uid, parsedArgs.gid,  
  43.                     parsedArgs.gids,  
  44.                     parsedArgs.debugFlags,  
  45.                     null,  
  46.                     parsedArgs.permittedCapabilities,  
  47.                     parsedArgs.effectiveCapabilities);  
  48.         } catch (IllegalArgumentException ex) {  
  49.             throw new RuntimeException(ex);  
  50.         }  
  51.   
  52.         /* For child process */  
  53.         if (pid == 0) {  
  54.             if (hasSecondZygote(abiList)) {  
  55.                 waitForSecondaryZygote(socketName);  
  56.             }  
  57.   
  58.             handleSystemServerProcess(parsedArgs);  
  59.         }  
  60.   
  61.         return true;  
  62.     }  

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

[java] view plain copy
  1. ZygoteInit.handleSystemServerProcess():  
  2.     /** 
  3.      * Finish remaining work for the newly forked system server process. 
  4.      */  
  5.     private static void handleSystemServerProcess(  
  6.             ZygoteConnection.Arguments parsedArgs)  
  7.             throws ZygoteInit.MethodAndArgsCaller {  
  8.   
  9.         closeServerSocket();  
  10.   
  11.         // set umask to 0077 so new files and directories will default to owner-only permissions.  
  12.         Os.umask(S_IRWXG | S_IRWXO);  
  13.   
  14.         if (parsedArgs.niceName != null) {  
  15.             Process.setArgV0(parsedArgs.niceName);  
  16.         }  
  17.   
  18.         final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");  
  19.         if (systemServerClasspath != null) {  
  20.             performSystemServerDexOpt(systemServerClasspath);  
  21.         }  
  22.   
  23.         if (parsedArgs.invokeWith != null) {  
  24.             String[] args = parsedArgs.remainingArgs;  
  25.             // If we have a non-null system server class path, we'll have to duplicate the  
  26.             // existing arguments and append the classpath to it. ART will handle the classpath  
  27.             // correctly when we exec a new process.  
  28.             if (systemServerClasspath != null) {  
  29.                 String[] amendedArgs = new String[args.length + 2];  
  30.                 amendedArgs[0] = "-cp";  
  31.                 amendedArgs[1] = systemServerClasspath;  
  32.                 System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);  
  33.             }  
  34.   
  35.             WrapperInit.execApplication(parsedArgs.invokeWith,  
  36.                     parsedArgs.niceName, parsedArgs.targetSdkVersion,  
  37.                     null, args);  
  38.         } else {  
  39.             ClassLoader cl = null;  
  40.             if (systemServerClasspath != null) {  
  41.                 cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());  
  42.                 Thread.currentThread().setContextClassLoader(cl);  
  43.             }  
  44.   
  45.             /* 
  46.              * Pass the remaining arguments to SystemServer. 
  47.              */  
  48.             RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);  
  49.         }  
  50.   
  51.         /* should never reach here */  
  52.     }  

这个函数接着调用RuntimeInit.zygoteInit函数来进一步执行启动SystemServer组件的操作。

[java] view plain copy
  1. RuntimeInit.zygoteInit函数定义在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中。  
  2.   
  3.     public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)  
  4.             throws ZygoteInit.MethodAndArgsCaller {  
  5.         if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");  
  6.   
  7.         redirectLogStreams();  
  8.   
  9.         commonInit();  
  10.         nativeZygoteInit(); //调用了JNI层的方法,为Binder通信机制的建立奠定了基础,此处暂不深入讨论  
  11.   
  12.         applicationInit(targetSdkVersion, argv, classLoader);  
  13.     }  

继续查看RuntimeInit.applicationInit()方法
[java] view plain copy
  1.     private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)  
  2.             throws ZygoteInit.MethodAndArgsCaller {  
  3.         // If the application calls System.exit(), terminate the process  
  4.         // immediately without running any shutdown hooks.  It is not possible to  
  5.         // shutdown an Android application gracefully.  Among other things, the  
  6.         // Android runtime shutdown hooks close the Binder driver, which can cause  
  7.         // leftover running threads to crash before the process actually exits.  
  8.         nativeSetExitWithoutCleanup(true);  
  9.   
  10.         // We want to be fairly aggressive about heap utilization, to avoid  
  11.         // holding on to a lot of memory that isn't needed.  
  12.         VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);  
  13.         VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);  
  14.   
  15.         final Arguments args;  
  16.         try {  
  17.             args = new Arguments(argv);  
  18.         } catch (IllegalArgumentException ex) {  
  19.             Slog.e(TAG, ex.getMessage());  
  20.             // let the process exit  
  21.             return;  
  22.         }  
  23.           
  24.         // Remaining arguments are passed to the start class's static main  
  25.         /* 
  26.         *从ZygoteInit.startSystemServer()方法中传过来的parsedArgs参数包括  
  27.         *"--nice-name=system_server", "com.android.server.SystemServer" 
  28.         *实际上它们就是互相对应的硬编码,调用SystemServer的main方法 
  29.         */  
  30.         invokeStaticMain(args.startClass, args.startArgs, classLoader);  
  31.     }  
  32.     }  

不要放弃,继续往下看,到这里我们将调用RuntimeInit.java中的invokeStaticMain方法: 

[java] view plain copy
  1.    /** 
  2.      * Invokes a static "main(argv[]) method on class "className". 
  3.      * Converts various failing exceptions into RuntimeExceptions, with 
  4.      * the assumption that they will then cause the VM instance to exit. 
  5.      * 
  6.      * @param className Fully-qualified class name 
  7.      * @param argv Argument vector for main() 
  8.      * @param classLoader the classLoader to load {@className} with 
  9.      */  
  10.     private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)  
  11.             throws ZygoteInit.MethodAndArgsCaller {  
  12.         Class<?> cl;  
  13.   
  14.         try {            
  15.             cl = Class.forName(className, true, classLoader);//加载com.android.server.SystemServer这个类  
  16.         } catch (ClassNotFoundException ex) {  
  17.             throw new RuntimeException(  
  18.                     "Missing class when invoking static main " + className,  
  19.                     ex);  
  20.         }  
  21.   
  22.         Method m;  
  23.         try {  
  24.             m = cl.getMethod("main"new Class[] { String[].class });//获取main方法  
  25.         } catch (NoSuchMethodException ex) {  
  26.             throw new RuntimeException(  
  27.                     "Missing static main on " + className, ex);  
  28.         } catch (SecurityException ex) {  
  29.             throw new RuntimeException(  
  30.                     "Problem getting static main on " + className, ex);  
  31.         }  
  32.   
  33.         int modifiers = m.getModifiers();  
  34.         if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {  
  35.             throw new RuntimeException(  
  36.                     "Main method is not public and static on " + className);  
  37.         }  
  38.   
  39.         /* 
  40.          * This throw gets caught in ZygoteInit.main(), which responds 
  41.          * by invoking the exception's run() method. This arrangement 
  42.          * clears up all the stack frames that were required in setting 
  43.          * up the process. 
  44.          */  
  45.         throw new ZygoteInit.MethodAndArgsCaller(m, argv);  
  46.     }  

我们出奇的发现RuntimeInit.invokeStaticMain方法并没有直接调用SystemServer的main的方法,那么它是怎么被调用的?答案在这个函数的末尾——抛出了一个MethodAndArgsCaller异常。源码中注释非常清楚地说明了,这个异常将在main方法中被截获。

[java] view plain copy
  1. public static void main(String argv[]) {  
  2.         try {  
  3.          ........ //省略掉中间的内容  
  4.         } catch (MethodAndArgsCaller caller) {//就是在这里截获的!  
  5.             caller.run();  
  6.         } catch(RuntimeException ex) {  
  7.             Log.e(TAG, "Zygote died withexception", ex);  
  8.             closeServerSocket();  
  9.             throw ex;  
  10.         }  
  11. }  

目光转移到MethodAndArgsCaller的run()方法。该方法定义在/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java方法中。

 

[java] view plain copy
  1.  public static class MethodAndArgsCaller extends Exception  
  2.             implements Runnable {  
  3.         /** method to call */  
  4.         private final Method mMethod;  
  5.   
  6.         /** argument array */  
  7.         private final String[] mArgs;  
  8.   
  9.         public MethodAndArgsCaller(Method method, String[] args) {  
  10.             //将方法参数,和调用方法的类传递下来  
  11.             mMethod = method;  
  12.             mArgs = args;  
  13.         }  
  14.   
  15.         public void run() {  
  16.             try {  
  17.                 //在线程的run()方法中开始正式调用main方法  
  18.                 mMethod.invoke(nullnew Object[] { mArgs });  
  19.             } catch (IllegalAccessException ex) {  
  20.                 throw new RuntimeException(ex);  
  21.             } catch (InvocationTargetException ex) {  
  22.                 Throwable cause = ex.getCause();  
  23.                 if (cause instanceof RuntimeException) {  
  24.                     throw (RuntimeException) cause;  
  25.                 } else if (cause instanceof Error) {  
  26.                     throw (Error) cause;  
  27.                 }  
  28.                 throw new RuntimeException(ex);  
  29.             }  
  30.         }  
  31.     }  

至此,终于正式调用SystemServer的main方法了。

Android5.0.0以上版本的SystemServer.java文件位于

/frameworks/base/services/java/com/android/server/中

[java] view plain copy
  1. public static void main(String[] args) {  
  2.     new SystemServer().run();  
  3. }  
main方法中只有仅仅一句代码。调用了SystemServer的构造函数,并让他以“线程的方式”跑起来。

[java] view plain copy
  1. public SystemServer() {  
  2.     // Checkfor factory test mode.  
  3.    mFactoryTestMode = FactoryTest.getMode();  
  4. }  

 

[java] view plain copy
  1. private void run() {  
  2.     // If a device's clock is before 1970 (before 0), a lot of  
  3.     // APIs crash dealing with negative numbers, notably  
  4.     // java.io.File#setLastModified, so instead we fake it and  
  5.     // hope that time from cell towers or NTP fixes it shortly.  
  6.     if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {  
  7.         Slog.w(TAG, "System clock is before 1970; setting to 1970.");  
  8.         SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);  
  9.     }  
  10.   
  11.     // Here we go!  
  12.     Slog.i(TAG, "Entered the Android system server!");  
  13.     EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());  
  14.   
  15.     // In case the runtime switched since last boot (such as when  
  16.     // the old runtime was removed in an OTA), set the system  
  17.     // property so that it is in sync. We can't do this in  
  18.     // libnativehelper's JniInvocation::Init code where we already  
  19.     // had to fallback to a different runtime because it is  
  20.     // running as root and we need to be the system user to set  
  21.     // the property. http://b/11463182  
  22.     SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());  
  23.   
  24.     // Enable the sampling profiler.  
  25.     if (SamplingProfilerIntegration.isEnabled()) {  
  26.         SamplingProfilerIntegration.start();  
  27.         mProfilerSnapshotTimer = new Timer();  
  28.         mProfilerSnapshotTimer.schedule(new TimerTask() {  
  29.             @Override  
  30.             public void run() {  
  31.                 SamplingProfilerIntegration.writeSnapshot("system_server"null);  
  32.             }  
  33.         }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);  
  34.     }  
  35.   
  36.     // Mmmmmm... more memory!  
  37.     VMRuntime.getRuntime().clearGrowthLimit();  
  38.   
  39.     // The system server has to run all of the time, so it needs to be  
  40.     // as efficient as possible with its memory usage.  
  41.     VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);  
  42.   
  43.     // Some devices rely on runtime fingerprint generation, so make sure  
  44.     // we've defined it before booting further.  
  45.     Build.ensureFingerprintProperty();  
  46.   
  47.     // Within the system server, it is an error to access Environment paths without  
  48.     // explicitly specifying a user.  
  49.     Environment.setUserRequired(true);  
  50.   
  51.     // Ensure binder calls into the system always run at foreground priority.  
  52.     BinderInternal.disableBackgroundScheduling(true);  
  53.   
  54.     // Prepare the main looper thread (this thread).  
  55.     android.os.Process.setThreadPriority(  
  56.             android.os.Process.THREAD_PRIORITY_FOREGROUND);  
  57.     android.os.Process.setCanSelfBackground(false);  
  58.     Looper.prepareMainLooper();  
  59.   
  60.     // Initialize native services.  
  61.     //关键步骤1  
  62.     System.loadLibrary("android_servers");  
  63.     nativeInit();  
  64.   
  65.     // Check whether we failed to shut down last time we tried.  
  66.     // This call may not return.  
  67.     performPendingShutdown();  
  68.   
  69.     // Initialize the system context.  
  70.     createSystemContext();  
  71.   
  72.     //关键步骤2  
  73.     // Create the system service manager.  
  74.     mSystemServiceManager = new SystemServiceManager(mSystemContext);  
  75.     LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);  
  76.   
  77.     //关键步骤3  
  78.     // Start services.  
  79.     try {  
  80.         startBootstrapServices();  
  81.         startCoreServices();  
  82.         startOtherServices();  
  83.     } catch (Throwable ex) {  
  84.         Slog.e("System""******************************************");  
  85.         Slog.e("System""************ Failure starting system services", ex);  
  86.         throw ex;  
  87.     }  
  88.   
  89.     // For debug builds, log event loop stalls to dropbox for analysis.  
  90.     if (StrictMode.conditionallyEnableDebugLogging()) {  
  91.         Slog.i(TAG, "Enabled StrictMode for system server main thread.");  
  92.     }  
  93.   
  94.     // Loop forever.  
  95.     Looper.loop();  
  96.     throw new RuntimeException("Main thread loop unexpectedly exited");  
  97. }  

 

SystemServer.run()方法中最值得关注的就是我注释中标注的三个关键步骤,下面稍作解释:

关键步骤1——初始化native层的系统服务。从nativeInit名字就可以看出来这是一个native层的代码,调用了jni层的代码。这个方法的实际实现在:frameworks/base/services/core/jni/com_android_server_SystemServer.cpp。相关代码如下:

[cpp] view plain copy
  1. </pre><pre name="code" class="cpp">static void android_server_SystemServer_nativeInit(JNIEnv* env, jobject clazz) {  
  2.     char propBuf[PROPERTY_VALUE_MAX];  
  3.     property_get("system_init.startsensorservice", propBuf, "1");  
  4.     if (strcmp(propBuf, "1") == 0) {  
  5.         // Start the sensor service  
  6.         SensorService::instantiate();  
  7.     }  
  8. }  

大概就是根据属性配置文件来确定是否需要初始化SensorService,这里就不多介绍了。

关键步骤2——将SystemManagerService注册到SystemServer(自身)中。

关键步骤3——启动系统运行所需的服务。其中:

startBootstrapServices()方法启动ActivityManagerService(AMS),PowerManagerService,PackageManagerServices(),DisplayManagerService等系统关键服务。

startCoreServices()方法调用了一些核心服务,例如LightService,BatteryService等。

startOtherServices()方法则调用剩余的一些服务。出人意料的是,WindowMangaerService竟然是在这里启动。除此之外,还有InputManagerService和AlarmManagerService都在这里启动。

完成了这三个关键步骤后,最后会通过Looper.loop()来进行消息循环,然后处理消息。

此前安卓版本与5.0之后版本SystemServer的启动方式有很大区别:

此前的SystemServer会通过  ServerThread thr = new ServerThread();直接建立一个ServerThread进程。 

 

到这里,系统的关键服务都启动完毕,安卓系统的启动过程也接近尾声。

这里执行完成后,层层返回,最后回到上面的ZygoteInit.main函数中,接下来它就要调用runSelectLoop函数进入一个无限循环在前面ZygoteInit.main函数关键步骤1中创建的socket接口上等待ActivityManagerService请求创建新的应用程序进程了。runSelectLoop()函数实际上是在一死循环中利用zygoteConnection类通过socket的方式进行消息 处理,用于fork出新的zygote,从而以最轻量级的方式实现每个进程一个虚拟机的机制。

 

最后我们再简单梳理下Android启动的过程。毕竟这么复杂的过程需要不断回顾。后续可能会补充上更多流程图,以帮助自己和大家进行梳理。


 

1. Linux内核启动完毕后,系统开始init.rc配置文件启动Zygote进程。

2. Zygote进程的启动经历了ZygoteInit,RuntimeInit,fork出SystemServer这个进程。

3. SystemServer进程负责启动,初始化系统的关键服务,如包管理服务PackageManagerService和应用程序组件管理服务ActivityManagerService。除了注册到ServiceManager中,还将调用各服务的systemReady()告诉它们系统已经正常启动

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


文末感谢下为我提供过帮助的博客大牛和文章,传送门:

1.《Android启动过程深入解析》我所归纳的安卓启动分为几个阶段由此文借鉴。

2.《Android系统进程Zygote启动过程的源代码分析》 安卓名人老罗的传世名作。

3. 《Android情景分析之深入解析system_server》为我解决了不少疑惑。



0 0