> 文档中心 > Android system_server进程的初始化过程(包含jvm的初始化)

Android system_server进程的初始化过程(包含jvm的初始化)

在Android系统中,如果用ps来查看进程列表的话,会发现有一个进程是zygote,它的父进程是init,而且,它是所有应用的父进程;还有一个进程是system_server,它的父进程是zygote

事实上, zygote正是我们所说的JVM。system_server进程又该如何理解呢?其实,它是整个Android Framework所在的进程。这样,我们所说的android系统最核心的组成部分就呈现给大家了(当然,这里先将kernel和应用除外),即jvm+framework。本文描述了整个jvm 和 system_server的初始化过程,这篇文章是在本博另外一篇文章"android初始化流程”的基础上继续探讨的。

 一.   zygote进程是通过app_process的方式启动的,而且是在init.rc中指定的,具体如下:
 service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server 

app_process是一个用可执行程序,代码位于: frameworks\base\cmds\app_process\目录下。

二.   system_server既然是zygote的子进程,理所当然,是由zygote来初始化的。

1. 通过app_process启动zygote
   (1)app_main.cpp中的main函数: 
   int main(int argc, const char* const argv[])
{
    // These are global variables in ProcessState.cpp
    mArgC = argc;
    mArgV = argv;
    
    mArgLen = 0;
    for (int i=0; i<argc; i++) {
        mArgLen += strlen(argv[i]) + 1;
    }
    mArgLen--;

    AppRuntime runtime;
    const char *arg;
    const char *argv0;

    argv0 = argv[0];

    // Process command line arguments
    // ignore argv[0]
    argc--;
    argv++;

    // Everything up to '--' or first non '-' arg goes to the vm
    
    int i = runtime.addVmArguments(argc, argv);

    // Next arg is parent directory
    if (i < argc) {
        runtime.mParentDir = argv[i++];
    }

    // Next arg is startup classname or "--zygote"
    if (i < argc) {
        arg = argv[i++];
        if (0 == strcmp("--zygote", arg)) {
            bool startSystemServer = (i < argc) ? 
                    strcmp(argv[i], "--start-system-server") == 0 : false;
            setArgv0(argv0, "zygote");
            set_process_name("zygote");
            runtime.start("com.android.internal.os.ZygoteInit",
                startSystemServer);

        } else {
            set_process_name(argv0);

            runtime.mClassName = arg;

            // Remainder of args get passed to startup class main()
            runtime.mArgC = argc-i;
            runtime.mArgV = argv+i;

            LOGV("App process is starting with pid=%d, class=%s.\n",
                 getpid(), runtime.getClassName());
            runtime.start();
        }
    } else {
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        return 10;
    }
}
 
(2)AndroidRuntime.cpp中的start(位于frameworks\base\core\jni\AndroidRuntime.cpp):
void AndroidRuntime::start(const char* className, const bool startSystemServer)
{
    LOGD("\n>>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<\n");
    ......

    preloadClasses();
    //cacheRegisterMaps();
    preloadResources();


    ......
    /*
     * Initialize the VM.
     *
     * The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.
     * If this call succeeds, the VM is ready, and we can start issuing
     * JNI calls.
     */
    if (JNI_CreateJavaVM(&mJavaVM, &env, &initArgs) < 0) {
        LOGE("JNI_CreateJavaVM failed\n");
        goto bail;
    }
    /*
     * We want to call main() with a String array with arguments in it.
     * At present we only have one argument, the class name.  Create an
     * array to hold it.
     */
    jclass stringClass;
    jobjectArray strArray;
    jstring classNameStr;
    jstring startSystemServerStr;

    stringClass = env->FindClass("java/lang/String");
    assert(stringClass != NULL);
    strArray = env->NewObjectArray(2, stringClass, NULL);
    assert(strArray != NULL);
    classNameStr = env->NewStringUTF(className);
    assert(classNameStr != NULL);
    env->SetObjectArrayElement(strArray, 0, classNameStr);
    startSystemServerStr = env->NewStringUTF(startSystemServer ? 
                                                 "true" : "false");
    env->SetObjectArrayElement(strArray, 1, startSystemServerStr);

    /*
     * Start VM.  This thread becomes the main thread of the VM, and will
     * not return until the VM exits.
     */
    jclass startClass;
    jmethodID startMeth;

    slashClassName = strdup(className);
    for (cp = slashClassName; *cp != '\0'; cp++)
        if (*cp == '.')
            *cp = '/';

    startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
        startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            LOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
            env->CallStaticVoidMethod(startClass, startMeth, strArray);

#if 0
            if (env->ExceptionCheck())
                threadExitUncaughtException(env);
#endif
        }
    }

    LOGD("Shutting down VM\n");
    if (mJavaVM->DetachCurrentThread() != JNI_OK)
        LOGW("Warning: unable to detach main thread\n");
    if (mJavaVM->DestroyJavaVM() != 0)
        LOGW("Warning: VM did not shut down cleanly\n");

