参考文章

  1. Android系统开篇

一、概述

简单梳理下Andorid启动流程。

一般操作系统启动流程如下图:

Android开机流程(一)-LMLPHP

Android系统启动流程概览:

Android开机流程(一)-LMLPHP
Android开机流程(一)-LMLPHP

system_server服务启动流程

启动过程:  Loader -> Kernel -> Native -> Framework -> App

1.1  Loader层

  1. Boot ROM: 当手机处于关机状态时,长按Power键开机,引导芯片开始从固化在ROM里的预设出代码开始执行,然后加载引导程序到RAM;
  2. Boot Loader:这是启动Android系统之前的引导程序,主要是检查RAM,初始化硬件参数等功能。

1.2  Kernel层

Kernel是指Android内核层,到这里才刚刚开始进入Android系统。

  1. 启动Kernel的swapper进程(pid=0):该进程又称为idle进程, 系统初始化过程Kernel由无到有开创的第一个进程, 用于初始化进程管理、内存管理,加载Display,Camera Driver,Binder Driver等相关工作;
  2. 启动kthreadd进程(pid=2):是Linux系统的内核进程,会创建内核工作线程kworkder,软中断线程ksoftirqd,thermal等内核守护进程。kthreadd进程是所有内核进程的鼻祖。

1.3  Native层

Native层主要包括init孵化来的用户空间的守护进程、HAL层以及开机动画等。启动init进程(pid=1),是Linux系统的用户进程,init进程是所有用户进程的鼻祖。

  1. init进程会孵化出ueventd、logd、healthd、installd、adbd、lmkd等用户守护进程;
  2. init进程还启动servicemanager(binder服务管家)、bootanim(开机动画)等重要服务
  3. init进程孵化出Zygote进程,Zygote进程是Android系统的第一个Java进程(即虚拟机进程),Zygote是所有Java进程的父进程,Zygote进程本身是由init进程孵化而来的。

1.4  Framework层

  1. Zygote进程,是由init进程通过解析init.rc文件后fork生成的,Zygote进程主要包含:
        1. 加载ZygoteInit类,注册Zygote Socket服务端套接字;
        3. 加载虚拟机;
        4. preloadClasses;
        5. preloadResouces。

  2. System Server进程,是由Zygote进程fork而来,System Server是Zygote孵化的第一个进程,System Server负责启动和管理整个Java framework,包含ActivityManager,PowerManager等服务。

  3. Media Server进程,是由init进程fork而来,负责启动和管理整个C++ framework,包含AudioFlinger,Camera Service,等服务。

##1.5 App层

  1. Zygote进程孵化出的第一个App进程是Launcher,这是用户看到的桌面App;
  2. Zygote进程还会创建Browser,Phone,Email等App进程,每个App至少运行在一个进程上。
  3. 所有的App进程都是由Zygote进程fork生成的。

##1.6 Syscall && JNI

  1. Native与Kernel之间有一层系统调用(SysCall)层
  2. Java层与Native(C/C++)层之间的纽带JNI

二、源码

Kernel中启动的第一个用户进程是init程序;而init会通过解析init.rc来启动zygote服务;而zygote又会进一步的启动SystemServer。在SystemServer中,Android会启动一系列的系统服务共用户调用。整个流程大致如此。

init进程, 启动的第一个用户进程,进程id 为1,init创建zygote进程,提供属性服务(property service);在这里会解析init.rc。

init.rc是由一种被称为“Android初始化语言”(Android Init Language,这里简称为AIL)的脚本写成的文件。这里先大致了解下AIL。

AIL由如下4部分组成:

  1. 动作(Actions)
  2. 命令(Commands)
  3. 服务(Services)
  4. 选项(Options)

