笔记:Zygote和SystemServer进程启动过程
简述
Android设备启动过程中,先是Linux内核加载完,接着Android中的第一个进程init启动,它会启动一些需要开机启动的进程。
Zygote就是进程init启动起来的。Android中所有应用程序进程,以及运行系统关键服务的System进程都是由Zygote创建的。它通过复制自身的形式创建其它进程。Zygote在启动时会在内部创建一个虚拟机实例,因此,通过复制Zygote得到的其它应用程序进程和System进程都可以快速地在内部获得一个虚拟机地拷贝。Zygote启动完成后就立即将System进程启动,以便各种关键服务被启动运行。
Zygote的启动
它以服务的形式被启动。
创建虚拟机
进程内创建一个虚拟机实例,并注册一系列JNI方法。
frameworks/base/core/jni/AndroidRuntime.cpp
/* start the virtual machine. */
startVM(&mJavaVM, &env);
/* Register android functions. */
startReg(env);
接下来执行“com.android.internal.os.ZygoteInit”Java类的main方法继续执行启动。
ZygoteInit.main
package com.android.internal.os;
import android.net.LocalServerSocket;
...
public class ZygoteInit {
private static LocalServerSocket sServerSocket;
public static void main(String argv[]) {
...
registerZygoteSocket();
...
if (argv[1].equals("true")) {
startSystemServer();
} else if (!argv[1].equals("false")) {
throw new RuntimeException(argv[0] + USAGE_STRING);
}
...
if (ZYGOTE_FORK_MODE) {
runForkMode();
} else {
runSelectLoopMode();
}
...
closeServerSocket();
...
}
}
创建Socket
Zygote调用registerZygoteSocket();
创建一个LocalServerSocket sServerSocket
的Server端Socket,等待以后运行在System进程中的服务ActivityManagerService创建的Client端Socket连接,然后通过Socket进程间通信通知Zygote创建新的应用程序进程。
创建System进程
/**
* Prepare the arguments and fork for the system server process.
*/
private static boolean startSystemServer()
throws MethodAndArgsCaller, RuntimeException {
/* Hardcoded command line to start the system server */
String args[] = new String[] {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006",
"--capabilities=130104352,130104352",
"--rlimit=8,",
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};
...
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, debugFlags, rlimits,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
handleSystemServerProcess(parsedArgs);
}
return true;
}
变量args保存启动System进程的参数。
Zygote.forkSystemServer()复制当前进程来创建子进程。
handleSystemServerProcess()继续处理System进程的启动。
轮询等待AMS请求创建App进程
private static void runSelectLoopMode() throws MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList();
ArrayList<ZygoteConnection> peers = new ArrayList();
FileDescriptor[] fdArray = new FileDescriptor[4];
fds.add(sServerSocket.getFileDescriptor());
peers.add(null);
while (true) {
...
try {
fdArray = fds.toArray(fdArray);
index = selectReadable(fdArray);
} catch (IOException ex) {
throw new RuntimeException("Error in select()", ex);
}
if (index < 0) {
throw new RuntimeException("Error in select()");
} else if (index == 0) {
ZygoteConnection newPeer = acceptCommandPeer();
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
boolean done;
done = peers.get(index).runOnce();
if (done) {
peers.remove(index);
fds.remove(index);
}
}
}
}
/**
* Waits for and accepts a single command connection. Throws
* RuntimeException on failure.
*/
private static ZygoteConnection acceptCommandPeer() {
try {
return new ZygoteConnection(sServerSocket.accept());
} catch (IOException ex) {
throw new RuntimeException(
"IOException during accept()", ex);
}
}
无限循环,等待来自AMS创建的Socket连接。
sServerSocket在fds[0]位置。
每当accept()返回一个连接后,将对应此连接的newPeer.getFileDesciptor()套接字描述添加到fds(第0位置后),下一次读取到数据时,若在fds[0]以后的,说明是前面的newPeer连接收到的AMS的创建新应用程序进程的请求。
runOnce()用来处理AMS创建新应用程序进程的请求。
System进程的启动
ZygoteInit.handleSystemServerProcess()执行System进程的启动操作。
ZygoteInit.handleSystemServerProcess()
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
closeServerSocket();
/*
* Pass the remaining arguments to SystemServer.
* "--nice-name=system_server com.android.server.SystemServer"
*/
RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
/* should never reach here */
}
Zygote复制自身创建的子进程做为System进程,这样它得到了Zygote的Server Socket,但是用不到,所以第一句closeServerSocket()
关闭此套接字。
RuntimeInit.zygoteInit
package com.android.internal.os;
public class RuntimeInit {
public static final void zygoteInit(String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
...
commonInit();
zygoteInitNative();
...
// Remaining arguments are passed to the start class's static main
String startClass = argv[curArg++];
String[] startArgs = new String[argv.length - curArg];
System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
invokeStaticMain(startClass, startArgs);
}
}
zygoteInitNative()在System进程中启动一个Binder线程池。
RuntimeInit.invokeStaticMain()静态方法调用"com.android.server.SystemServer"
的main方法。
SystemServer.main
传递调用native方法init1():
class SystemServer {
/**
* This method is called from Zygote to initialize the system. This will cause the native
* services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
* up into init2() to start the Android services.
*/
native public static void init1(String[] args);
}
init1()的工作:
注册Service Manager的死亡通知:调用binderDied()。System进程执行kill结束自己。
创建SurfaceFlinger、和SensorService两个服务。
返回SystemServer.init2()继续启动java语言开发的系统服务。
SystemServer.init2
public static final void init2() {
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}
ServerThread继承自Thread。
ServerThread.run
class ServerThread extends Thread {
@Override
public void run() {
Looper.prepare();
...
// Critical services...
try {
...
Slog.i(TAG, "Activity Manager");
context = ActivityManagerService.main(factoryTest);
...
Slog.i(TAG, "Package Manager");
pm = PackageManagerService.main(context,
factoryTest != SystemServer.FACTORY_TEST_OFF);
...
Slog.i(TAG, "Content Manager");
ContentService.main(context,
factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL);
...
Slog.i(TAG, "Window Manager");
wm = WindowManagerService.main(context, power,
factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
...
((ActivityManagerService)ServiceManager.getService("activity"))
.setWindowManager(wm);
...
} catch (RuntimeException e) {
Slog.e("System", "Failure starting core service", e);
}
...
Looper.loop();
Slog.d(TAG, "System ServerThread is exiting!");
}
}
启动各个Service然后注册到ServiceManager。
各个服务都使用Binder和其它服务使用者进程进行就行交互。
(本文使用Atom编写)