bail:
    free(slashClassName);
    free(stackTraceFile);

    
说明:
(1) LOGD("\n>>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<\n");
      这个log信息应该不陌生了吧。 

(2) preloadClasses();  和preloadResources();, 顾名思义,它加载了许多class和resources,libmedia_jni.so 和libwebcore就是在这里加载的(在本文最后面,会给出相关的log信息,里面显示了加载了哪些库,一定要看喔:))。

 (3) JNI_CreateJavaVM, 用于初始化虚拟机。

(4)  GetStaticMethodID和 CallStaticVoidMethod就会调用 传入的class的对应的方法。
       这里,class是ZygoteInit,方法是main, 而ZygoteInit位于ZygoteInit.java中,注意,从这里开始,
       首次以java定义的类来调用,因为在这之前,jvm也初始化好了,需要jniEnv的参数也设置好了。
       于是,就会执行到下面的ZygoteInit.java的main函数中。 
2.  ZygoteInit.java   
 代码:
     位于frameworks\base\core\java\com\android\internal\os目录下。
  在它的main函数中,最主要的就是:
  startSystemServer(); 这个函数也位于ZygoteInit.java中,代码如下:
   /**
     * Prepare the arguments and fork for the system server process.
     */
    private static boolean startSystemServer() 
            throws MethodAndArgsCaller, RuntimeException {
        /* Hardcoded command line to start the system server */
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003",
            "--capabilities=121715744,121715744",
            "--runtime-init",
            "--nice-name=system_server",
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
            parsedArgs = new ZygoteConnection.Arguments(args);

            /*
             * Enable debugging of the system process if *either* the command line flags
             * indicate it should be debuggable or the ro.debuggable system property
             * is set to "1"
             */
            int debugFlags = parsedArgs.debugFlags;
            if ("1".equals(SystemProperties.get("ro.debuggable")))
                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;

            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids, debugFlags, null);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        } 
 
        /* For child process */
        if (pid == 0) {
            handleSystemServerProcess(parsedArgs);
        }

        return true;
    } 
       
说明: 
   (1)  设置进程的参数是system_server, ; 
          对应的类是com.android.server.SystemServer。 
   (2)  Zygote.forkSystemServer真正地fork一个进程,参数前面已经设置好了,所以,这个fork出来的进程就是system_server,而这个进程恰恰是zygote的子进程(用ps可以看到)。
   (3) Zygote.forkSystemServer相关:
         它调用了forkAndSpecialize(dalvik\libcore\dalvik\src\main\java\dalvik\system\zytote.java), 而后者又通过jni的方式调用到 
         Dalvik_dalvik_system_Zygote_forkSystemServer(dalvik\vm\native\dalvik_system_Zygote.c),继而调用到forkAndSpecializeCommon,在这个函数中,通过 fork()函数来真正创建一个进程。这里,如果看log的话,有打印语句:LOGE("System server process %d has died. Restarting Zygote!", pid);, 而这个log在本文最后给出的log中也是有体现的。
         所以,最终,还是回到了下层的c或者cpp代码中; 而jvm只不过是对fork()进行了封装,当然,这只是它的一个必不可少的功能之一而已。 
3. system_server

  system_server上面也提到了,是一个进程,事实上,它是整个Framework的主进程,在这个进程中,会创建并启动一个thread,而这个线程是整个framework的主线程,在这个线程中,这里声明并初始化了所有的framework组件。代码位于:

  systemserver.java(位于frameworks\base\services\java\com\android\server)

   至此, 整个Android os 可以认为是启动完毕。

4.  log,是在开机过程中抓取的,当然,用的是logcat:

09-07 06:21:52.288: DEBUG/AndroidRuntime(541): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<
09-07 06:21:52.288: DEBUG/AndroidRuntime(541): CheckJNI is ON
......
09-07 06:21:52.937: INFO/(542): ServiceManager: 0xac38
09-07 06:21:52.957: INFO/AudioFlinger(542): AudioFlinger's thread ready to run for output 0
09-07 06:21:52.957: INFO/CameraService(542): CameraService started: pid=542
09-07 06:21:52.978: DEBUG/AndroidRuntime(541): --- registering native functions ---
09-07 06:21:53.308: INFO/Zygote(541): Preloading classes...
09-07 06:21:53.318: DEBUG/dalvikvm(541): GC freed 764 objects / 42216 bytes in 11ms
09-07 06:21:53.517: DEBUG/dalvikvm(541): GC freed 278 objects / 17160 bytes in 4ms
09-07 06:21:53.898: DEBUG/dalvikvm(541): GC freed 208 objects / 12696 bytes in 6ms
09-07 06:21:53.988: DEBUG/dalvikvm(541): Trying to load lib /system/lib/libmedia_jni.so 0x0
09-07 06:21:54.148: DEBUG/dalvikvm(541): Added shared lib /system/lib/libmedia_jni.so 0x0
09-07 06:21:54.148: DEBUG/dalvikvm(541): Trying to load lib /system/lib/libmedia_jni.so 0x0
09-07 06:21:54.158: DEBUG/dalvikvm(541): Shared lib '/system/lib/libmedia_jni.so' already loaded in same CL 0x0
09-07 06:21:54.158: DEBUG/dalvikvm(541): Trying to load lib /system/lib/libmedia_jni.so 0x0
09-07 06:21:54.158: DEBUG/dalvikvm(541): Shared lib '/system/lib/libmedia_jni.so' already loaded in same CL 0x0
09-07 06:21:54.158: DEBUG/dalvikvm(541): Trying to load lib /system/lib/libmedia_jni.so 0x0
09-07 06:21:54.158: DEBUG/dalvikvm(541): Shared lib '/system/lib/libmedia_jni.so' already loaded in same CL 0x0
09-07 06:21:54.168: DEBUG/dalvikvm(541): GC freed 462 objects / 29144 bytes in 8ms
......
09-07 06:21:58.748: DEBUG/dalvikvm(541): Trying to load lib /system/lib/libwebcore.so 0x0
09-07 06:21:58.828: DEBUG/dalvikvm(541): Added shared lib /system/lib/libwebcore.so 0x0
......
09-07 06:22:02.258: INFO/Zygote(541): ...preloaded 1166 classes in 8951ms.
09-07 06:22:02.337: DEBUG/dalvikvm(541): GC freed 313 objects / 19952 bytes in 67ms
09-07 06:22:02.337: INFO/Zygote(541): Preloading resources...
......
09-07 06:22:03.509: INFO/dalvikvm(541): Splitting out new zygote heap
09-07 06:22:03.569: INFO/dalvikvm(541): System server process 570 has been created
09-07 06:22:03.569: INFO/Zygote(541): Accepting command socket connections
09-07 06:22:03.638: INFO/jdwp(570): received file descriptor 10 from ADB
09-07 06:22:03.797: DEBUG/dalvikvm(570): Trying to load lib /system/lib/libandroid_servers.so 0x0
09-07 06:22:04.008: DEBUG/dalvikvm(570): Added shared lib /system/lib/libandroid_servers.so 0x0
09-07 06:22:04.027: INFO/sysproc(570): Entered system_init()
09-07 06:22:04.051: INFO/sysproc(570): ServiceManager: 0x16c900
09-07 06:22:04.051: INFO/SurfaceFlinger(570): SurfaceFlinger is starting
09-07 06:22:04.058: INFO/SurfaceFlinger(570): SurfaceFlinger's main thread ready to run. Initializing graphics H/W...
09-07 06:22:04.079: ERROR/MemoryHeapBase(570): error opening /dev/pmem: No such file or directory
09-07 06:22:04.087: ERROR/SurfaceFlinger(570): Couldn't open /sys/power/wait_for_fb_sleep or /sys/power/wait_for_fb_wake
09-07 06:22:04.117: ERROR/GLLogger(570): couldn't load library (Cannot find library)
09-07 06:22:04.127: INFO/SurfaceFlinger(570): EGL informations:
09-07 06:22:04.127: INFO/SurfaceFlinger(570): # of configs : 6
09-07 06:22:04.127: INFO/SurfaceFlinger(570): vendor    : Android
09-07 06:22:04.127: INFO/SurfaceFlinger(570): version   : 1.31 Android META-EGL
09-07 06:22:04.127: INFO/SurfaceFlinger(570): extensions: 
09-07 06:22:04.127: INFO/SurfaceFlinger(570): Client API: OpenGL ES
09-07 06:22:04.127: INFO/EGLDisplaySurface(570): using (fd=22)
09-07 06:22:04.127: INFO/EGLDisplaySurface(570): id           = 
09-07 06:22:04.127: INFO/EGLDisplaySurface(570): xres         = 320 px
09-07 06:22:04.127: INFO/EGLDisplaySurface(570): yres         = 480 px
09-07 06:22:04.127: INFO/EGLDisplaySurface(570): xres_virtual = 320 px
09-07 06:22:04.127: INFO/EGLDisplaySurface(570): yres_virtual = 960 px
09-07 06:22:04.127: INFO/EGLDisplaySurface(570): bpp          = 16
09-07 06:22:04.127: INFO/EGLDisplaySurface(570): r            = 11:5
09-07 06:22:04.127: INFO/EGLDisplaySurface(570): g            =  5:6
09-07 06:22:04.127: INFO/EGLDisplaySurface(570): b            =  0:5
09-07 06:22:04.127: INFO/EGLDisplaySurface(570): width        = 49 mm (165.877548 dpi)
09-07 06:22:04.127: INFO/EGLDisplaySurface(570): height       = 74 mm (164.756760 dpi)
09-07 06:22:04.127: INFO/EGLDisplaySurface(570): refresh rate = 60.00 Hz
09-07 06:22:04.138: WARN/HAL(570): load: module=/system/lib/hw/copybit.goldfish.so error=Cannot find library
09-07 06:22:04.138: WARN/HAL(570): load: module=/system/lib/hw/copybit.default.so error=Cannot find library
09-07 06:22:04.138: WARN/SurfaceFlinger(570): ro.sf.lcd_density not defined, using 160 dpi by default.
09-07 06:22:04.148: INFO/SurfaceFlinger(570): OpenGL informations:
09-07 06:22:04.148: INFO/SurfaceFlinger(570): vendor    : Android
09-07 06:22:04.148: INFO/SurfaceFlinger(570): renderer  : Android PixelFlinger 1.0
09-07 06:22:04.148: INFO/SurfaceFlinger(570): version   : OpenGL ES-CM 1.0
09-07 06:22:04.148: INFO/SurfaceFlinger(570): extensions: GL_OES_byte_coordinates GL_OES_fixed_point GL_OES_single_precision GL_OES_read_format GL_OES_compressed_paletted_texture GL_OES_draw_texture GL_OES_matrix_get GL_OES_query_matrix GL_ARB_texture_compression GL_ARB_texture_non_power_of_two GL_ANDROID_direct_texture GL_ANDROID_user_clip_plane GL_ANDROID_vertex_buffer_object GL_ANDROID_generate_mipmap 
09-07 06:22:04.148: WARN/HAL(570): load: module=/system/lib/hw/copybit.goldfish.so error=Cannot find library
09-07 06:22:04.148: WARN/HAL(570): load: module=/system/lib/hw/copybit.default.so error=Cannot find library
09-07 06:22:04.148: WARN/HAL(570): load: module=/system/lib/hw/overlay.goldfish.so error=Cannot find library
09-07 06:22:04.148: WARN/HAL(570): load: module=/system/lib/hw/overlay.default.so error=Cannot find library
09-07 06:22:04.167: INFO/sysproc(570): System server: starting Android runtime.
09-07 06:22:04.167: INFO/sysproc(570): System server: starting Android services.
09-07 06:22:04.179: INFO/SystemServer(570): Entered the Android system server!
09-07 06:22:04.209: INFO/sysproc(570): System server: entering thread pool.
09-07 06:22:04.267: ERROR/GLLogger(570): couldn't load library (Cannot find library)
09-07 06:22:04.338: INFO/SystemServer(570): Starting Power Manager.
09-07 06:22:04.387: INFO/ARMAssembler(570): generated scanline__00000077:03545404_00000A01_00000000 [ 30 ipp] (51 ins) at [0x190ed0:0x190f9c] in 6840752 ns
09-07 06:22:04.397: INFO/SystemServer(570): Starting Activity Manager.
09-07 06:22:04.578: INFO/SystemServer(570): Starting telephony registry
09-07 06:22:04.588: INFO/SystemServer(570): Starting Package Manager.
09-07 06:22:04.619: INFO/Installer(570): connecting...
09-07 06:22:04.619: INFO/installd(543): new connection
......

当然,这里的信息足够多的,有兴趣的朋友不妨用这种方法去理解和研究一下android启动过程。

Android system_server进程的初始化过程(包含jvm的初始化) 阅读世界,共赴山海 Android system_server进程的初始化过程(包含jvm的初始化) 423全民读书节,邀你共读