Android系统源码情景分析-学习笔记-11

概述:

     在Android系统中,所有的应用程序进程,以及用来运行系统关键服务的System进程都是由Zygote进程负责创建的,因此,我们将它成为进程孵化器。Zygote进程是通过复制自身的方式来创建System进程和应用程序进程。由于Zygote进程在启动时会在内部创建一个虚拟机实例,因此,通过复制Zygote进程而得到的System进程和应用程序进程可以快速地在内部获得一个虚拟机实例拷贝。
     Zygote进程启动完成以后,会马上将system进程启动起来,以便它可以将系统关键服务启动起来。

init 进程概述:

init进程是Android启动后的,由内核启动的第一个用户级进程
Android 的init进程提供四大功能:

  1. init进程处理子进程的终止与再启动
  2. init 进程分析init.rc 启动脚本文件,并根据相关中包含的内容,执行相应的功能;
  3. init进程提供属性服务;
  4. init进程生成设备节点文件

11. 1 zygote进程的启动脚本

     Zygote进程是由Android系统的第一个进程init启动起来的。init进程是在内核加载完成之后就启动起来的(也就是用户空间的第一个进程),它的启动过程中,会读取根目录下的一个脚本文件init.rc,以便可以将其他需要开启的进程也一起启动起来。

     Zygote进程在脚本文件init.rc 中的启动脚本

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
socket zygote stream 666
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd

     第一行表示Zygote进程是以服务的形式启动的,并且它所对应的应用程序文件为 /system/bin/app_process。接下来的四个选项是Zygote进程的启动参数,其中,
最后一个参数 "--start-system-server" 表示Zygote进程在启动完成之后,需要马上将System进程也启动起来。

     第二行表示Zygote进程在启动的过程中,需要再内部创建一个名称为 "zygote" 的socket。这个Socket是用来执行进程间通信的,
它的访问权限被这只为666,即所有用户都可以对它进行读写。

     由于Zygote进程在脚本文件init.rc中配置了以服务的形式来启动,因此,init进程在启动时,就会调用函数service_start来启动它,

11.2 Zygote 进程的启动过程

app_main.cpp # main

int main(int argc, const char* const argv[])
{
    ...

    // Next arg is startup classname or "--zygote"
    if (i < argc) {
        arg = argv[i++];
        // zygote 启动流程  
        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 {
            ....
        }
    } else {
        ....
    }

}

通过AppRuntime (父类:AndroidRuntime) 来启动java 虚拟机,运行com.android.internal.os.ZygoteInit 的main函数

AndroidRuntime.cpp # start

来启动java 虚拟机,运行com.android.internal.os.ZygoteInit 的main函数

void AndroidRuntime::start(const char* className, const bool startSystemServer)
{

    char* slashClassName = NULL;
    char* cp;
    JNIEnv* env;

    blockSigpipe();

    /* 
     * 'startSystemServer == true' means runtime is obslete and not run from 
     * init.rc anymore, so we print out the boot start event here.
     */
    if (startSystemServer) {
        /* track our progress through the boot sequence */
        const int LOG_BOOT_PROGRESS_START = 3000;
        LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, 
                       ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
    }

    const char* rootDir = getenv("ANDROID_ROOT");
    if (rootDir == NULL) {
        rootDir = "/system";
        if (!hasDir("/system")) {
            LOG_FATAL("No root directory specified, and /android does not exist.");
            goto bail;
        }
        setenv("ANDROID_ROOT", rootDir, 1);
    }

    //const char* kernelHack = getenv("LD_ASSUME_KERNEL");
    //LOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);

    /* start the virtual machine */
    if (startVm(&mJavaVM, &env) != 0)
        goto bail;

    /*
     * Register android functions.
     */
    if (startReg(env) < 0) {
        LOGE("Unable to register all android natives\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) {
        ...
    } else {
        startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            ...
        } else {
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
...
        }
    }

    ...

bail:
    free(slashClassName);
}

ZygoteInit # main

    public static void main(String argv[]) {
        try {
            VMRuntime.getRuntime().setMinimumHeapSize(5 * 1024 * 1024);

            
            // 创建一个Server端Socket, 等待 ActivityManagerservice 的请求来创建新的进程。
            registerZygoteSocket();
           
            preloadClasses();
            //cacheRegisterMaps();
            preloadResources();

            // Do an initial gc to clean up after startup
            gc();
            
            if (argv[1].equals("true")) {
                // 启动 system server
                startSystemServer();
            } 
            // ZYGOTE_FORK_MODE 的值默认为true
            if (ZYGOTE_FORK_MODE) {
                // 调用这个函数,来等待ActivityManagerService 请求Zygote进程创建新的应用程序。
               // 不过,这种情况下,对于每一个请求,Zygote进程都会创建一个新的进程来处理,这样会浪费大量的进程资源。
              // 因此, 为了让所有的创建应用程序进程请求都在同一个进程中处理,我们将ZygoteInit类的静态成员变量 ZYGOTE_FORK_MODE 设置为false
                runForkMode();
            } else {
                runSelectLoopMode();
            }

            closeServerSocket();
        } catch (MethodAndArgsCaller caller) { ... } catch (RuntimeException ex) { ... }
    }

ZygoteInit#startSystemServer

