android8.0.0源码分析-zygote的启动

前提知识

PC主板上有一小段程序叫做BIOS,主板加电时它是第一个跑起来的程序。
功能:

  1. 硬件检测
  2. 初始化中断向量、设置寄存器等
  3. 从硬盘的开始扇区读取记录,引导操作系统

这个在android中叫Bootloader

系统加载

首先Android启动三种方式:
1.Bootloader交互式启动,此时可刷全部存储空间(和向硬盘中装系统一样、放入正确的路径/分区)
2.recover模式,从recovery.img镜像启动系统,可以修改部分存储,更新系统
3.Main System,从boot.img镜像启动系统

引导默认从Main System启动

系统启动

此时linux系统启动,设置缓存、被保护存储器、计划列表,加载驱动等系统任务。创建基本的程序运行环境,启动init进程。
android在init进程中启动/init.rc脚本来启动android系统
里面有一句import /init.${ro.zygote}.rc
在default.prop中定义ro.zygote=zygote64_32

/init.zygote64_32.rc中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
class main
priority -20
user root
group root readproc
socket zygote stream 660 root system socket关键字表示这个zygote进程需要一个名称为"zygote"的socket资源
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver 系列onrestart关键字表示这个zygote进程重启时需要执行的命令。
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload
class main
priority -20
user root
group root readproc
socket zygote_secondary stream 660 root system
onrestart restart zygote
writepid /dev/cpuset/foreground/tasks

创建名为zygote的进程,这个zygote进程要执行的程序是/system/bin/app_process64后面都是参数。
可见我的nexus_6p 8.1.0是启动/system/bin/app_process64来启动Zygote进程的。

android启动zygote

时序图:

app_main.cpp

/system/bin/app_process64的源码位于frameworks\base\cmds\app_process\app_main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
求参数块的大小
static size_t computeArgBlockSize(int argc, char* const argv[]) {
uintptr_t start = reinterpret_cast<uintptr_t>(argv[0]);
uintptr_t end = reinterpret_cast<uintptr_t>(argv[argc - 1]);
end += strlen(argv[argc - 1]) + 1;
return (end - start);
}
......
int main(int argc, char* const argv[])
{
.......
第一个参数的位置 ,参数块大小
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));//在栈中构建AppRuntime对象
// Process command line arguments
// ignore argv[0] 忽略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]));//向一开始构造的AppRuntime中加参数设置strdup是c中的字符串拷贝
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;
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;
}
}
//配置runtime.start参数
Vector<String8> args;
if (!className.isEmpty()) {
// We're not in zygote mode, the only argument we need to pass
// to RuntimeInit is the application argument.
//
// The Remainder of args get passed to startup class main(). Make
// copies of them before we overwrite them with the process name.
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 {
// We're in zygote mode.
maybeCreateDalvikCache();
if (startSystemServer) {
args.add(String8("start-system-server")); //启动SystemServer组件
}
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);
// In zygote mode, pass all remaining arguments to the zygote
// main() method.
for (; i < argc; ++i) {
args.add(String8(argv[i]));
}
}
if (!niceName.isEmpty()) {
runtime.setArgv0(niceName.string(), true /* setProcName */);
}
//调用runtime.start
if (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.");
}
}

主要干了:

  1. 处理分发各参数
  2. 创建AppRuntime对象
  3. runtime.start(“com.android.internal.os.ZygoteInit”, args, zygote);参:类名,设置,true

AppRuntime

定义于frameworks\base\cmds\app_process\app_main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class AppRuntime : public AndroidRuntime
{
public:
AppRuntime(char* argBlockStart, const size_t argBlockLength)
: AndroidRuntime(argBlockStart, argBlockLength)
, mClass(NULL)//调用父、赋值属性的简写
{
}
//将自己的 mClassName; mArgs; 设置
void setClassNameAndArgs(const String8& className, int argc, char * const *argv) {
mClassName = className;
for (int i = 0; i < argc; ++i) {
mArgs.add(String8(argv[i]));
}
}
virtual为虚函数供子类重写
virtual void onVmCreated(JNIEnv* env)
{
......
}
virtual void onStarted()
{
......
}
virtual void onZygoteInit()
{
......
}
virtual void onExit(int code)
{
......
}
String8 mClassName;
Vector<String8> mArgs;
jclass mClass;
};