这4部分都是面向行的代码,也就是说用回车换行符作为每一条语句的分隔符。而每一行的代码由多个符号(Tokens)表示,用#来注释。
AIL在编写时需要分成多个部分(Section),而每一部分的开头需要指定Actions或Services。也就是说,每一个Actions或Services确定一个Section。而所有的Commands和Options只能属于最近定义的Section。如果Commands和Options在第一个Section之前被定义,它们将被忽略。
Actions和Services的名称必须唯一。如果有两个或多个Action或Service拥有同样的名称,那么init在执行它们时将抛出错误,并忽略这些Action和Service。写法如下:

on <trigger>
   <command>
   <command>
   <command>

如下:

on boot
    ifup lo
    hostname localhost
    domainname localdomain

关键字on后接的就是Section,接下来就是每行一条的command。
重点关注下: class name,其功能是指定一个名为name的服务类。所有同一类的服务可以同时启动和停止。如果不指定name,则默认为"default"类服务。

2.1 android/kernel/msm-4.9/init/main.c

kernel 启动 init 程序:

static int __ref kernel_init(void *unused)
{
    int ret;
    // 2.1.1 挂载根文件系统并指定init路径
    kernel_init_freeable();
    if (ramdisk_execute_command) {
        // 2.1.2 执行 “/init” 程序
        ret = run_init_process(ramdisk_execute_command);
        if (!ret)
            return 0;
        pr_err("Failed to execute %s (error %d)\n",
              ramdisk_execute_command, ret);
    }
    ......
}

2.1.1 kernel_init_freeable

static noinline void __init kernel_init_freeable(void)
{
    // 等待直到 kthreadd 设置完毕
    wait_for_completion(&kthreadd_done);
    ......
    if (!ramdisk_execute_command)
        ramdisk_execute_command = "/init"; // 默认init路径,在根目录下
    // 挂载根文件系统
    if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
        ramdisk_execute_command = NULL;
        prepare_namespace();
    }
    integrity_load_keys();
    load_default_modules();
}

2.1.2 init 服务定义

Android.mk 编译文件位于 /system/core/init 目录,所以 /init 源文件是 /system/core/init/init.cpp 。

include $(CLEAR_VARS)
LOCAL_CPPFLAGS := $(init_cflags)
LOCAL_SRC_FILES:= \
    bootchart.cpp \
    builtins.cpp \
    devices.cpp \
    init.cpp \
    init_first_stage.cpp \
    keychords.cpp \
    property_service.cpp \
    reboot.cpp \
    signal_handler.cpp \
    ueventd.cpp \
    ueventd_parser.cpp \
    watchdogd.cpp \
LOCAL_MODULE:= init
LOCAL_C_INCLUDES += \
    system/core/mkbootimg

2.1.3 system/core/init/init.cpp:main

由.mk文件所知,Android init进程的入口文件在android/system/core/init/init.cpp中:

int main(int argc, char** argv) {
    // 这里会根据启动的init程序传入的参数决定运行的是什么。
    // init模块包含三个部分,分别有两个守护进程ueventd watchdogd。
    // 默认启动的才是init进程本身
    if (!strcmp(basename(argv[0]), "ueventd")) {
        return ueventd_main(argc, argv);
    }
    if (!strcmp(basename(argv[0]), "watchdogd")) {
        return watchdogd_main(argc, argv);
    }
    // REBOOT_BOOTLOADER_ON_PANIC是否定义由init模块的 .mk 决定
    // 只有userdebug eng 这两个版本会打开这个选项,user 版本没有。 
    // 主要作用,当init进程崩溃后,不是让内核崩溃,而是重启bootloader,让开发者容易定位问题。
    if (REBOOT_BOOTLOADER_ON_PANIC) {
        install_reboot_signal_handlers();// 主要作用将各种信号量,如SIGABRT,SIGABRT等的行为设置为SA_RESTART
    }
    add_environment("PATH", _PATH_DEFPATH);

    bool is_first_stage = (getenv("INIT_SECOND_STAGE") == nullptr);
    if (is_first_stage) {
        boot_clock::time_point start_time = boot_clock::now();
        // 清除屏蔽字(file mode creation mask),保证新建的目录的访问权限不受屏蔽字影响。
        umask(0);

        // 在initRamdisk上设置基本的文件系统,然后由rc文件设置剩余部分
        // initRamdisk 就是 RAM 创建的虚拟文件系统,之后挂载真实的文件系统
        // mpfs是一种虚拟内存文件系统,它会将所有的文件存储在虚拟内存中,如果将tmpfs文件系统卸载后,那么其下的所有的内容将不复存在。 
        mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
        mkdir("/dev/pts", 0755);
        mkdir("/dev/socket", 0755);
        // devpts文件系统为伪终端提供了一个标准接口,它的标准挂接点是/dev/ pts。只要pty的主复合设备/dev/ptmx被打开,就会在/dev/pts下动态的创建一个新的pty设备文件。
        mount("devpts", "/dev/pts", "devpts", 0, NULL);
        #define MAKE_STR(x) __STRING(x)
        // proc文件系统是一个非常重要的虚拟文件系统,它可以看作是内核内部数据结构的接口,通过它我们可以获得系统的信息,同时也能够在运行时修改特定的内核参数。
        mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
        chmod("/proc/cmdline", 0440);
        gid_t groups[] = { AID_READPROC };
        setgroups(arraysize(groups), groups);
        // 与proc文件系统类似,sysfs文件系统也是一个不占有任何磁盘空间的虚拟文件系统。它通常被挂接在/sys目录下。
        // sysfs文件系统是Linux2.6内核引入的,它把连接在系统上的设备和总线组织成为一个分级的文件,使得它们可以在用户空间存取。
        mount("sysfs", "/sys", "sysfs", 0, NULL);
        // 挂载SELinux文件系统
        mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);
        mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11));
        mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8));
        mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9));
        // 现在RAM已经挂载了存储设备
        InitKernelLogging(argv);
        LOG(INFO) << "init first stage started!";
        if (!DoFirstStageMount()) {
            LOG(ERROR) << "Failed to mount required partitions early ...";
            panic();
        }
        SetInitAvbVersionInRecovery();
        // 设置SELinux,加载SELinux策略
        selinux_initialize(true);
        if (restorecon("/init") == -1) {
            PLOG(ERROR) << "restorecon failed";
            security_failure();
        }
        setenv("INIT_SECOND_STAGE", "true", 1);
        static constexpr uint32_t kNanosecondsPerMillisecond = 1e6;
        uint64_t start_ms = start_time.time_since_epoch().count() / kNanosecondsPerMillisecond;
        setenv("INIT_STARTED_AT", StringPrintf("%" PRIu64, start_ms).c_str(), 1);
        char* path = argv[0];
        char* args[] = { path, nullptr };
        execv(path, args);
        PLOG(ERROR) << "execv(\"" << path << "\") failed";
        security_failure();
    }

    // At this point we're in the second stage of init.
    InitKernelLogging(argv);
    LOG(INFO) << "init second stage started!";
    keyctl(KEYCTL_GET_KEYRING_ID, KEY_SPEC_SESSION_KEYRING, 1);
    close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));

    property_init();//property初始化property,创建一块存储区域
    process_kernel_dt();
    process_kernel_cmdline();
    export_kernel_boot_props();
    property_set("ro.boottime.init", getenv("INIT_STARTED_AT"));
    property_set("ro.boottime.init.selinux", getenv("INIT_SELINUX_TOOK"));
    const char* avb_version = getenv("INIT_AVB_VERSION");
    if (avb_version) property_set("ro.boot.avb_version", avb_version);
    // 清理环境
    unsetenv("INIT_SECOND_STAGE");
    unsetenv("INIT_STARTED_AT");
    unsetenv("INIT_SELINUX_TOOK");
    unsetenv("INIT_AVB_VERSION");

    selinux_initialize(false);
    selinux_restore_context();
    epoll_fd = epoll_create1(EPOLL_CLOEXEC);
    if (epoll_fd == -1) {
        PLOG(ERROR) << "epoll_create1 failed";
        exit(1);
    }
    signal_handler_init();
    property_load_boot_defaults();//加载默认的property
    export_oem_lock_status();
    start_property_service();//开启property service
    set_usb_controller();
    const BuiltinFunctionMap function_map;
    Action::set_function_map(&function_map);
    // 准备解析init.rc文件
    Parser& parser = Parser::GetInstance();
    parser.AddSectionParser("service",std::make_unique<ServiceParser>());
    parser.AddSectionParser("on", std::make_unique<ActionParser>());
    parser.AddSectionParser("import", std::make_unique<ImportParser>());
    std::string bootscript = GetProperty("ro.boot.init_rc", "");
    if (bootscript.empty()) {
        parser.ParseConfig("/init.rc"); //解析init.rc文件,这个脚本里面包括启动Zygote进程命令
        parser.set_is_system_etc_init_loaded(
                parser.ParseConfig("/system/etc/init"));
        parser.set_is_vendor_etc_init_loaded(
                parser.ParseConfig("/vendor/etc/init"));
        parser.set_is_odm_etc_init_loaded(parser.ParseConfig("/odm/etc/init"));
    } else {
        parser.ParseConfig(bootscript);
        parser.set_is_system_etc_init_loaded(true);
        parser.set_is_vendor_etc_init_loaded(true);
        parser.set_is_odm_etc_init_loaded(true);
    }
    if (false) parser.DumpState();

    ActionManager& am = ActionManager::GetInstance();
    // QueueEventTrigger函数就是利用参数构造EventTrigger,然后加入到trigger_queue_中。
    // 添加触发器early-init,执行on early-init内容
    am.QueueEventTrigger("early-init");

    // QueueBuiltinAction函数中构造新的action加入到actions_中,第一个参数作为新建action携带cmd的执行函数;
    // 第二个参数既作为action的trigger name,也作为action携带cmd的参数。
     // 等待冷启动完毕
    am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done");
    // 从硬件RNG的设备文件/dev/hw_random中读取512字节并写到Linux RNG的设备文件/dev/urandom中。
    am.QueueBuiltinAction(MixHwrngIntoLinuxRngAction, "MixHwrngIntoLinuxRng");
    am.QueueBuiltinAction(SetMmapRndBitsAction, "SetMmapRndBits");
    am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict");
    // 初始化组合键监听模块
    am.QueueBuiltinAction(keychord_init_action, "keychord_init");
     // 显示开机画面
    am.QueueBuiltinAction(console_init_action, "console_init");
    // 添加触发器init,执行on init内容,主要包括创建/挂载一些目录,以及symlink等
    am.QueueEventTrigger("init");

    am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
    //这里做个判断,如果是充电的情况,先不开机,执行init.rc:charger
    //否则,执行init.rc:late-init
    std::string bootmode = GetProperty("ro.bootmode", "");
    if (bootmode == "charger") {
        am.QueueEventTrigger("charger");
    } else {
        am.QueueEventTrigger("late-init");
    }
    am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers");
    while (true) {
        int epoll_timeout_ms = -1;
        // 判断是否有事件处理
        if (!(waiting_for_prop || ServiceManager::GetInstance().IsWaitingForExec())) {
            am.ExecuteOneCommand(); // 依次执行每个action中携带的command对应的函数
        }
        if (!(waiting_for_prop || ServiceManager::GetInstance().IsWaitingForExec())) {
            restart_processes(); // 重启挂掉的进程
            // 存在待重启的进程,计算等待时间
            if (process_needs_restart_at != 0) {
                epoll_timeout_ms = (process_needs_restart_at - time(nullptr)) * 1000;
                if (epoll_timeout_ms < 0) epoll_timeout_ms = 0;
            }
            // 存在命令待执行,等待时间置零,立刻执行
            if (am.HasMoreCommands()) epoll_timeout_ms = 0;
        }
        epoll_event ev;
        // 没有事件等待 epoll_timeout_ms
        int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, epoll_timeout_ms));
        if (nr == -1) {
            PLOG(ERROR) << "epoll_wait failed";
        } else if (nr == 1) {
            // 有事件到来,执行对应处理函数
            // 根据上文知道,epoll句柄(即epoll_fd)主要监听子进程结束,及其它进程设置系统属性的请求。
            ((void (*)()) ev.data.ptr)();
        }
    }
    return 0;
}

