前面的篇章已经打通了kernel到init只zygote进程,下面就说下怎么从zygote中把SystemServer启动 起来的.
/frameworks/base/core/java/com/android/internal/os/
  - ZygoteInit.java
  - RuntimeInit.java
  - Zygote.java
/frameworks/base/core/services/java/com/android/server/
  - SystemServer.java
/frameworks/base/core/jni/
  - com_android_internal_os_Zygote.cpp
  - AndroidRuntime.cpp
从上面的代码我们可以知道在zygote中调用startSystemServer方法,最终会调用到Zygote.forkSystemServer 的方法
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
    VM_HOOKS.preFork();
    // 调用native方法fork system_server进程【见小节3】
    int pid = nativeForkSystemServer(
            uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
    if (pid == 0) {
        Trace.setTracingEnabled(true);
    }
    VM_HOOKS.postForkCommon();
    return pid;
}
nativeForkSystemServer()方法在AndroidRuntime.cpp中注册的,这个我们在上一篇说过会有一个native的对应关系
com_android_internal_os_Zygote.cpp中的  
register_com_android_internal_os_Zygote()所以接下来进入如下方法。
在这个cpp文件里面 com_android_internal_os_Zygote.cpp
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
871        JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
872        jint runtime_flags, jobjectArray rlimits, jlong permittedCapabilities,
873        jlong effectiveCapabilities) {
     //fork子进程
874  pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
875                                      runtime_flags, rlimits,
876                                      permittedCapabilities, effectiveCapabilities,
877                                      MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
878                                      NULL, false, NULL, NULL);
879  if (pid > 0) {
880      // The zygote process checks whether the child process has died or not.
         zygote进程,检测system_server进程是否创建
881      ALOGI("System server process %d has been created", pid);
882      gSystemServerPid = pid;
883      // There is a slight window that the system server process has crashed
884      // but it went unnoticed because we haven't published its pid yet. So
885      // we recheck here just to make sure that all is well.
886      int status;
887      if (waitpid(pid, &status, WNOHANG) == pid) {
888          ALOGE("System server process %d has died. Restarting Zygote!", pid);
             当system_server进程死亡后,重启zygote进程
889          RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
890      }
891
892      // Assign system_server to the correct memory cgroup.
893      // Not all devices mount /dev/memcg so check for the file first
894      // to avoid unnecessarily printing errors and denials in the logs.
895      if (!access("/dev/memcg/system/tasks", F_OK) &&
896                !WriteStringToFile(StringPrintf("%d", pid), "/dev/memcg/system/tasks")) {
897        ALOGE("couldn't write %d to /dev/memcg/system/tasks", pid);
898      }
899  }
900  return pid;
901}
这个方法太长了,我只截取其中的一小部分的关键字
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
540                                     jint runtime_flags, jobjectArray javaRlimits,
541                                     jlong permittedCapabilities, jlong effectiveCapabilities,
542                                     jint mount_external,
543                                     jstring java_se_info, jstring java_se_name,
544                                     bool is_system_server, jintArray fdsToClose,
545                                     jintArray fdsToIgnore, bool is_child_zygote,
546                                     jstring instructionSet, jstring dataDir) {
547
570
571  // Temporarily block SIGCHLD during forks. The SIGCHLD handler might
572  // log, which would result in the logging FDs we close being reopened.
573  // This would cause failures because the FDs are not whitelisted.
574  //
575  // Note that the zygote process is single threaded at this point.
576  if (sigprocmask(SIG_BLOCK, &sigchld, nullptr) == -1) {
577    fail_fn(CREATE_ERROR("sigprocmask(SIG_SETMASK, { SIGCHLD }) failed: %s", strerror(errno)));
578  }
579
580  // Close any logging related FDs before we start evaluating the list of
581  // file descriptors.
582  __android_log_close();
583
584  std::string error_msg;
585
586  // If this is the first fork for this zygote, create the open FD table.
587  // If it isn't, we just need to check whether the list of open files has
588  // changed (and it shouldn't in the normal case).
589  std::vector<int> fds_to_ignore;
590  if (!FillFileDescriptorVector(env, fdsToIgnore, &fds_to_ignore, &error_msg)) {
591    fail_fn(error_msg);
592  }
593  if (gOpenFdTable == NULL) {
594    gOpenFdTable = FileDescriptorTable::Create(fds_to_ignore, &error_msg);
595    if (gOpenFdTable == NULL) {
596      fail_fn(error_msg);
597    }
598  } else if (!gOpenFdTable->Restat(fds_to_ignore, &error_msg)) {
599    fail_fn(error_msg);
600  }
601  //在这里调用linux的标准创建进程的方法
602  pid_t pid = fork();
603
604  if (pid == 0) {
605    PreApplicationInit();
606
607    // Clean up any descriptors which must be closed immediately
608    if (!DetachDescriptors(env, fdsToClose, &error_msg)) {
609      fail_fn(error_msg);
610    }
611
612    // Re-open all remaining open file descriptors so that they aren't shared
613    // with the zygote across a fork.
614    if (!gOpenFdTable->ReopenOrDetach(&error_msg)) {
615      fail_fn(error_msg);
616    }
       .............
       最后return 这个pid,这里创建已经完成了
       fork()创建新进程,采用copy on write方式,这是linux创建进程的标准方法,会有两次return,
       对于pid==0为子进程的返回,对于pid>0为父进程的返回.到此system_server进程已完成了创建的所有工  
       作,接下来开始了system_server进程的真正工作.在zygoteinit.java中,创建完成systemserver进程之后
       执行handleSystemServerProcess
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
454        // set umask to 0077 so new files and directories will default to owner-only permissions.
455        Os.umask(S_IRWXG | S_IRWXO);
456
457        if (parsedArgs.niceName != null) {
458            Process.setArgV0(parsedArgs.niceName);
459        }
460        获取SYSTEMSERVERCLASSPATH环境变量中的值
           adb shell, export,查看所有环境变量的值, $SYSTEMSERVERCLASSPATH 取值
461        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
462        if (systemServerClasspath != null) {
463            performSystemServerDexOpt(systemServerClasspath);
464            // Capturing profiles is only supported for debug or eng builds since selinux normally
465            // prevents it.
466            boolean profileSystemServer = SystemProperties.getBoolean(
467                    "dalvik.vm.profilesystemserver", false);
468            if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
469                try {
470                    prepareSystemServerProfile(systemServerClasspath);
471                } catch (Exception e) {
472                    Log.wtf(TAG, "Failed to set up system server profile", e);
473                }
474            }
475        }
476
477        if (parsedArgs.invokeWith != null) {
478            String[] args = parsedArgs.remainingArgs;
479            // If we have a non-null system server class path, we'll have to duplicate the
480            // existing arguments and append the classpath to it. ART will handle the classpath
481            // correctly when we exec a new process.
482            if (systemServerClasspath != null) {
483                String[] amendedArgs = new String[args.length + 2];
484                amendedArgs[0] = "-cp";
485                amendedArgs[1] = systemServerClasspath;
486                System.arraycopy(args, 0, amendedArgs, 2, args.length);
487                args = amendedArgs;
488            }
489
490            WrapperInit.execApplication(parsedArgs.invokeWith,
491                    parsedArgs.niceName, parsedArgs.targetSdkVersion,
492                    VMRuntime.getCurrentInstructionSet(), null, args);
493
494            throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
495        } else {
496            ClassLoader cl = null;
497            if (systemServerClasspath != null) {
                   //加载SYSTEMSERVERCLASSPATH环境变量中的类
498                cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
499
500                Thread.currentThread().setContextClassLoader(cl);
501            }
502
503            /*
504             * Pass the remaining arguments to SystemServer.
505             */
506            return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
507        }
508
509        /* should never reach here */
510    }
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
903        if (RuntimeInit.DEBUG) {
904            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
905        }
906
907        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
908        RuntimeInit.redirectLogStreams();
909
910        RuntimeInit.commonInit();
911        ZygoteInit.nativeZygoteInit();
912        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
913    }
在AndroidRuntime.cpp中可以得知 nativeZygoteInit 所对应的c++方法为 com_android_internal_os_ZygoteInit_nativeZygoteInit
int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
258{
259    const JNINativeMethod methods[] = {
260        { "nativeZygoteInit", "()V",
261            (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
262    };
263    return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
264        methods, NELEM(methods));
265}
gCurRuntime为zygote中的runtime
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
231{
       //开启一个binder线程
232    gCurRuntime->onZygoteInit();
233}
234
在zygoteinit中继续开启
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
346            ClassLoader classLoader) {
347        // If the application calls System.exit(), terminate the process
348        // immediately without running any shutdown hooks.  It is not possible to
349        // shutdown an Android application gracefully.  Among other things, the
350        // Android runtime shutdown hooks close the Binder driver, which can cause
351        // leftover running threads to crash before the process actually exits.
352        nativeSetExitWithoutCleanup(true);
353
354        // We want to be fairly aggressive about heap utilization, to avoid
355        // holding on to a lot of memory that isn't needed.
356        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
357        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
358
359        final Arguments args = new Arguments(argv);
360
361        // The end of of the RuntimeInit event (see #zygoteInit).
362        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
363
364        // Remaining arguments are passed to the start class's static main
365        return findStaticMain(args.startClass, args.startArgs, classLoader);
366    }
protected static Runnable findStaticMain(String className, String[] argv,
288            ClassLoader classLoader) {
289        Class<?> cl;
290
291        try {
292            cl = Class.forName(className, true, classLoader);
293        } catch (ClassNotFoundException ex) {
294            throw new RuntimeException(
295                    "Missing class when invoking static main " + className,
296                    ex);
297        }
298
299        Method m;
300        try {
              获取com.android.server.SystemServer的main方法
301            m = cl.getMethod("main", new Class[] { String[].class });
302        } catch (NoSuchMethodException ex) {
303            throw new RuntimeException(
304                    "Missing static main on " + className, ex);
305        } catch (SecurityException ex) {
306            throw new RuntimeException(
307                    "Problem getting static main on " + className, ex);
308        }
309
310        int modifiers = m.getModifiers();
311        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
312            throw new RuntimeException(
313                    "Main method is not public and static on " + className);
314        }
315
316        /*
317         * This throw gets caught in ZygoteInit.main(), which responds
318         * by invoking the exception's run() method. This arrangement
319         * clears up all the stack frames that were required in setting
320         * up the process.
321         */
322        return new MethodAndArgsCaller(m, argv);
323    }
紧接着
static class MethodAndArgsCaller implements Runnable {
480        /** method to call */
481        private final Method mMethod;
482
483        /** argument array */
484        private final String[] mArgs;
485
486        public MethodAndArgsCaller(Method method, String[] args) {
487            mMethod = method;
488            mArgs = args;
489        }
490
491        public void run() {
492            try {
493                mMethod.invoke(null, new Object[] { mArgs });
494            } catch (IllegalAccessException ex) {
495                throw new RuntimeException(ex);
496            } catch (InvocationTargetException ex) {
497                Throwable cause = ex.getCause();
498                if (cause instanceof RuntimeException) {
499                    throw (RuntimeException) cause;
500                } else if (cause instanceof Error) {
501                    throw (Error) cause;
502                }
503                throw new RuntimeException(ex);
504            }
505        }
506    }
最终会返回一个runnable. 会在zygote main函数里面调用. 最终com.android.server.SystemServer中的
main方法执行,并且作为一个fork出来的进程执行
到此终于进入到systemserver中的main方法里面,并且系统中最为重要的一个线程起来了.
Zygote是由init进程通过解析init.zygote.rc文件而创建的,zygote所对应的可执行程序app_process, 所对应的源文件是App_main.cpp,进程名为zygote。
通过查看http://androidxref.com/9.0.0_r3/xref/system/core/rootdir/init.rc文件
在 /system/core/rootdir/init.rc 文件里面会导入
import /init.${ro.zygote}.rcimport /init.${ro.zygote}.rc
这个目录下面http://androidxref.com/9.0.0_r3/xref/system/core/rootdir/ zygote文件里面
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    class main
    socket zygote stream 660 root system
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart media
    onrestart restart netd
