参考文章
一、概述
简单梳理下Andorid启动流程。
一般操作系统启动流程如下图:
Android系统启动流程概览:
system_server服务启动流程
启动过程: Loader -> Kernel -> Native -> Framework -> App
1.1 Loader层
- Boot ROM: 当手机处于关机状态时,长按Power键开机,引导芯片开始从固化在ROM里的预设出代码开始执行,然后加载引导程序到RAM;
- Boot Loader:这是启动Android系统之前的引导程序,主要是检查RAM,初始化硬件参数等功能。
1.2 Kernel层
Kernel是指Android内核层,到这里才刚刚开始进入Android系统。
- 启动Kernel的swapper进程(pid=0):该进程又称为idle进程, 系统初始化过程Kernel由无到有开创的第一个进程, 用于初始化进程管理、内存管理,加载Display,Camera Driver,Binder Driver等相关工作;
- 启动kthreadd进程(pid=2):是Linux系统的内核进程,会创建内核工作线程kworkder,软中断线程ksoftirqd,thermal等内核守护进程。kthreadd进程是所有内核进程的鼻祖。
1.3 Native层
Native层主要包括init孵化来的用户空间的守护进程、HAL层以及开机动画等。启动init进程(pid=1),是Linux系统的用户进程,init进程是所有用户进程的鼻祖。
- init进程会孵化出ueventd、logd、healthd、installd、adbd、lmkd等用户守护进程;
- init进程还启动servicemanager(binder服务管家)、bootanim(开机动画)等重要服务
- init进程孵化出Zygote进程,Zygote进程是Android系统的第一个Java进程(即虚拟机进程),Zygote是所有Java进程的父进程,Zygote进程本身是由init进程孵化而来的。
1.4 Framework层
Zygote进程,是由init进程通过解析init.rc文件后fork生成的,Zygote进程主要包含:
1. 加载ZygoteInit类,注册Zygote Socket服务端套接字;
3. 加载虚拟机;
4. preloadClasses;
5. preloadResouces。System Server进程,是由Zygote进程fork而来,System Server是Zygote孵化的第一个进程,System Server负责启动和管理整个Java framework,包含ActivityManager,PowerManager等服务。
Media Server进程,是由init进程fork而来,负责启动和管理整个C++ framework,包含AudioFlinger,Camera Service,等服务。
##1.5 App层
- Zygote进程孵化出的第一个App进程是Launcher,这是用户看到的桌面App;
- Zygote进程还会创建Browser,Phone,Email等App进程,每个App至少运行在一个进程上。
- 所有的App进程都是由Zygote进程fork生成的。
##1.6 Syscall && JNI
- Native与Kernel之间有一层系统调用(SysCall)层
- 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部分组成:
- 动作(Actions)
- 命令(Commands)
- 服务(Services)
- 选项(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方法释放一些内