2.2 启动Zygote进程

late-init:

# Mount filesystems and start core system services.
on late-init
    trigger early-fs
    #通过mount_all命令在init {{device} .rc中挂载fstab。
    #可选参数'--early'可以被指定为跳过'latemount'的条目。 
    #/system 和/vendor 必须安装在阶段fs的末尾,而/data是可选的。
    trigger fs

    #启动logd
    trigger post-fs

    #在init {$ Device} .rc中使用'--late'参数通过mount_all挂载fstab,以便仅使用'latemount'挂载条目
    trigger late-fs

    #现在我们可以挂载/数据。文件加密需要keymaster解密/数据,只有当系统属性存在时才能加载。
    trigger post-fs-data

    #这里启动Zygote进程,也就是第一个java进程
    #这里是Andoird O版本改变的地方,O以前Zygote进程并非在此,具体位置待查
    trigger zygote-start

    # 加载永久属性
    trigger load_persist_props_action

    # Remove a file to wake up anything waiting for firmware.
    trigger firmware_mounts_complete

    trigger early-boot
    #boot中启动core服务,core服务有ueventd、logd、healthd、sh、adbd、servicemanager、vold、SurfaceFlinger、bootanimation。
    trigger boot

上面trigger zygote-start:

2.3 app_main

目录:/frameworks/base/cmds/app_process/app_main.cpp
关于这个类怎么工作的,稍后研究,先关注Zygote进程的孵化过程:

int main(int argc, char* const argv[])
{
    if (!LOG_NDEBUG) {
      String8 argv_String;
      for (int i = 0; i < argc; ++i) {
        argv_String.append("\"");
        argv_String.append(argv[i]);
        argv_String.append("\" ");
      }
      ALOGV("app_process main with argv: %s", argv_String.string());
    }
    // 这里的AppRuntime继承了大名鼎鼎的AndroidRuntime
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    // 忽略参数 argv[0]
    argc--;
    argv++;

    const char* spaced_commands[] = { "-cp", "-classpath" };
    // Allow "spaced commands" to be succeeded by exactly 1 argument (regardless of -s).
    bool known_command = false;

    int i;
    for (i = 0; i < argc; i++) {
        if (known_command == true) {
          runtime.addOption(strdup(argv[i]));
          ALOGV("app_process main add known option '%s'", argv[i]);
          known_command = false;
          continue;
        }

        for (int j = 0;
            j < static_cast<int>(sizeof(spaced_commands) / sizeof(spaced_commands[0]));
            ++j) {
          if (strcmp(argv[i], spaced_commands[j]) == 0) {
            known_command = true;
            ALOGV("app_process main found known command '%s'", argv[i]);
          }
        }

        if (argv[i][0] != '-') {
            break;
        }
        if (argv[i][1] == '-' && argv[i][2] == 0) {
            ++i; // Skip --.
            break;
        }

        runtime.addOption(strdup(argv[i]));
        ALOGV("app_process main add option '%s'", argv[i]);
    }

    // Parse runtime arguments.  Stop at first unrecognized option.
    bool zygote = false;
    bool startSystemServer = false;
    bool application = false;
    String8 niceName;
    String8 className;

    ++i;  // Skip unused "parent dir" argument.
    while (i < argc) {
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true; // 标记启动zygote进程
            // 对于64位 ZYGOTE_NICE_NAME = zygote64 否则为 zygote
            niceName = ZYGOTE_NICE_NAME;
        } else if (strcmp(arg, "--start-system-server") == 0) {
            startSystemServer = true;
        } else if (strcmp(arg, "--application") == 0) {
            application = true;
        } else if (strncmp(arg, "--nice-name=", 12) == 0) {
            niceName.setTo(arg + 12);
        } else if (strncmp(arg, "--", 2) != 0) {
            className.setTo(arg);
            break;
        } else {
            --i;
            break;
        }
    }

    Vector<String8> args;
    if (!className.isEmpty()) {
        args.add(application ? String8("application") : String8("tool"));
        runtime.setClassNameAndArgs(className, argc - i, argv + i);

        if (!LOG_NDEBUG) {
          String8 restOfArgs;
          char* const* argv_new = argv + i;
          int argc_new = argc - i;
          for (int k = 0; k < argc_new; ++k) {
            restOfArgs.append("\"");
            restOfArgs.append(argv_new[k]);
            restOfArgs.append("\" ");
          }
          ALOGV("Class name = %s, args = %s", className.string(), restOfArgs.string());
        }
    } else {
        // 创建 /data/dalvik-cache路径
        maybeCreateDalvikCache();

        if (startSystemServer) {
            args.add(String8("start-system-server"));
        }

        char prop[PROP_VALUE_MAX];
        if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
            LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
                ABI_LIST_PROPERTY);
            return 11;
        }

        String8 abiFlag("--abi-list=");
        abiFlag.append(prop);
        args.add(abiFlag);

        // zygote模式下,将所有参数传给zygote.main()
        for (; i < argc; ++i) {
            args.add(String8(argv[i]));
        }
    }

    if (!niceName.isEmpty()) {
        runtime.setArgv0(niceName.string(), true /* setProcName */);
    }

    if (zygote) {
        // 2.3.1 启动AndroidRuntime和zygote进程
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    }
}