为AndroidRuntime类的子类,构造中调用父,本身无start方法

AndroidRuntime类定义于frameworks\base\core\jni\AndroidRuntime.cpp
首先看下构造方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
......
static AndroidRuntime* gCurRuntime = NULL;
......
AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) :
mExitWithoutCleanup(false),
mArgBlockStart(argBlockStart),
mArgBlockLength(argBlockLength)
{
SkGraphics::Init();
// There is also a global font cache, but its budget is specified by
// SK_DEFAULT_FONT_CACHE_COUNT_LIMIT and SK_DEFAULT_FONT_CACHE_LIMIT.
// Pre-allocate enough space to hold a fair number of options.
mOptions.setCapacity(20);
assert(gCurRuntime == NULL); // one per process断言肯定是unll true没事
gCurRuntime = this; //一个进程只有一个该类实例。
}

为全局静态变量gCurRuntime赋值,该AndroidRuntime一个进程只会有一个。
注意构建函数的俩个参数:第一个为程序名的地址,但是在进程初始堆栈中argv[0]指向的正是初始栈的参数字串统一存储区域一开始的位置(由运行库传给main)
第二个参数为参数块大小。因此可以命名为 mArgBlockStart作为所有参数存于全局。

runtime.start(“com.android.internal.os.ZygoteInit”, args, zygote);执行的是AndroidRuntime类的start方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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' means runtime is obsolete and not run from
* init.rc anymore, so we print out the boot start event here.
*/
for (size_t i = 0; i < options.size(); ++i) {
if (options[i] == startSystemServer) {
/* track our progress through the boot sequence */
const int LOG_BOOT_PROGRESS_START = 3000;
LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
}
}
const char* rootDir = getenv("ANDROID_ROOT");
if (rootDir == NULL) {
rootDir = "/system";
if (!hasDir("/system")) {
LOG_FATAL("No root directory specified, and /android does not exist.");
return;
}
setenv("ANDROID_ROOT", rootDir, 1);
}
//const char* kernelHack = getenv("LD_ASSUME_KERNEL");
//ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);
/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL); 加载libart.so 导出artvm接口
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0) { //启动vm虚拟机
return;
}
onVmCreated(env); //AppRuntime是this的类型,所以执行的是AppRuntime的onVmCreate。
/*
* Register android functions.
*/
if (startReg(env) < 0) { //注册jni方法
ALOGE("Unable to register all android natives\n");
return;
}
/*
* We want to call main() with a String array with arguments in it.
* At present we have two arguments, the class name and an option string.
* Create an array to hold them.
*/
jclass stringClass;
jobjectArray strArray;
jstring classNameStr;
stringClass = env->FindClass("java/lang/String");
assert(stringClass != NULL);
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);
}
/*
* Start VM. This thread becomes the main thread of the VM, and will
* not return until the VM exits.
*/
char* slashClassName = toSlashClassName(className);
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
env->CallStaticVoidMethod(startClass, startMeth, strArray); //调用com.android.internal.os.ZygoteInit的main
#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");
}

Dalvik虚拟机和ART虚拟机都实现了三个用来抽象Java虚拟机的接口:

  1. JNI_GetDefaultJavaVMInitArgs – 获取虚拟机的默认初始化参数
  2. JNI_CreateJavaVM – 在进程中创建虚拟机实例 这里创建javavm与javaenv给予该进程虚拟机
  3. JNI_GetCreatedJavaVMs – 获取进程中创建的虚拟机实例

art通过替换libdvm.so为libart.so,开放公共接口,从而替换虚拟机,安装时dex->oat

libnativehelper/JniInvocation.cpp中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
bool JniInvocation::Init(const char* library)
dlopen加载libart.so
FindSymbol三个接口存储为指针
libart.so由属性persist.sys.dalvik.vm.lib定
extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
return JniInvocation::GetJniInvocation().JNI_CreateJavaVM(p_vm, p_env, vm_args);
}
获取之前创建的对象,调用其方法
jint JniInvocation::JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
return JNI_CreateJavaVM_(p_vm, p_env, vm_args);
}
继续调用存储好的指针