大致流程

这里不在画了,用了gityuan先生的图,很简单的,跟着代码就可以画了
而init.rc文件会在init进程里面解析::
static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
111    Parser parser = CreateParser(action_manager, service_list);
112
113    std::string bootscript = GetProperty("ro.boot.init_rc", "");
114    if (bootscript.empty()) {
115        parser.ParseConfig("/init.rc");
116        if (!parser.ParseConfig("/system/etc/init")) {
117            late_import_paths.emplace_back("/system/etc/init");
118        }
119        if (!parser.ParseConfig("/product/etc/init")) {
120            late_import_paths.emplace_back("/product/etc/init");
121        }
122        if (!parser.ParseConfig("/odm/etc/init")) {
123            late_import_paths.emplace_back("/odm/etc/init");
124        }
125        if (!parser.ParseConfig("/vendor/etc/init")) {
126            late_import_paths.emplace_back("/vendor/etc/init");
127        }
128    } else {
129        parser.ParseConfig(bootscript);
130    }
131}
132
所以zygote进程就启动了
源码所在目录http://androidxref.com/9.0.0_r3/xref/frameworks/base/cmds/app_process/
在zygote文件里面可以看到
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
后面的参数是 –zygote 和 –start-system-server
while (i < argc) {
279        const char* arg = argv[i++];
280        if (strcmp(arg, "--zygote") == 0) {
	             下面要用到
281            zygote = true;
282            niceName = ZYGOTE_NICE_NAME;
283        } else if (strcmp(arg, "--start-system-server") == 0) {
	             需要开启systemserver
284            startSystemServer = true;
285        } else if (strcmp(arg, "--application") == 0) {
286            application = true;
287        } else if (strncmp(arg, "--nice-name=", 12) == 0) {
288            niceName.setTo(arg + 12);
289        } else if (strncmp(arg, "--", 2) != 0) {
290            className.setTo(arg);
291            break;
292        } else {
293            --i;
294            break;
295        }
296    }
297
348    zygote为true,通过反射调用zygoteinit,开启虚拟机,在开启虚拟机的时候加载android基础的类
       bootclasspath路径下的类