2.3.1 AppRuntime:AndroidRuntime.start

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
    ALOGD(">>>>>> START %s uid %d <<<<<<\n",
            className != NULL ? className : "(unknown)", getuid());
    static const String8 startSystemServer("start-system-server");

    // 'startSystemServer == true' 意味着运行时过时且并非从init.rc文件启动
    // 所以这里打印引导事件
    for (size_t i = 0; i < options.size(); ++i) {
        if (options[i] == startSystemServer) {
          const int LOG_BOOT_PROGRESS_START = 3000;
          LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,  ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
        }
    }
    // Android根目录
    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.");
            return;
        }
        setenv("ANDROID_ROOT", rootDir, 1);
    }
     // 启动虚拟机,详细后续分析虚拟机
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }
    onVmCreated(env);

    // 向JavaVM注册安卓原生函数(JNI)
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }

    // 将参数转成Java String类型的对象
    jclass stringClass;
    jobjectArray strArray;
    jstring classNameStr;
    stringClass = env->FindClass("java/lang/String");
    assert(stringClass != NULL);
    // 创建String数组
    strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
    assert(strArray != NULL);
    classNameStr = env->NewStringUTF(className);
    assert(classNameStr != NULL);
    env->SetObjectArrayElement(strArray, 0, classNameStr);
    for (size_t i = 0; i < options.size(); ++i) {
        jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
        assert(optionsStr != NULL);
        env->SetObjectArrayElement(strArray, i + 1, optionsStr);
    }

    // 启动JavaVM,本线程成为VM的主线程,一直运行直到VM退出
    // 这里的 className = "com.android.internal.os.ZygoteInit"
    // slashClassName = "com/android/internal/os/ZygoteInit"
    char* slashClassName = toSlashClassName(className);
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
    } else {
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
        } else {
            // 2.4 调用ZygoteInit.main方法!!!
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
            if (env->ExceptionCheck())
                threadExitUncaughtException(env);
#endif
        }
    }
    free(slashClassName);
    ALOGD("Shutting down VM\n");
    if (mJavaVM->DetachCurrentThread() != JNI_OK)
        ALOGW("Warning: unable to detach main thread\n");
    if (mJavaVM->DestroyJavaVM() != 0)
        ALOGW("Warning: VM did not shut down cleanly\n");
}

2.4 ZygoteInit.main