启动System Server 进程

    /**
     * Prepare the arguments and fork for the system server process.
     */
    private static boolean startSystemServer()
            throws MethodAndArgsCaller, RuntimeException {
        // System Server 进程的启动参数 
        /* 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,1018,3001,3002,3003",
            "--capabilities=130104352,130104352",
            "--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,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        if (pid == 0) {
            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }

System Server 进程的启动

由于System进程复制了Zygote进程的地址空间,因此它就会获得Zygote进程在启动过程中创建的一个socket。System进程不需要使用这个Socket,因此,需要调用closeServerSocket 来关闭它。
接下来需要调用RuntimeInit 的 zygoteInit 来进一步启动System进程。

    /**
     * Finish remaining work for the newly forked system server process.
     */
    private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {

        closeServerSocket();

        /*
         * Pass the remaining arguments to SystemServer.
         * "--nice-name=system_server com.android.server.SystemServer"
         */
        RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
        /* should never reach here */
    }

RuntimeInit # zygoteInit

    /**
     * The main function called when started through the zygote process. This
     * could be unified with main(), if the native code in finishInit()
     * were rationalized with Zygote startup.

* * Current recognized args: *

    *
  • --nice-name=nice name to appear in ps *
  • [--] <start class name> <args> *
* * @param argv arg strings */ public static final void zygoteInit(String[] argv) throws ZygoteInit.MethodAndArgsCaller { // 设置System进程的回去和键盘布局等通用信息 commonInit(); // 在System进程中启动一个Binder线程池 zygoteInitNative(); int curArg = 0; for ( /* curArg */ ; curArg < argv.length; curArg++) { String arg = argv[curArg]; if (arg.equals("--")) { curArg++; break; } else if (!arg.startsWith("--")) { break; } else if (arg.startsWith("--nice-name=")) { String niceName = arg.substring(arg.indexOf('=') + 1); Process.setArgV0(niceName); } } if (curArg == argv.length) { Slog.e(TAG, "Missing classname argument to RuntimeInit!"); // let the process exit return; } // Remaining arguments are passed to the start class's static main String startClass = argv[curArg++]; String[] startArgs = new String[argv.length - curArg]; System.arraycopy(argv, curArg, startArgs, 0, startArgs.length); // 启动 com.android.server.SystemServer类的main函数 invokeStaticMain(startClass, startArgs); }

SystemServer # main

进入SystemServer进程的java世界

    public static void main(String[] args) {
        // The system server has to run all of the time, so it needs to be
        // as efficient as possible with its memory usage.
        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
        
        System.loadLibrary("android_servers");
        // 启动一些使用C++语言开发的系统服务,
        // com_android_server_SystemServer.cpp
        // android_server_SystemServer_init1 方法
        init1(args);
    }

system_init.cpp # system_init

extern "C" status_t system_init()
{
    LOGI("Entered system_init()");
    
    sp proc(ProcessState::self());
    
    sp sm = defaultServiceManager();
    LOGI("ServiceManager: %p\n", sm.get());
    
    sp grim = new GrimReaper();
    sm->asBinder()->linkToDeath(grim, grim.get(), 0);
    
    char propBuf[PROPERTY_VALUE_MAX];
    property_get("system_init.startsurfaceflinger", propBuf, "1");
    if (strcmp(propBuf, "1") == 0) {
        // Start the SurfaceFlinger
        SurfaceFlinger::instantiate();
    }

    // Start the sensor service
    SensorService::instantiate();

    // On the simulator, audioflinger et al don't get started the
    // same way as on the device, and we need to start them here
    if (!proc->supportsProcesses()) {

        // Start the AudioFlinger
        AudioFlinger::instantiate();

        // Start the media playback service
        MediaPlayerService::instantiate();

        // Start the camera service
        CameraService::instantiate();

        // Start the audio policy service
        AudioPolicyService::instantiate();
    }

    // And now start the Android runtime.  We have to do this bit
    // of nastiness because the Android runtime initialization requires
    // some of the core system services to already be started.
    // All other servers should just start the Android runtime at
    // the beginning of their processes's main(), before calling
    // the init function.
    LOGI("System server: starting Android runtime.\n");
    
    AndroidRuntime* runtime = AndroidRuntime::getRuntime();

    LOGI("System server: starting Android services.\n");
    runtime->callStatic("com/android/server/SystemServer", "init2");
        
    // If running in our own process, just go into the thread
    // pool.  Otherwise, call the initialization finished
    // func to let this process continue its initilization.
    if (proc->supportsProcesses()) {
        LOGI("System server: entering thread pool.\n");
        ProcessState::self()->startThreadPool();
        IPCThreadState::self()->joinThreadPool();
        LOGI("System server: exiting thread pool.\n");
    }
    return NO_ERROR;
}

SystemServer#init2

    public static final void init2() {
        Slog.i(TAG, "Entered the Android system server!");
        Thread thr = new ServerThread();
        thr.setName("android.server.ServerThread");
        thr.start();
    }

SystemServer#ServerThread#

    @Override
    public void run() {
        Looper.prepare();

        ((ActivityManagerService)ActivityManagerNative.getDefault())
                .systemReady(new Runnable() {
            public void run() {
                Slog.i(TAG, "Making services ready");
                ...
            }
        });

        Looper.loop();
        Slog.d(TAG, "System ServerThread is exiting!");
    }

你可能感兴趣的:(Android系统源码情景分析-学习笔记-11)