在前一篇文章"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\n",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.c18 19 LOCAL_MODULE:= init20 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_runtime12 13 LOCAL_MODULE:= app_process14 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 arguments17     // ignore argv[0]18     argc--;19     argv++;20 21     // Everything up to '--' or first non '-' arg goes to the vm22 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为true39             zygote = true;40             niceName = "zygote";41         } else if (strcmp(arg, "--start-system-server") == 0) {42             // 设置startSystemServer为true43             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.\n");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()的源码如下:

Android之 系统启动流程
  1 void AndroidRuntime::start(const char* className, const char* options)  2 {  3     ALOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n",  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'\n", 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\n"); 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'\n", 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'\n", 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\n"); 98     if (mJavaVM->DetachCurrentThread() != JNI_OK) 99         ALOGW("Warning: unable to detach main thread\n");100     if (mJavaVM->DestroyJavaVM() != 0)101         ALOGW("Warning: VM did not shut down cleanly\n");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()源码如下:

Android之 系统启动流程
 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 startup17         gc();18 19         // If requested, start system server directly from Zygote20         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中,源码如下:

Android之 系统启动流程
 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()启动SystemServer11     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 exit14         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             // 通过反射,执行方法mMethod15             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了!

更多相关文章

  1. android studio 程序员有福了—从layout自动生成viewholder类
  2. Android自定义属性与自定义属性的获取
  3. 【Android】源码分析 - Handler消息机制再梳理
  4. Android中AsyncTask详解,源码剖析(API 23)
  5. [转]Android 应用程序基础(Application Fundamentals)
  6. Android下添加新的自定义键值和按键处理流程
  7. Android 5.1.1 源码目录结构
  8. Android中自定义控件

随机推荐

  1. Android(java)回调函数经典示例
  2. Android(安卓)无法解决第三方库依赖问题
  3. android实现双击事件暨多击事件详解
  4. Android(安卓)图片缩放引起的OOM异常全篇
  5. linux下 在Android工程中查看framework j
  6. 【Android】将Xamarin For VS升级为4.0.1
  7. apk之间资源共享
  8. android 实现图片选择拖拽控件
  9. Android(安卓)4.4 Kit Kat 源码下载
  10. Android(安卓)NestedScrollView嵌套Recyc