zygote和SystemServer的创建都在SecondStageMain阶段之后,到此阶段可以使用adb功能是可以正常使用了
在init.rc文件中会执行class_start main
来启动zygote,代码如下
# 启动zygote
on nonencrypted
class_start main
class_start late_start
这个main就是zygote,可以通过init.{zygote64}.rc来查看,代码如下
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
# class : 给服务指定一个类属
class main
priority -20
# user 在执行此服务之前先切换用户名。当前默认为root.
user root
# 切换组名
group root readproc reserved_disk
# 在/dev/socket/下创建一个socket,并传递创建的文件描述符fd给服务进程
# 其中type必须为dgram或stream,seqpacket.用户名和组名默认为0
socket zygote stream 660 root system
socket usap_pool_primary stream 660 root system
onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
# oneshot : 当此服务退出时不会自动重启.
# disabled:服务不会自动运行,必须显式地通过服务器来启动
# 据设备相关的关键服务,如果在4分钟内,此服务重复启动了4次,那么设备将会重启进入还原模式。
critical window=${zygote.critical_window.minute:-off} target=zygote-fatal
第二个参数就是服务进程的名称,通过class指定函数入口,并且位于:/system/bin/app_process64
,可以看到audioserver
,cameraserver
,media
,netd
,wificond
这些进程都隶属于zygote进程中,那就代表着
如果zygote挂了将会捕获到进程异常信号,将zygote进程进行重启,zygote main入口位置:
frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[])
{
...
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
...
// 如果zygote为true则代表即将创建该进程
// 如果startSystemServer为true则代表创建zygote时也会创建SystemServer
// 系统正常启动都会将这两个bool默认给到true
// 因为rc启动main后携带了--zygote和--start-system-server两个参数
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
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {// startSystemServer将为true
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()) {
...
} else {
// 进入创建zygote模式
// 创建/data/dalvik-cache,为后续会创建Dalvik虚拟机做准备
maybeCreateDalvikCache();
// 如果startSystemServer为true的话(默认为true)
// 将”start-system-server”放入启动的参数args
if (startSystemServer) {
args.add(String8("start-system-server"));
}
char prop[PROP_VALUE_MAX];
...
// 将所有剩余参数传递给args,例如application或tool或start-system-server或abi
// 这些启动参数将会传递到其他进程中,后续取出参数决定是否启动systemServer等操作
for (; i < argc; ++i) {
args.add(String8(argv[i]));
}
}
...
// zygote为真,将创建zygote,该args启动参数会包含start-system-server
// 调用runtime(AppRuntime)的start来启动zygote,将args传入,因为args包含了启动SystemServer的标志
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.");
}
}
以上代码就是启动zygote和将start-system-server放入启动参数,后续会读取参数启动SystemServer,继续分析一下runtime.start的com.android.internal.os.ZygoteInit"
进程,位于:frameworks/base/core/jni/AndroidRuntime.cpp
Vector<String8>& options就是包含了start-system-server的启动参数,通过app_main传递过来的
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
ALOGD(">>>>>> START %s uid %d <<<<<<\n",
className != NULL ? className : "(unknown)", getuid());
// 默认会启动SystemServer
static const String8 startSystemServer("start-system-server");
// 是否私有,如果SystemServer会被创建时,将会设置为私有
bool primary_zygote = false;
for (size_t i = 0; i < options.size(); ++i) {
// options就是传递过来的args,默认是包含了start-system-server
if (options[i] == startSystemServer) {
primary_zygote = true;
...
}
}
// 获取环境变量,这里第一次执行时默认为空,所以rootDir不存在
// = 将直接拿到/system作为rootDir并设置环境变量
const char* rootDir = getenv("ANDROID_ROOT");
if (rootDir == NULL) {
rootDir = "/system";
if (!hasDir("/system")) {
LOG_FATAL("No root directory specified, and /system does not exist.");
return;
}
setenv("ANDROID_ROOT", rootDir, 1);
}
...
/* start the virtual machine */
// 这里就开始启动虚拟机了
// JNI功能初始化
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
// 创建Dalvik虚拟机(这里-->DVM==JavaVM)
if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
return;
}
onVmCreated(env);
// 调用startReg函数用来为DVM注册JNI
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
jclass stringClass;
jobjectArray strArray;
jstring classNameStr;
// 通过反射拿到String类型
stringClass = env->FindClass("java/lang/String");
assert(stringClass != NULL);
//options就是app_main.cpp传递过来的args,包含了start-system-server
// 将options转换为array list对象
strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
assert(strArray != NULL);
//从app_main的main函数得知className为com.android.internal.os.ZygoteInit
classNameStr = env->NewStringUTF(className);
assert(classNameStr != NULL);
// 将数据转换给java类型的array 数组
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,该线程成为JVM的主进程,在VM退出之前不会返回
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
...
} else {
// 通过反射的方式,找到ZygoteInit的main函数
// 若获取到内容则执行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 {
// 通过JNI调用ZygoteInit的main函数,将args(strArray)传递到java层
// 因为ZygoteInit的main函数是Java编写的,因此需要通过JNI调用
// 所以这里继续跟到java层面:ZygoteInit.java
env->CallStaticVoidMethod(startClass, startMeth, strArray);
...
}
}
// 若执行到这里,则会结束zygote创建,关闭jvm
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");
}
可以看到以上的代码主要就是初始化了JNI(c++与Java交互)功能并创建并启动了JVM虚拟机,通过反射的方式去启动ZygoteInit.java的main方法,并将args参数(包含了是否启动SystemServer的参数)传递过去。
而JVM虚拟机进程就是:com.android.internal.os.ZygoteInit,而ZygoteInit进程位于:
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String[] argv) {
ZygoteServer zygoteServer = null;
// 标记zygote开始了
ZygoteHooks.startZygoteNoThreadCreation();
// 设置zygote自己的用户组pid
try {
Os.setpgid(0, 0);
} catch (ErrnoException ex) {
throw new RuntimeException("Failed to setpgid(0,0)", ex);
}
Runnable caller;
try {
// 读取系统是否已经启动完成
final long startTime = SystemClock.elapsedRealtime();
final boolean isRuntimeRestarted = "1".equals(
SystemProperties.get("sys.boot_completed"));
// 将行为写入trace log 标记目前正处于ZygoteInit阶段
String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
Trace.TRACE_TAG_DALVIK);
bootTimingsTraceLog.traceBegin("ZygoteInit");
RuntimeInit.preForkInit();
boolean startSystemServer = false;
// zygote进程就是一个socket,名称就叫zygote
String zygoteSocketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
for (int i = 1; i < argv.length; i++) {
// 从AndroidRuntime.cpp中传递上来,已经包含了start-system-server
// 所以startSystemServer = true
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} ...
}
// 为true,是私有zygote
final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);
...
// 记录的trace log,只记录到这个地方
bootTimingsTraceLog.traceEnd(); // ZygoteInit
// 初始化socket,从环境中获取套接字FD(ANDROID_SOCKET_zygote)
// 若获取不到则创建一个用于和systemServer通信的socket,当systemServer fork出来后socket进程将关闭
Zygote.initNativeState(isPrimaryZygote);
...
// 根据环境变量(LocalServerSocket)获取zygote文件描述符并重新创建一个socket,可以从这里看到zygote其实就是一个socket
// 这个name为”zygote”的Socket用来等待ActivityManagerService来请求Zygote来fork出新的应用程序进程
// 所以ActivityManagerService里启动应用程序(APP),都是由该zygote socket进行处理并fork出的子进程
zygoteServer = new ZygoteServer(isPrimaryZygote);
// 默认为true,将启动systemServer
if (startSystemServer) {
// zygote就是一个孵化器,所以这里直接fork(分叉,派生)出来SystemServer
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
...
// 让SystemServer子进程运行起来
if (r != null) {
r.run();
return;
}
}
Log.i(TAG, "Accepting command socket connections");
// 让zygote socket(注意不是systemServer zygote)循环运行
// 等待client进程来请求调用,请求创建子进程(fork出子进程(例如等待AMS的请求))
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
...
} finally {
if (zygoteServer != null) {
// 停止关于systemServer的socket,保留和AMS通信的socket
// 在initNativeState阶段创建了一个和systemServer通信的socket
// 接着拿到systemServer socket文件描述符重新创建了一个可以和AMS通信的socket(/dev/socket/zygote)
zygoteServer.closeServerSocket();
}
}
...
}
继续来看一下zygoteServer = new ZygoteServer(isPrimaryZygote);
ZygoteServer(boolean isPrimaryZygote) {
mUsapPoolEventFD = Zygote.getUsapPoolEventFD();
// 创建socket,名称为zygote,路径:/dev/sockets/zygote
if (isPrimaryZygote) {
mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);
...
}
...
}
static LocalServerSocket createManagedSocketFromInitSocket(String socketName) {
//文件描述符通过ANDROID_socket_环境变量共享
int fileDesc;
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
try {
String env = System.getenv(fullSocketName);
// 拿到文件描述符内容
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
throw new RuntimeException("Socket unset or invalid: " + fullSocketName, ex);
}
try {
// 生成文件描述符
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
return new LocalServerSocket(fd);
} catch (IOException ex) {
throw new RuntimeException(
"Error building socket from file descriptor: " + fileDesc, ex);
}
}
public LocalServerSocket(FileDescriptor fd) throws IOException
{
// 创建socket并持续监听(等待client来调用)
impl = new LocalSocketImpl(fd);
impl.listen(LISTEN_BACKLOG);
localAddress = impl.getSockAddress();
}
简单点来说就是创建了一个zygoye socket ,位于/dev/sockets/zygote,并调用了runSelectLoop让其循环运行,等待新进程发来的请求并进行连接zygoteServer.runSelectLoop(abiList)
然后fork出子应用程序进程
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> socketFDs = new ArrayList<>();
ArrayList<ZygoteConnection> peers = new ArrayList<>();
// 拿到socket的文件描述符
socketFDs.add(mZygoteSocket.getFileDescriptor());
...
while (true) {
...
if (pollReturnValue == 0) {
...
} else {
boolean usapPoolFDRead = false;
while (--pollIndex >= 0) {
if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
continue;
}
if (pollIndex == 0) {
// Zygote server socket
// acceptCommandPeer函数得到ZygoteConnection类并添加到Socket连接列表peers中,
// 接着将该ZygoteConnection的文件描述符添加到fd列表fds中,以便可以接收到ActivityManagerService发送过来的请求
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
socketFDs.add(newPeer.getFileDescriptor());
}
...
}
}
}
zygoteServer.runSelectLoop(abiList)持续等待进程来请求连接并fork出应用。
至此zygote socket已经启动完毕了,该socket会等待AMS进程发来的应用程序进程fork
继续看看systemServer是怎么被fork出来的
forkSystemServer(abiList, zygoteSocketName, zygoteServer);
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
...
// 创建args数组,这个数组用来保存启动SystemServer的启动参数,其中可以看出SystemServer进程的用户id和用户组id被设置为1000;
// 并且拥有用户组10011010,1018、1021、1032、30013010的权限;进程名为system_server;
// 启动的类名为com.android.server.SystemServer
String[] args = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
+ "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011,3012",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};
ZygoteArguments parsedArgs;
int pid;
try {
...
// 通过JNI形式去调用init进程下的fork函数,派生出systemServer进程
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
// pid == 0代表已经运行在子进程(SystemServer)上了
// 代表SystemServer创建成功,创建成功后会关闭该socket
if (pid == 0) {
...
// 销毁zygoteServer,保留和AMS通信的socket(runSelectLoop)
// 当SystemServer创建过后,zygoteServerSocket就没有用处了,进行关闭
zygoteServer.closeServerSocket();
// 处理 system server 进程初始化工作并启动SystemServer进程
// 并启动了一个 binder 线程池供system server 进程和其他进程通信使用
// 最后调用 RuntimeInit.applicationInit() 执行进程启动自身初始化工作
// applicationInit()最后是通过反射调用了 SystemServer.java 中的 main() 方法
return handleSystemServerProcess(parsedArgs);
}
return null;
}
Zygote.forkSystemServer
就是调用了底层的fork函数,不再进一步分析了。以上代码已知SystemServer子进程已经创建成功,将调用handleSystemServerProcess
来启动SystemServer.java的入口
handleSystemServerProcess会一直调用到RuntimeInit.java#findStaticMain方法中
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
// className:com.android.server.SystemServer
// 反射拿到SystemServer类
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
...
}
Method m;
try {
// 反射拿到SystemServer.java的main函数,并启动
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
...
} catch (SecurityException ex) {
...
}
...
return new MethodAndArgsCaller(m, argv);
}
可以看到handleSystemServerProcess下面的子方法去调用了com.android.server.SystemServer的main方法,至此SystemServer就创建和启动完毕了
至此SystemServer 已经创建并启动完毕了,那么SystemServer socket就会销毁并关闭
可以知道zygote是从rc中启动的,zygote本质上就是一个socket,不会关闭和销毁,而创建zygote时携带的StartSystemServer参数(必须携带此参数),会启动SystemServer子进程,SystemServer也是通过fork出来的,而底层和上层的交互是通过JNI实现的,SystemServer的启动是由zygoteInit通过反射的方式启动SystemServer的main方法
zygote启动时创建了服务端socket,用于SystemServer的创建,当SystemServer创建完成后则会关闭连接,期间已经调用了runSelectLoop来循环等待AMS及其他进程来请求连接,从而fork出应用程序的socket
服务端 socket会在SystemServer进程创建完毕后就会关闭,已经没有用处了,等待AMS发来连接将采用runSelectLoop方法进行循环等待