AndroidRuntime::start的过程:参:执行的java类com.android.internal.os.ZygoteInit,设置,true 。返回void

  1. jni_invocation.Init(NULL);加载libart.so,导出虚拟机接口
  2. startVm(&mJavaVM, &env, zygote)启动虚拟机,参:全局静态量JavaVM类型的地址,该函数内变量JNIEnv类型的地址,true。返回0成功
  3. startReg(env)注册jni方法,参:函数内变量JNIEnv*类型的地址。返回>=0表成功
  4. env->CallStaticVoidMethod(startClass, startMeth, strArray);通过jni调用com.android.internal.os.ZygoteInit的main。参:jclass类型的类对象,main方法id,参数数组

之后进入java层。

ZygoteInit

位于frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
参数为设置选选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer(); //ZygoteServer服务对象
// Mark zygote start. This ensures that thread creation will throw
// an error.
ZygoteHooks.startZygoteNoThreadCreation();
// Zygote goes into its own process group.
try {
Os.setpgid(0, 0);
} catch (ErrnoException ex) {
throw new RuntimeException("Failed to setpgid(0,0)", ex);
}
try {
// Report Zygote start time to tron unless it is a runtime restart
if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
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();
// Start profiling the zygote initialization.
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.");
}
zygoteServer.registerServerSocket(socketName);//ZygoteServer注册socket名字为zygote
// In some configurations, we avoid preloading resources and classes eagerly.
// In such cases, we will preload things prior to our first 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();
}
// Finish profiling the zygote initialization.
SamplingProfilerIntegration.writeZygoteSnapshot();
// Do an initial gc to clean up after startup
bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
gcAndFinalize();
bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
bootTimingsTraceLog.traceEnd(); // ZygoteInit
// Disable tracing so that forked processes do not inherit stale tracing tags from
// Zygote.
Trace.setTracingEnabled(false);
// Zygote process unmounts root storage spaces.
Zygote.nativeUnmountStorageOnInit();
// Set seccomp policy
Seccomp.setPolicy();
ZygoteHooks.stopZygoteNoThreadCreation();
if (startSystemServer) {
startSystemServer(abiList, socketName, zygoteServer); //开启系统服务,SystemServer由Zygote fork生成的,是zygote孵化出的第一个进程
}
Log.i(TAG, "Accepting command socket connections");
zygoteServer.runSelectLoop(abiList); //进入选择循环
zygoteServer.closeServerSocket();
} catch (Zygote.MethodAndArgsCaller caller) {
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
zygoteServer.closeServerSocket();
throw ex;
}
}

ZygoteInit.main的主要任务:

  1. 构造ZygoteServer对象
  2. zygoteServer.registerServerSocket(socketName);//ZygoteServer注册socket名字为zygote
  3. startSystemServer(abiList, socketName, zygoteServer);开启系统服务,第一个子进程。参:abilist,zy注册的socketName,zy开启的socketName对象。
  4. zygoteServer.runSelectLoop(abiList);进入选择循环,参为abilist

zygoteServer

位于frameworks\base\core\java\com\android\internal\os\ZygoteServer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/**
* Runs the zygote process's select loop. Accepts new connections as
* they happen, and reads commands from connections one spawn-request's
* worth at a time.
*
* @throws Zygote.MethodAndArgsCaller in a child process when a main()
* should be executed.
*/
void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
fds.add(mServerSocket.getFileDescriptor());
peers.add(null);
while (true) {
StructPollfd[] pollFds = new StructPollfd[fds.size()];
for (int i = 0; i < pollFds.length; ++i) {
pollFds[i] = new StructPollfd();
pollFds[i].fd = fds.get(i);
pollFds[i].events = (short) POLLIN;
}
try {
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
for (int i = pollFds.length - 1; i >= 0; --i) {
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
boolean done = peers.get(i).runOnce(this);//将当前的连接事件取出来执行
if (done) {
peers.remove(i);
fds.remove(i);
}
}
}
}
}

该函数进入循环模式监听处理消息

总结

init启动zygote进程,期间进行了native库加载、初始化jni环境、初始化bootclassloader、加载framework等操作,最后jni调用启动zygote。
zygote在java层主要做了俩件事:

  1. startSystemServer进程,该进程运行SystemServer服务,其启动WMS、PMS、AMS等众多系统服务
  2. 进入loop监听socket,听从SystemServer发送的消息进行分裂。