349    if (zygote) {
350        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
351    //如果是App的话
        } else if (className) {
352        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
353    } else {
354        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
355        app_usage();
356        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
357    }
358}
359
可以看到在app_main.cpp里面定义了runtime
class AppRuntime : public AndroidRuntime
34{
35public:
36    AppRuntime(char* argBlockStart, const size_t argBlockLength)
37        : AndroidRuntime(argBlockStart, argBlockLength)
38        , mClass(NULL)
39    {
40    }
41
42    void setClassNameAndArgs(const String8& className, int argc, char * const *argv) {
43        mClassName = className;
44        for (int i = 0; i < argc; ++i) {
45             mArgs.add(String8(argv[i]));
46        }
47    }
48
49    virtual void onVmCreated(JNIEnv* env)
50    {
51        if (mClassName.isEmpty()) {
52            return; // Zygote. Nothing to do here.
53        }
54
55        /*
56         * This is a little awkward because the JNI FindClass call uses the
57         * class loader associated with the native method we're executing in.
58         * If called in onStarted (from RuntimeInit.finishInit because we're
59         * launching "am", for example), FindClass would see that we're calling
60         * from a boot class' native method, and so wouldn't look for the class
61         * we're trying to look up in CLASSPATH. Unfortunately it needs to,
62         * because the "am" classes are not boot classes.
63         *
64         * The easiest fix is to call FindClass here, early on before we start
65         * executing boot class Java code and thereby deny ourselves access to
66         * non-boot classes.
67         */
68        char* slashClassName = toSlashClassName(mClassName.string());
69        mClass = env->FindClass(slashClassName);
70        if (mClass == NULL) {
71            ALOGE("ERROR: could not find class '%s'\n", mClassName.string());
72        }
73        free(slashClassName);
74
75        mClass = reinterpret_cast<jclass>(env->NewGlobalRef(mClass));
76    }
77
78    virtual void onStarted()
79    {
80        sp<ProcessState> proc = ProcessState::self();
81        ALOGV("App process: starting thread pool.\n");
82        proc->startThreadPool();
83
84        AndroidRuntime* ar = AndroidRuntime::getRuntime();
85        ar->callMain(mClassName, mClass, mArgs);
86
87        IPCThreadState::self()->stopProcess();
88        hardware::IPCThreadState::self()->stopProcess();
89    }
90
91    virtual void onZygoteInit()
92    {
93        sp<ProcessState> proc = ProcessState::self();
94        ALOGV("App process: starting thread pool.\n");
95        proc->startThreadPool();
96    }
97
98    virtual void onExit(int code)
99    {
100        if (mClassName.isEmpty()) {
101            // if zygote
102            IPCThreadState::self()->stopProcess();
103            hardware::IPCThreadState::self()->stopProcess();
104        }
105
106        AndroidRuntime::onExit(code);
107    }
108
109
110    String8 mClassName;
111    Vector<String8> mArgs;
112    jclass mClass;
113};
114
115}
116
查看AndroidRunTime.cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
1057{
1058    ALOGD(">>>>>> START %s uid %d <<<<<<\n",
1059            className != NULL ? className : "(unknown)", getuid());
1060
1061    static const String8 startSystemServer("start-system-server");
1062
1063    /*
1064     * 'startSystemServer == true' means runtime is obsolete and not run from
1065     * init.rc anymore, so we print out the boot start event here.
1066     */
1067    for (size_t i = 0; i < options.size(); ++i) {
1068        if (options[i] == startSystemServer) {
1069           /* track our progress through the boot sequence */
1070           const int LOG_BOOT_PROGRESS_START = 3000;
1071           LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,  ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
1072        }
1073    }
1074
1075    const char* rootDir = getenv("ANDROID_ROOT");
1076    if (rootDir == NULL) {
1077        rootDir = "/system";
1078        if (!hasDir("/system")) {
1079            LOG_FATAL("No root directory specified, and /android does not exist.");
1080            return;
1081        }
1082        setenv("ANDROID_ROOT", rootDir, 1);
1083    }
1084
1085    //const char* kernelHack = getenv("LD_ASSUME_KERNEL");
1086    //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);
1087
1088    /* start the virtual machine */
1089    JniInvocation jni_invocation;
1090    jni_invocation.Init(NULL);
1091    JNIEnv* env;
        //创建虚拟机,看下面2.2
1092    if (startVm(&mJavaVM, &env, zygote) != 0) {
1093        return;
1094    }
1095    onVmCreated(env);
1096
1097    /*
1098     * Register android functions.
1099     */
        //JNI方法注册,看下面2.3
1100    if (startReg(env) < 0) {
1101        ALOGE("Unable to register all android natives\n");
1102        return;
1103    }
1104
1105    /*
1106     * We want to call main() with a String array with arguments in it.
1107     * At present we have two arguments, the class name and an option string.
1108     * Create an array to hold them.
1109     */
1110    jclass stringClass;
1111    jobjectArray strArray;
1112    jstring classNameStr;
1113
1114    stringClass = env->FindClass("java/lang/String");
1115    assert(stringClass != NULL);
1116    strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
1117    assert(strArray != NULL);
1118    classNameStr = env->NewStringUTF(className);
1119    assert(classNameStr != NULL);
1120    env->SetObjectArrayElement(strArray, 0, classNameStr);
1121
1122    for (size_t i = 0; i < options.size(); ++i) {
1123        jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
1124        assert(optionsStr != NULL);
1125        env->SetObjectArrayElement(strArray, i + 1, optionsStr);
1126    }
1127
1128    /*
1129     * Start VM.  This thread becomes the main thread of the VM, and will
1130     * not return until the VM exits.
1131     */
        将"com.android.internal.os.ZygoteInit"转换为"com/android/internal/os/ZygoteInit"
        因为传入进来的是com.android.internal.os.ZygoteInit
1132    char* slashClassName = toSlashClassName(className != NULL ? className : "");
1133    jclass startClass = env->FindClass(slashClassName);
1134    if (startClass == NULL) {
1135        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
1136        /* keep going */
1137    } else {
            //进入java的世界了
1138        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
1139            "([Ljava/lang/String;)V");
1140        if (startMeth == NULL) {
1141            ALOGE("JavaVM unable to find main() in '%s'\n", className);
1142            /* keep going */
1143        } else {
1144            env->CallStaticVoidMethod(startClass, startMeth, strArray);
1145
1146#if 0
1147            if (env->ExceptionCheck())
1148                threadExitUncaughtException(env);
1149#endif
1150        }
1151    }
1152    free(slashClassName);
1153
1154    ALOGD("Shutting down VM\n");
1155    if (mJavaVM->DetachCurrentThread() != JNI_OK)
1156        ALOGW("Warning: unable to detach main thread\n");
1157    if (mJavaVM->DestroyJavaVM() != 0)
1158        ALOGW("Warning: VM did not shut down cleanly\n");
1159}
只是列出了一些常用的参数,是不是很熟悉,这些都可以在配置文件里面看到
...................
parseRuntimeOption("dalvik.vm.heapstartsize", heapstartsizeOptsBuf, "-Xms", "4m");
716    parseRuntimeOption("dalvik.vm.heapsize", heapsizeOptsBuf, "-Xmx", "16m");
717
718    parseRuntimeOption("dalvik.vm.heapgrowthlimit", heapgrowthlimitOptsBuf, "-XX:HeapGrowthLimit=");
719    parseRuntimeOption("dalvik.vm.heapminfree", heapminfreeOptsBuf, "-XX:HeapMinFree=");
720    parseRuntimeOption("dalvik.vm.heapmaxfree", heapmaxfreeOptsBuf, "-XX:HeapMaxFree=");
721    parseRuntimeOption("dalvik.vm.heaptargetutilization",
722                       heaptargetutilizationOptsBuf,
723                       "-XX:HeapTargetUtilization=");
724
...................
/*
1009     * Initialize the VM.
1010     *
1011     * The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.
1012     * If this call succeeds, the VM is ready, and we can start issuing
1013     * JNI calls.
1014     */
        //去创建jvm
