init
进程是 Android 系统中用户空间的第一个进程,进程号为 1。作为第一个进程,它被赋予了很多重要的职责,比如创建 Zygote
进程和属性服务等。
init
进程由多个源文件共同组成,这些文件位于源码目录 system/core/init
中。
Android 系统启动的前几步
-
当电源接通时。引导芯片代码从预定义的地方(硬编码在 ROM)开始执行。加载引导程序 BootLoader 到 (内存)RAM 中,然后执行。
-
BootLoader 是在 Android 系统开始运行前的一个小程序(它不是 Android 的一部分)。BootLoader 是制造商放置锁定和限制的地方。BootLoader 分两个阶段执行。 在第一阶段,它检测外部 RAM 并加载程序。在第二阶段,为内核启动做准备,引导加载程序设置网络,内存等
-
Android 内核的启动方式与 Linux 内核类似。随着内核的启动,开始设置缓存,受保护的内存,调度和加载驱动程序。当内核完成系统设置时,它会在系统文件中查找 init 文件。
-
init 进程启动
- 创建和挂载启动所需的文件目录
- 初始化和启动属性服务
- 解析
init.rc
脚本,并启动 Zygote
进程
init 进程的入口
在 Android 内核加载完成后,它会执行 init 进程的入口函数 main
,main
函数中会解析 init.rc
配置文件到 Action Service 对象中,然后执行 Actions 中的命令。
init.rc
是按照 Android Init Language 语法编写的脚本。
在 init 进程在执行 main
方法时,会解析执行 /init.rc
脚本,init.rc
脚本中会 import
与 zygote 相关的 init.${ro.zygote}.rc
脚本:
ro.zygote 是一个编译期指定的属性值,可以为 zygote32、zygote64、zygote32_64、zygote64_32
init.rc 内容如下:
import /init.environ.rc
import /init.usb.rc
import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
import /init.usb.configfs.rc
import /init.${ro.zygote}.rc
init.zygote64.rc 内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main //指定服务的类名。 同一个类名中的所有服务可以一起启动或停止。 如果未通过 class 选项指定服务,则服务在类“default”中
priority -20 //调度服务进程的优先级。 该值必须在 [-20,19] 的范围内。默认优先级为 0
user root //所属用户
socket zygote stream 660 root system //创建一个名为 /dev/socket/name 的 UNIX 域 socket,并将其 fd 传递给已启动的进程
socket usap_pool_primary stream 660 root system
onrestart write /sys/power/state on //onrestart 表示在重启时执行的动作
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks //将进程id写入文件
|
进入 Java 世界
待配置文件解析完成之后,就会开始依次执行 Actions 里的命令,在 init.rc
中能看到有如下配置:
init.rc
on nonencrypted
class_start main // 执行 class_start 命令,参数为 main
class_start late_start
表示当 nonencrypted 事件发生时,就执行下面定义的命令 class_start main
等。
system/core/init/builtins.cpp 中每个命令对应的解析函数关系
1
2
3
4
5
6
7
8
9
10
11
12
|
const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
static const Map builtin_functions = {
...
{"class_reset", {1, 1, do_class_reset}},
{"class_restart", {1, 1, do_class_restart}},
{"class_start", {1, 1, do_class_start}},
...
{"write", {2, 2, do_write}},
};
return builtin_functions;
}
|
所以 class_start main
会执行 do_class_start
方法,并传递参数 main
:
1
2
3
4
5
|
static int do_class_start(const std::vector<std::string>& args) {
ServiceManager::GetInstance().ForEachServiceInClass(args[1], [] (Service* s) { s->StartIfNotDisabled(); });
// 循环执行 class name 匹配 args[1](这里是main) 的 Service 的 StartIfNotDisabled
return 0;
}
|
1
2
3
4
5
6
7
8
|
bool Service::StartIfNotDisabled() {
if (!(flags_ & SVC_DISABLED)) {
return Start();
} else {
flags_ |= SVC_DISABLED_START;
}
return true;
}
|
init.zygote64.rc 中配置的 zygote 服务的 class name 恰恰就是 main, 所以这里会执行在 zygote 配置的 Service 对象的 Start()
方法。
@startuml
Service -> Service: Start
Service -> Service: fork
note right: fork 进程,接下来的操作在子进程中
Service -> Service: ExpandArgsAndExecve
note right: 调用 execve 执行 zygote service 的程序\n system/bin/app_process64\n其对应源码为app_main.cpp
Service -> app_main.cpp: main
app_main.cpp -> AndroidRuntime: start("com.android.internal.os.ZygoteInit")
AndroidRuntime -> AndroidRuntime: startVM
note right: 启动 JVM
AndroidRuntime -> JNIEnv: CallStaticVoidMethod
note right: 调用 ZygoteInit 类的静态方法: main
JNIEnv -> ZygoteInit: main
@enduml
Service
的 Start()
会最终执行 zygote service 配置中的参数 system/bin/app_process64
程序, 其对应源码为app_main.cpp.
frameworks/base/cmds/app_process/app_main.cpp
app_main.cpp 的 main
方法接收的参数就是在 init.zygote64.rc
中配置的 --zygote --start-system-server
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
|
int main(int argc, char* const argv[]) {
//...
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;
}
}
//...
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.");
}
}
|
app_main.cpp
的 main
方法中会调用 AndroidRuntime
的 start
方法, 进而 startVM
启动 JVM, 然后通过 JNIEnv
调用 ZygoteInit
Java 类的静态方法 main
. 至此, 就从 cpp 世界进入了 java 世界.
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
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
|
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote) {
// className: com.android.internal.os.ZygoteInit
//...
// 启动 JVM
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
//...
/*
* 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.
* 创建一个 strArray 存放相关参数
*/
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.
*/
// com.android.internal.os.ZygoteInit 转变为 com/android/internal/os/ZygoteInit
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
} else {
// 获取 ZygoteInit 类的 static void main 方法
jmethodID startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
} else {
// 调用 main 方法
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
}
}
|
Zygote 进程启动
进入 Java 世界之后, 程序从 ZygoteInit
类的 main
开始运行.
主流程
@startuml
ZygoteInit -> ZygoteInit: main
ZygoteInit -> ZygoteServer: registerServerSocket
ZygoteInit -> ZygoteInit: preload
group 启动 SystemServer 进程
ZygoteInit -> Zygote: forkSystemServer
Zygote -> Zygote: nativeForkSystemServer
Zygote --> ZygoteInit: pid
ZygoteInit -> ZygoteServer: closeServerSocket
ZygoteInit -> ZygoteInit: handleSystemServerProcess
end
ZygoteInit -> ZygoteServer: runSelectLoop
ZygoteInit -> ZygoteServer: closeServerSocket
@enduml
ZygoteInit.java#main
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
|
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
//...
final Runnable caller;
try {
//...
// 创建一个 LocalServerSocket, 用来接收其他服务的请求. socketName 为 zygote
zygoteServer.registerServerSocket(socketName);
//...
if (startSystemServer) {
// 通过 fork 一个子进程来启动 System Server
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
// {@code r == null } 说明还是运行在父(zygote)进程
// {@code r != null } 说明运行在子进程(system_server)
if (r != null) {
r.run();
// 这里的 return 是让子进程(system_server)不执行下面的代码, zygote 进程中代码还是继续向下运行
return;
}
}
// 运行 Zygote 进程的循环来等待 AMS 的请求
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
throw ex;
} finally {
zygoteServer.closeServerSocket();
}
// 如果 caller != null, 说明在 zygote 进程中. 执行 runSelectLoop 返回的 Runnable
if (caller != null) {
caller.run();
}
}
|
registerServerSocket
创建 Zygote 接受事件的 Server Socket
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
void registerServerSocket(String socketName) {
if (mServerSocket == null) {
int fileDesc;
// 拼接 scoket name 为: ANDROID_SOCKET_zygote
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
try {
String env = System.getenv(fullSocketName);
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
throw new RuntimeException(fullSocketName + " unset or invalid", ex);
}
try {
// 创建文件描述符
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
// 创建 LocalServerSocket
mServerSocket = new LocalServerSocket(fd);
} catch (IOException ex) {
throw new RuntimeException("Error binding to local socket '" + fileDesc + "'", ex);
}
}
}
|
启动 SystemServer
通过调用 forSystemServer
启动 SystemServer 进程。
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
|
private static Runnable forkSystemServer(String abiList, String socketName, ZygoteServer zygoteServer) {
// ...
// 一些参数设置
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--nice-name=system_server",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
// fork 当前进程
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
if (pid == 0) {
// fork 成功之后, 在子进程中运行下面的代码
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
// 因为 SystemServer 用不到 Zygote 的 Server Socket, 所以关掉
zygoteServer.closeServerSocket();
// 在 SystemServer 进程做一些工作
return handleSystemServerProcess(parsedArgs);
}
// 父进程方法调用结束
return null;
}
|
handleSystemServerProcess
SystemServer 进程 fork 成功之后,在其进程做一些工作。比如:加载一些系统类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
//...
if (parsedArgs.mInvokeWith != null) {
//...
} else {
// 创建 PathClassLoader 作为系统 ClassLoader
createSystemServerClassLoader();
ClassLoader cl = sCachedSystemServerClassLoader;
if (cl != null) {
// 注入到 ContextClassLoader 中
Thread.currentThread().setContextClassLoader(cl);
}
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mRemainingArgs, cl);
}
}
|
zygoteInit
每个从 zygote 进程 fork 而来的进程都会执行 zygoteInit
方法。
1
2
3
4
5
6
7
8
9
10
|
public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
// 将System.out和System.err重定向到Android日志。
RuntimeInit.redirectLogStreams();
// 做一些公共的操作,比如:设置系统的 User-Agent
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}
|
applicationInit
1
2
3
4
5
6
7
8
9
|
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
VMRuntime.getRuntime().setDisabledCompatChanges(disabledCompatChanges);
final Arguments args = new Arguments(argv);
// 找到参数中 startClass 的 static main 方法
// 这里 startClass 是: com.android.server.SystemServer
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
|
1
2
3
4
5
6
7
8
9
10
11
|
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
// 获取目标类
cl = Class.forName(className, true, classLoader);
Method m;
// 获取目标类的 main 方法
m = cl.getMethod("main", new Class[] { String[].class });
// MethodAndArgsCaller 是一个 Runnable, run 时会执行方法 m, 并传递参数 argv
return new MethodAndArgsCaller(m, argv);
}
|
启动 SystemServer 的过程可以概述为:
- fork zygote 进程
- 关闭 zygote 的 server socket
- 在 fork 的进程中加载 com.android.server.SystemServer 类,并调用 SystemServer 类的 main 方法
runSelectLoop
在 zygote 进程, ZygoteServer
会继续执行 runSelectLoop
方法:
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
|
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
// 获取通过 registerServerSokcet 创建的 socket 的 FileDescriptor, 添加到 fd 列表 fds 中
fds.add(mServerSocket.getFileDescriptor());
peers.add(null);
// 无限循环
while (true) {
// 将 fds 中的信息转移到 pollFds 中
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;
// 设置 StructPollfd 等待的事件为 POLLIN
// POLLIN: 表示有数据可读
}
try {
// Linux poll 调用: 等待一组文件描述符中的一个准备好执行 I/O, -1 表示一直等待
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
// 从 pollFds 末尾开始遍历
for (int i = pollFds.length - 1; i >= 0; --i) {
if ((pollFds[i].revents & POLLIN) == 0) {
// revents: 实际发生的事件
// 如果实际发生的事件不为 POLLIN, 则跳过后面步骤
continue;
}
// i == 0: 表示是 mServerSocket 的 FileDescriptor 发生了 POLLIN 事件. 因为 mServerSocket 的 FileDescriptor 是在无限循环之前添加到 fds 中的, 其 index 一定为 0
if (i == 0) {
// 从 mServerSocket accept 一个客户端的 socket 连接, 封装为 ZygoteConnection
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
// 将客户端的 socket FileDescriptor 添加到 fds 中
fds.add(newPeer.getFileDesciptor());
} else {
// 能走到这里的 fd 都是客户端的 socket 的 fd
try {
ZygoteConnection connection = peers.get(i);
final Runnable command = connection.processOneCommand(this);
// processOneCommand 执行成功,最终返回一个 Runnable:
// ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, null /* classLoader */);
if (mIsForkChild) {
// mIsForkChild 在 processOneCommand 当 fork 成功之后会设置
// We're in the child. We should always have a command to run at this
// stage if processOneCommand hasn't called "exec".
if (command == null) {
throw new IllegalStateException("command == null");
}
return command;
//return 到 ZygoteInit#main 最下面的 caller
} else {
// fork 失败或者执行 processOneCommand 期间其他参数错误
// We're in the server - we should never have any commands to run.
if (command != null) {
throw new IllegalStateException("command != null");
}
// We don't know whether the remote side of the socket was closed or
// not until we attempt to read from it from processOneCommand. This shows up as
// a regular POLLIN event in our regular processing loop.
if (connection.isClosedByPeer()) {
connection.closeSocket();
peers.remove(i);
fds.remove(i);
}
}
} catch (Exception e) {
}
}
}
}
|
看完整体过程,init 进程的启动过程可以概要为:
- 解析 init.rc 脚本,执行 app_process 程序
- app_process 程序运行后会创建 Java VM
- Java VM 创建成功之后,会执行 Java 类 ZygoteInit 的 main 方法从而创建 ZygoteServerSocket、启动 SystemService
参考