进入Zygote进程~~
目录:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

    public static void main(String argv[]) {
        ZygoteServer zygoteServer = new ZygoteServer();

        // 标记Zygote开始,启动无多线程模式,意味着在zygoteInit中新建线程系统挂掉 
        ZygoteHooks.startZygoteNoThreadCreation();
        try {
            Os.setpgid(0, 0); // 设置Zygote的pid,gid为0.
        } catch (ErrnoException ex) {
            throw new RuntimeException("Failed to setpgid(0,0)", ex);
        }
        try {
            if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
                // 在Event.log输出:boot_zygote_init+开机时间
                MetricsLogger.histogram(null, "boot_zygote_init",
                        (int) SystemClock.elapsedRealtime());
            }

            String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
            BootTimingsTraceLog bootTimingsTraceLog = new BootTimingsTraceLog(bootTimeTag,
                    Trace.TRACE_TAG_DALVIK);
            bootTimingsTraceLog.traceBegin("ZygoteInit");
            RuntimeInit.enableDdms();
            // 启动性能统计,默认关闭,persist.sys.profiler_ms属性控制(>0开启)
            SamplingProfilerIntegration.start();

            boolean startSystemServer = false;
            String socketName = "zygote";
            String abiList = null;
            boolean enableLazyPreload = false;
            for (int i = 1; i < argv.length; i++) {
                if ("start-system-server".equals(argv[i])) {
                    startSystemServer = true;
                } else if ("--enable-lazy-preload".equals(argv[i])) {
                    enableLazyPreload = true;
                } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                    abiList = argv[i].substring(ABI_LIST_ARG.length());
                } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                    socketName = argv[i].substring(SOCKET_NAME_ARG.length());
                } else {
                    throw new RuntimeException("Unknown command line argument: " + argv[i]);
                }
            }

            if (abiList == null) {
                throw new RuntimeException("No ABI list supplied.");
            }
            // 创建名为 ANDROID_SOCKET_zygote 的Socket接口
            zygoteServer.registerServerSocket(socketName);
            // 某些配置下,预加载资源和类会在第一次fork时进行
            if (!enableLazyPreload) {
                bootTimingsTraceLog.traceBegin("ZygotePreload");
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                    SystemClock.uptimeMillis());
                preload(bootTimingsTraceLog);
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                    SystemClock.uptimeMillis());
                bootTimingsTraceLog.traceEnd(); // ZygotePreload
            } else {
                Zygote.resetNicePriority();
            }
            SamplingProfilerIntegration.writeZygoteSnapshot();

            // 初始化gc
            bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
            gcAndFinalize();
            bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC

            bootTimingsTraceLog.traceEnd(); // ZygoteInit
            // 关闭trace以防止fork出的进程trace错误
            Trace.setTracingEnabled(false);

            // Zygote 进程卸载根存储空间,喵喵喵?
            // 大概是Zygote进程存在的唯一意义是用于fork进程,不涉及存储操作,为防止出错,索性使Zygote进程无法接触存储设备
            Zygote.nativeUnmountStorageOnInit();

            // 设置Android沙盒策略
            Seccomp.setPolicy();
            // 停止无多线程模式
            ZygoteHooks.stopZygoteNoThreadCreation();

            if (startSystemServer) {
                // 2.5 启动 SystemServer 进程
                startSystemServer(abiList, socketName, zygoteServer);
            }

            Log.i(TAG, "Accepting command socket connections");
            zygoteServer.runSelectLoop(abiList); // 2.4.1 无限循环监听Socket接口等待AMS请求创建应用进程

            zygoteServer.closeServerSocket();
        } catch (Zygote.MethodAndArgsCaller caller) {
            caller.run();
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            zygoteServer.closeServerSocket();
            throw ex;
        }
    }

首先调用registerZygoteSocket方法,创建一个socket接口,用来和ActivityManagerService通讯,然后调用preload方法预加载一些资源等;然后调用gcAndFinalize方法释放一些内

10-04 13:26