1015    if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
1016        ALOGE("JNI_CreateJavaVM failed\n");
1017        return -1;
1018    }
1019
int AndroidRuntime::startReg(JNIEnv* env)
{
    //设置线程创建javaCreateThreadEtc
    androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
    env->PushLocalFrame(200);
    //注册jni方法
    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
        env->PopLocalFrame(NULL);
        return -1;
    }
    env->PopLocalFrame(NULL);
    return 0;
}
注册系统里面的jni方法, 以便上层Api可以调用到Native方法,这里举一个例子
extern int register_android_hardware_Camera(JNIEnv *env);
REG_JNI(register_android_hardware_Camera)
extern 是c++中的关键字,代表着不用引入.h 或者 .cpp文件,也可以调用到.意思是别的地方已经定义过了
//举一个列子camera
register_android_hardware_Camera 这个方法会在下面这个文件里面注册
/frameworks/base/core/jni/android_hardware_Camera.cpp
6int register_android_hardware_Camera(JNIEnv *env)
1127{
        //注册成员变量
1128    field fields_to_find[] = {
1129        { "android/hardware/Camera", "mNativeContext",   "J", &fields.context },
1130        { "android/hardware/Camera$CameraInfo", "facing",   "I", &fields.facing },
1131        { "android/hardware/Camera$CameraInfo", "orientation",   "I", &fields.orientation },
1132        { "android/hardware/Camera$CameraInfo", "canDisableShutterSound",   "Z",
1133          &fields.canDisableShutterSound },
1134        { "android/hardware/Camera$Face", "rect", "Landroid/graphics/Rect;", &fields.face_rect },
1135        { "android/hardware/Camera$Face", "leftEye", "Landroid/graphics/Point;", &fields.face_left_eye},
1136        { "android/hardware/Camera$Face", "rightEye", "Landroid/graphics/Point;", &fields.face_right_eye},
1137        { "android/hardware/Camera$Face", "mouth", "Landroid/graphics/Point;", &fields.face_mouth},
1138        { "android/hardware/Camera$Face", "score", "I", &fields.face_score },
1139        { "android/hardware/Camera$Face", "id", "I", &fields.face_id},
1140        { "android/graphics/Rect", "left", "I", &fields.rect_left },
1141        { "android/graphics/Rect", "top", "I", &fields.rect_top },
1142        { "android/graphics/Rect", "right", "I", &fields.rect_right },
1143        { "android/graphics/Rect", "bottom", "I", &fields.rect_bottom },
1144        { "android/graphics/Point", "x", "I", &fields.point_x},
1145        { "android/graphics/Point", "y", "I", &fields.point_y},
1146    };
1147
1148    find_fields(env, fields_to_find, NELEM(fields_to_find));
1149
1150    jclass clazz = FindClassOrDie(env, "android/hardware/Camera");
1151    fields.post_event = GetStaticMethodIDOrDie(env, clazz, "postEventFromNative",
1152                                               "(Ljava/lang/Object;IIILjava/lang/Object;)V");
1153
1154    clazz = FindClassOrDie(env, "android/graphics/Rect");
1155    fields.rect_constructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");
1156
1157    clazz = FindClassOrDie(env, "android/hardware/Camera$Face");
1158    fields.face_constructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");
1159
1160    clazz = env->FindClass("android/graphics/Point");
1161    fields.point_constructor = env->GetMethodID(clazz, "<init>", "()V");
1162    if (fields.point_constructor == NULL) {
1163        ALOGE("Can't find android/graphics/Point()");
1164        return -1;
1165    }
1166
1167    // Register native functions
        // camMethods 注册方法,java层的方法和native层方法对应
1168    return RegisterMethodsOrDie(env, "android/hardware/Camera", camMethods, NELEM(camMethods));
1169}
//注册方法
static const JNINativeMethod camMethods[] = {
1025  { "getNumberOfCameras",
1026    "()I",
1027    (void *)android_hardware_Camera_getNumberOfCameras },
1028  { "_getCameraInfo",
1029    "(ILandroid/hardware/Camera$CameraInfo;)V",
1030    (void*)android_hardware_Camera_getCameraInfo },
1031  { "native_setup",
1032    "(Ljava/lang/Object;IILjava/lang/String;)I",
1033    (void*)android_hardware_Camera_native_setup },
1034  { "native_release",
1035    "()V",
1036    (void*)android_hardware_Camera_release },
      }
