在前一篇文章"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()的源码如下:

  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()源码如下:

 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中,源码如下:

 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. Andriod开发必备资料
  2. Android中的Context对象
  3. Android之Intents 和Intent Filters
  4. Android(安卓)根文件系统启动分析
  5. Android(安卓)闹钟源码
  6. Android(安卓)Tablayout 的使用
  7. android Html Package机制说明
  8. Android进阶知识树——Android系统的启动过程
  9. 花了 6 个月整理了 100 篇 Android(安卓)干货文章

随机推荐

  1. 2013.11.04(3)——— android 创建公共库以
  2. Android多媒体框架初步分析
  3. android 带箭头的textview文字伸缩效果
  4. Android layer type与WebView白屏
  5. android设置屏幕禁止休眠的方法
  6. 大家网Android开发规范
  7. android动画Android 动画实践
  8. android 部分网址 https连接不上(Not tru
  9. Bluetooth in Android 4.2 and 4.3(三):Enab
  10. 基于命令行模式开发ANDROID应用