这个地方真正的进入了java的世界,接着是各种系统服务的创建
在/frameworks/base/core/jni/AndroidRuntime.cpp 里面的start方法会通过反射开始zygote
/*
1129     * Start VM.  This thread becomes the main thread of the VM, and will
1130     * not return until the VM exits.
1131     */
1132    char* slashClassName = toSlashClassName(className != NULL ? className : "");
1133    jclass startClass = env->FindClass(slashClassName);
1134    if (startClass == NULL) {
1135        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
1136        /* keep going */
1137    } else {
            //找到类里面的main函数,进入java的世界
            //http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
1138        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
1139            "([Ljava/lang/String;)V");
1140        if (startMeth == NULL) {
1141            ALOGE("JavaVM unable to find main() in '%s'\n", className);
1142            /* keep going */
1143        } else {
                //c++调用
1144            env->CallStaticVoidMethod(startClass, startMeth, strArray);
1145
1146#if 0
1147            if (env->ExceptionCheck())
1148                threadExitUncaughtException(env);
1149#endif
1150        }
1151    }
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
751        ZygoteServer zygoteServer = new ZygoteServer();
752
753        // Mark zygote start. This ensures that thread creation will throw
754        // an error.
755        ZygoteHooks.startZygoteNoThreadCreation();
756
757        // Zygote goes into its own process group.
758        try {
759            Os.setpgid(0, 0);
760        } catch (ErrnoException ex) {
761            throw new RuntimeException("Failed to setpgid(0,0)", ex);
762        }
763
764        final Runnable caller;
765        try {
766            // Report Zygote start time to tron unless it is a runtime restart
767            if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
768                MetricsLogger.histogram(null, "boot_zygote_init",
769                        (int) SystemClock.elapsedRealtime());
770            }
771
772            String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
773            TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
774                    Trace.TRACE_TAG_DALVIK);
775            bootTimingsTraceLog.traceBegin("ZygoteInit");
776            RuntimeInit.enableDdms();
777
778            boolean startSystemServer = false;
779            String socketName = "zygote";
780            String abiList = null;
781            boolean enableLazyPreload = false;
782            for (int i = 1; i < argv.length; i++) {
783                if ("start-system-server".equals(argv[i])) {
                       //这个地方设置为true,是在native zygote 进程里面孵化出来的
784                    startSystemServer = true;
785                } else if ("--enable-lazy-preload".equals(argv[i])) {
786                    enableLazyPreload = true;
787                } else if (argv[i].startsWith(ABI_LIST_ARG)) {
788                    abiList = argv[i].substring(ABI_LIST_ARG.length());
789                } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
790                    socketName = argv[i].substring(SOCKET_NAME_ARG.length());
791                } else {
792                    throw new RuntimeException("Unknown command line argument: " + argv[i]);
793                }
794            }
795
796            if (abiList == null) {
797                throw new RuntimeException("No ABI list supplied.");
798            }
799             
               //注册监听,以后通过这个这个socket来创建新的进程
800            zygoteServer.registerServerSocketFromEnv(socketName);
801            // In some configurations, we avoid preloading resources and classes eagerly.
802            // In such cases, we will preload things prior to our first fork.
803            if (!enableLazyPreload) {
804                bootTimingsTraceLog.traceBegin("ZygotePreload");
805                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
806                    SystemClock.uptimeMillis());
                   //加载一些新的资源
807                preload(bootTimingsTraceLog);
808                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
809                    SystemClock.uptimeMillis());
810                bootTimingsTraceLog.traceEnd(); // ZygotePreload
811            } else {
812                Zygote.resetNicePriority();
813            }
814
815            // Do an initial gc to clean up after startup
816            bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
817            gcAndFinalize();
818            bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
819
820            bootTimingsTraceLog.traceEnd(); // ZygoteInit
821            // Disable tracing so that forked processes do not inherit stale tracing tags from
822            // Zygote.
823            Trace.setTracingEnabled(false, 0);
824
825            Zygote.nativeSecurityInit();
826
827            // Zygote process unmounts root storage spaces.
828            Zygote.nativeUnmountStorageOnInit();
829
830            ZygoteHooks.stopZygoteNoThreadCreation();
831
832            if (startSystemServer) {
833                Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
834
835                // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
836                // child (system_server) process.
837                if (r != null) {
838                    r.run();
839                    return;
840                }
841            }
842
843            Log.i(TAG, "Accepting command socket connections");
844
845            // The select loop returns early in the child process after a fork and
846            // loops forever in the zygote.
847            caller = zygoteServer.runSelectLoop(abiList);
848        } catch (Throwable ex) {
849            Log.e(TAG, "System zygote died with exception", ex);
850            throw ex;
851        } finally {
852            zygoteServer.closeServerSocket();
853        }
854
855        // We're in the child process and have exited the select loop. Proceed to execute the
856        // command.
857        if (caller != null) {
858            caller.run();
859        }
860    }
static void preload(TimingsTraceLog bootTimingsTraceLog) {
124        Log.d(TAG, "begin preload");
125        bootTimingsTraceLog.traceBegin("BeginIcuCachePinning");
126        beginIcuCachePinning();
127        bootTimingsTraceLog.traceEnd(); // BeginIcuCachePinning
128        bootTimingsTraceLog.traceBegin("PreloadClasses");
           //加载/system/etc/preloaded-classes 这个列表里面的类,会用到Class.forName方法
           Class.forName(xxx.xx.xx);的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段
129        preloadClasses();
130        bootTimingsTraceLog.traceEnd(); // PreloadClasses
131        bootTimingsTraceLog.traceBegin("PreloadResources");
132        preloadResources();
133        bootTimingsTraceLog.traceEnd(); // PreloadResources
134        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
135        nativePreloadAppProcessHALs();
136        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
137        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
138        preloadOpenGL();
139        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
           //一些动态库
140        preloadSharedLibraries();
141        preloadTextResources();
142        // Ask the WebViewFactory to do any initialization that must run in the zygote process,
143        // for memory sharing purposes.
144        WebViewFactory.prepareWebViewInZygote();
145        endIcuCachePinning();
146        warmUpJcaProviders();
147        Log.d(TAG, "end preload");
148
149        sPreloadComplete = true;
150    }
这里引用gityuan先生的图,侵权请联系我
zygote进程内加载了preload()方法中的所有资源,当需要fork新进程时,采用copy on write技术,如下:

private static Runnable forkSystemServer(String abiList, String socketName,
658            ZygoteServer zygoteServer) {
659        long capabilities = posixCapabilitiesAsBits(
660            OsConstants.CAP_IPC_LOCK,
661            OsConstants.CAP_KILL,
662            OsConstants.CAP_NET_ADMIN,
663            OsConstants.CAP_NET_BIND_SERVICE,
664            OsConstants.CAP_NET_BROADCAST,
665            OsConstants.CAP_NET_RAW,
666            OsConstants.CAP_SYS_MODULE,
667            OsConstants.CAP_SYS_NICE,
668            OsConstants.CAP_SYS_PTRACE,
669            OsConstants.CAP_SYS_TIME,
670            OsConstants.CAP_SYS_TTY_CONFIG,
671            OsConstants.CAP_WAKE_ALARM,
672            OsConstants.CAP_BLOCK_SUSPEND
673        );
674        /* Containers run without some capabilities, so drop any caps that are not available. */
675        StructCapUserHeader header = new StructCapUserHeader(
676                OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
677        StructCapUserData[] data;
678        try {
679            data = Os.capget(header);
680        } catch (ErrnoException ex) {
681            throw new RuntimeException("Failed to capget()", ex);
682        }
683        capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);
684
685        /* Hardcoded command line to start the system server */
           //system_server的group id,uid名字
686        String args[] = {
687            "--setuid=1000",
688            "--setgid=1000",
689            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
690            "--capabilities=" + capabilities + "," + capabilities,
691            "--nice-name=system_server",
692            "--runtime-args",
693            "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
694            "com.android.server.SystemServer",
695        };
696        ZygoteConnection.Arguments parsedArgs = null;
697
698        int pid;
699
700        try {
701            parsedArgs = new ZygoteConnection.Arguments(args);
702            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
703            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
704
705            boolean profileSystemServer = SystemProperties.getBoolean(
706                    "dalvik.vm.profilesystemserver", false);
707            if (profileSystemServer) {
708                parsedArgs.runtimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
709            }
710
711            /* Request to fork the system server process */
               //fork子进程,用于运行system_server
712            pid = Zygote.forkSystemServer(
713                    parsedArgs.uid, parsedArgs.gid,
714                    parsedArgs.gids,
715                    parsedArgs.runtimeFlags,
716                    null,
717                    parsedArgs.permittedCapabilities,
718                    parsedArgs.effectiveCapabilities);
719        } catch (IllegalArgumentException ex) {
720            throw new RuntimeException(ex);
721        }
722
723        /* For child process */
724        if (pid == 0) {
725            if (hasSecondZygote(abiList)) {
726                waitForSecondaryZygote(socketName);
727            }
728
729            zygoteServer.closeServerSocket();
730            return handleSystemServerProcess(parsedArgs);
731        }
732
733        return null;
734    }
在zygote的main方法中会执行循环操作,一方面保证zygote不退出,一方面监听是否有创建进程的消息
Runnable runSelectLoop(String abiList) {
174        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
175        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
176
177        fds.add(mServerSocket.getFileDescriptor());
178        peers.add(null);
179
180        while (true) {
181            StructPollfd[] pollFds = new StructPollfd[fds.size()];
182            for (int i = 0; i < pollFds.length; ++i) {
183                pollFds[i] = new StructPollfd();
184                pollFds[i].fd = fds.get(i);
185                pollFds[i].events = (short) POLLIN;
186            }
187            try {
                   //处理轮询状态,当pollFds有事件到来则往下执行,否则阻塞在这里,我也没太看懂这个地方
                   //暂且理解为类似loop那种机制吧,如果有客户端请求就会向下走
188                Os.poll(pollFds, -1);
189            } catch (ErrnoException ex) {
190                throw new RuntimeException("poll failed", ex);
191            }
192            for (int i = pollFds.length - 1; i >= 0; --i) {
193                if ((pollFds[i].revents & POLLIN) == 0) {
194                    continue;
195                }
196
197                if (i == 0) {
                    即fds[0],代表的是sServerSocket,则意味着有客户端连接请求;
                    // 则创建ZygoteConnection对象,并添加到fds。
198                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
199                    peers.add(newPeer);
200                    fds.add(newPeer.getFileDesciptor());
201                } else {
202                    try {
203                        ZygoteConnection connection = peers.get(i);
                           会调用到Zygote里面的方法 Zygote.forkAndSpecialize,
                           nativeForkAndSpecialize
204                        final Runnable command = connection.processOneCommand(this);
205
206                        if (mIsForkChild) {
207                            // We're in the child. We should always have a command to run at this
208                            // stage if processOneCommand hasn't called "exec".
209                            if (command == null) {
210                                throw new IllegalStateException("command == null");
211                            }
212
213                            return command;
214                        } else {
215                            // We're in the server - we should never have any commands to run.
216                            if (command != null) {
217                                throw new IllegalStateException("command != null");
218                            }
219
220                            // We don't know whether the remote side of the socket was closed or
221                            // not until we attempt to read from it from processOneCommand. This shows up as
222                            // a regular POLLIN event in our regular processing loop.
223                            if (connection.isClosedByPeer()) {
224                                connection.closeSocket();
225                                peers.remove(i);
226                                fds.remove(i);
227                            }
228                        }
229                    } catch (Exception e) {
230                        if (!mIsForkChild) {
231                            // We're in the server so any exception here is one that has taken place
232                            // pre-fork while processing commands or reading / writing from the
233                            // control socket. Make a loud noise about any such exceptions so that
234                            // we know exactly what failed and why.
235
236                            Slog.e(TAG, "Exception executing zygote command: ", e);
237
238                            // Make sure the socket is closed so that the other end knows immediately
239                            // that something has gone wrong and doesn't time out waiting for a
240                            // response.
241                            ZygoteConnection conn = peers.remove(i);
242                            conn.closeSocket();
243
244                            fds.remove(i);
245                        } else {
246                            // We're in the child so any exception caught here has happened post
247                            // fork and before we execute ActivityThread.main (or any other main()
248                            // method). Log the details of the exception and bring down the process.
249                            Log.e(TAG, "Caught post-fork exception in child process.", e);
250                            throw e;
251                        }
252                    } finally {
253                        // Reset the child flag, in the event that the child process is a child-
254                        // zygote. The flag will not be consulted this loop pass after the Runnable
255                        // is returned.
256                        mIsForkChild = false;
257                    }
258                }
259            }
260        }
261    }
这里引用gityuan先生的图

然后这个地方总结的很好:
在次感谢gityuan先生。
对于Android的开机流程,不管是做为App开发者还是Framework开发者都应该了解的,做为App开发者来说
了解关于系统的开机流程, 对App的开发也是大有裨益的,对于bug的解决定位更快捷点. 所以我们一起来学习
下系统的开机流程.

 可以看到是通过do_execve方法来开启了一个新的进程
源码部分:: http://androidxref.com/kernel_3.18/xref/init/main.c#run_init_process
可以看到是通过do_execve方法来开启了一个新的进程
源码部分:: http://androidxref.com/kernel_3.18/xref/init/main.c#run_init_process
关于内核靠下部分,内核部分初始化了好多驱动的操作以及一些cpu的配置操作,我也是看了个大概就不拿出来现丑了.
查看kernel log的方法,启动后进入adb模式,然后命令:: dmesg
然后我们可以看到从kernel的kernel_init方法里面启动一个进程就是init进程,就是手机根目录下的init可执行程序
一切都始于init,bootloader 加载了内核,内核启动了init 进程。Linux系统中的init进程(pid=1)是除了idle进程(pid=0,也就是init_task)之外另一个比较特殊的进程,它是Linux内核开始建立起进程概念时第一个通过kernel_thread产生的进程,其开始在内核态执行,然后通过一个系统调用,开始执行用户空间的/sbin/init程序,期间Linux内核也经历了从内核态到用户态的特权级转变,然后所有的用户进程都有该进程派生出来。
init进程的源代码位于system/core/init
http://androidxref.com/9.0.0_r3/xref/system/core/init/init.cpp
查看mk文件得到编译生成的bin路径: LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)
int main(int argc, char** argv) {
546    if (!strcmp(basename(argv[0]), "ueventd")) {
           //创建设备节点,在这里会解析, ueventd.rc
           //ueventd.rc 这个文件里面会有设备节点,类似dev/
547        return ueventd_main(argc, argv);
548    }
549
550    if (!strcmp(basename(argv[0]), "watchdogd")) {
           //watchdogd俗称看门狗,用于系统出问题时重启系统
551        return watchdogd_main(argc, argv);
552    }
553
554    if (argc > 1 && !strcmp(argv[1], "subcontext")) {
555        InitKernelLogging(argv);
556        const BuiltinFunctionMap function_map;
557        return SubcontextMain(argc, argv, &function_map);
558    }
559
560    if (REBOOT_BOOTLOADER_ON_PANIC) {
            //初始化重启系统的处理信号,内部通过sigaction 注册信号,当监听到该信号时重启系统
561        InstallRebootSignalHandlers();
562    }
563
564    bool is_first_stage = (getenv("INIT_SECOND_STAGE") == nullptr);
565     //第一阶段:: 这个时候为true,
        //挂载文件系统并创建目录
566    if (is_first_stage) {
567        boot_clock::time_point start_time = boot_clock::now();
568
569        // Clear the umask.
570        umask(0);
571
572        clearenv();
573        setenv("PATH", _PATH_DEFPATH, 1);
574        // Get the basic filesystem setup we need put together in the initramdisk
575        // on / and then we'll let the rc file figure out the rest.
576        mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
577        mkdir("/dev/pts", 0755);
578        mkdir("/dev/socket", 0755);
579        mount("devpts", "/dev/pts", "devpts", 0, NULL);
580        #define MAKE_STR(x) __STRING(x)
581        mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
582        // Don't expose the raw commandline to unprivileged processes.
583        chmod("/proc/cmdline", 0440);
584        gid_t groups[] = { AID_READPROC };
585        setgroups(arraysize(groups), groups);
586        mount("sysfs", "/sys", "sysfs", 0, NULL);
587        mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);
588
589        mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11));
590
591        if constexpr (WORLD_WRITABLE_KMSG) {
592            mknod("/dev/kmsg_debug", S_IFCHR | 0622, makedev(1, 11));
593        }
594				 //mknod mknod用于创建Linux中的设备文件
					 path:设备所在目录
					 mode:指定设备的类型和读写访问标志
					 可能的类型
					 S_IFMT	type of file ,文件类型掩码
					 S_IFREG	regular 普通文件
					 S_IFBLK	block special 块设备文件
					 S_IFDIR	directory 目录文件
					 S_IFCHR	character special 字符设备文件
					 S_IFIFO	fifo 管道文件
					 S_IFNAM	special named file 特殊文件
					 S_IFLNK	symbolic link 链接文件
595        mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8));
596        mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9));
597
598        // Mount staging areas for devices managed by vold
599        // See storage config details at http://source.android.com/devices/storage/
           //mount属于Linux系统调用
					 mount 命令参数:
					 source:将要挂上的文件系统,通常是一个设备名。
					 target:文件系统所要挂载的目标目录。
					 filesystemtype:文件系统的类型,可以是"ext2","msdos","proc","ntfs","iso9660"。
600        mount("tmpfs", "/mnt", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
601              "mode=0755,uid=0,gid=1000");
602        // /mnt/vendor is used to mount vendor-specific partitions that can not be
603        // part of the vendor partition, e.g. because they are mounted read-write.
					 //mkdir也是Linux系统调用,作用是创建目录,第一个参数是目录路径,第二个是读写权限
604        mkdir("/mnt/vendor", 0755);
605
606        // Now that tmpfs is mounted on /dev and we have /dev/kmsg, we can actually
607        // talk to the outside world...
608        InitKernelLogging(argv);
609
610        LOG(INFO) << "init first stage started!";
611
612        if (!DoFirstStageMount()) {
613            LOG(FATAL) << "Failed to mount required partitions early ...";
614        }
615
616        SetInitAvbVersionInRecovery();
617
618        // Enable seccomp if global boot option was passed (otherwise it is enabled in zygote).
619        global_seccomp();
620
621        // Set up SELinux, loading the SELinux policy.
622        SelinuxSetupKernelLogging();
623        SelinuxInitialize();
624
625        // We're in the kernel domain, so re-exec init to transition to the init domain now
626        // that the SELinux policy has been loaded.
627        if (selinux_android_restorecon("/init", 0) == -1) {
628            PLOG(FATAL) << "restorecon failed of /init failed";
629        }
630				 //设置第二阶段的变量
631        setenv("INIT_SECOND_STAGE", "true", 1);
632
633        static constexpr uint32_t kNanosecondsPerMillisecond = 1e6;
634        uint64_t start_ms = start_time.time_since_epoch().count() / kNanosecondsPerMillisecond;
635        setenv("INIT_STARTED_AT", std::to_string(start_ms).c_str(), 1);
636
637        char* path = argv[0];
638        char* args[] = { path, nullptr };
					 //重新执行main函数, exec是函数族提供了一个在进程中执行另一个进程的方法
639        execv(path, args);
640
641        // execv() only returns if an error happened, in which case we
642        // panic and never fall through this conditional.
643        PLOG(FATAL) << "execv(\"" << path << "\") failed";
644    }
645
646    // At this point we're in the second stage of init.
       把log写入dev/kmsg中
647    InitKernelLogging(argv);
648    LOG(INFO) << "init second stage started!";
649
650    // Set up a session keyring that all processes will have access to. It
651    // will hold things like FBE encryption keys. No process should override
652    // its session keyring.
653    keyctl_get_keyring_ID(KEY_SPEC_SESSION_KEYRING, 1);
654
655    // Indicate that booting is in progress to background fw loaders, etc.
656    close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
657
658    property_init();
659
660    // If arguments are passed both on the command line and in DT,
661    // properties set in DT always have priority over the command-line ones.
662    process_kernel_dt();
663    process_kernel_cmdline();
664
665    // Propagate the kernel variables to internal variables
666    // used by init as well as the current required properties.
667    export_kernel_boot_props();
668
669    // Make the time that init started available for bootstat to log.
670    property_set("ro.boottime.init", getenv("INIT_STARTED_AT"));
671    property_set("ro.boottime.init.selinux", getenv("INIT_SELINUX_TOOK"));
672
673    // Set libavb version for Framework-only OTA match in Treble build.
674    const char* avb_version = getenv("INIT_AVB_VERSION");
675    if (avb_version) property_set("ro.boot.avb_version", avb_version);
676
			 //清除所设置的变量
677    // Clean up our environment.
678    unsetenv("INIT_SECOND_STAGE");
679    unsetenv("INIT_STARTED_AT");
680    unsetenv("INIT_SELINUX_TOOK");
681    unsetenv("INIT_AVB_VERSION");
682
683    // Now set up SELinux for second stage.
684    SelinuxSetupKernelLogging();
685    SelabelInitialize();
686    SelinuxRestoreContext();
687
688    epoll_fd = epoll_create1(EPOLL_CLOEXEC);
689    if (epoll_fd == -1) {
690        PLOG(FATAL) << "epoll_create1 failed";
691    }
692
693    sigchld_handler_init();
694
695    if (!IsRebootCapable()) {
696        // If init does not have the CAP_SYS_BOOT capability, it is running in a container.
697        // In that case, receiving SIGTERM will cause the system to shut down.
698        InstallSigtermHandler();
699    }
700
701    property_load_boot_defaults();
702    export_oem_lock_status();
703    start_property_service();
704    set_usb_controller();
705
706    const BuiltinFunctionMap function_map;
707    Action::set_function_map(&function_map);
708
709    subcontexts = InitializeSubcontexts();
710
711    ActionManager& am = ActionManager::GetInstance();
712    ServiceList& sm = ServiceList::GetInstance();
713
			 //解析init文件,init.rc文件,然后根据文件里面的配置来启动进程native或者service
			 //一般情况下这些service是daemon 也就是守护进程
714    LoadBootScripts(am, sm);
715
716    // Turning this on and letting the INFO logging be discarded adds 0.2s to
717    // Nexus 9 boot time, so it's disabled by default.
718    if (false) DumpState();
719
720    am.QueueEventTrigger("early-init");
721
722    // Queue an action that waits for coldboot done so we know ueventd has set up all of /dev...
723    am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done");
724    // ... so that we can start queuing up actions that require stuff from /dev.
725    am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");
726    am.QueueBuiltinAction(SetMmapRndBitsAction, "SetMmapRndBits");
727    am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict");
728    am.QueueBuiltinAction(keychord_init_action, "keychord_init");
729    am.QueueBuiltinAction(console_init_action, "console_init");
730
731    // Trigger all the boot actions to get us started.
732    am.QueueEventTrigger("init");
733
734    // Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random
735    // wasn't ready immediately after wait_for_coldboot_done
736    am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");
737
738    // Don't mount filesystems or start core system services in charger mode.
739    std::string bootmode = GetProperty("ro.bootmode", "");
740    if (bootmode == "charger") {
741        am.QueueEventTrigger("charger");
742    } else {
743        am.QueueEventTrigger("late-init");
744    }
745
746    // Run all property triggers based on current state of the properties.
747    am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers");
748
       //进入loop循环,保证init进程不会退出
749    while (true) {
750        // By default, sleep until something happens.
751        int epoll_timeout_ms = -1;
752
753        if (do_shutdown && !shutting_down) {
754            do_shutdown = false;
755            if (HandlePowerctlMessage(shutdown_command)) {
756                shutting_down = true;
757            }
758        }
759
760        if (!(waiting_for_prop || Service::is_exec_service_running())) {
761            am.ExecuteOneCommand();
762        }
763        if (!(waiting_for_prop || Service::is_exec_service_running())) {
764            if (!shutting_down) {
765                auto next_process_restart_time = RestartProcesses();
766
767                // If there's a process that needs restarting, wake up in time for that.
768                if (next_process_restart_time) {
769                    epoll_timeout_ms = std::chrono::ceil<std::chrono::milliseconds>(
770                                           *next_process_restart_time - boot_clock::now())
771                                           .count();
772                    if (epoll_timeout_ms < 0) epoll_timeout_ms = 0;
773                }
774            }
775
776            // If there's more work to do, wake up again immediately.
777            if (am.HasMoreCommands()) epoll_timeout_ms = 0;
778        }
779
780        epoll_event ev;
781        int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, epoll_timeout_ms));
782        if (nr == -1) {
783            PLOG(ERROR) << "epoll_wait failed";
784        } else if (nr == 1) {
785            ((void (*)()) ev.data.ptr)();
786        }
787    }
788
789    return 0;
790}
791
792}  // namespace init
793}  // namesp
#####
最近在做HIDL相关的工作,HIDL暂且不谈, 现在我编译完HIDL的接口之后会给上层App
提供一个jar包,以供App来调用HIDL接口. 当时我的想法很简单,我编译完之后用studio来
引入jar包。然后我就可以美滋滋的调用了.
熟悉的在out/target/…目录下找到生成的jar包.add library. 在类里面直接引用jar包 
里面的方法. 走起. run。。。。
