android8.1启动过程 SystemServer
Posted we1less
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android8.1启动过程 SystemServer相关的知识,希望对你有一定的参考价值。
本文承接上一篇文章https://blog.csdn.net/we1less/article/details/116325856?spm=1001.2014.3001.5501
SystemServer进程主要用于创建系统服务,AMS、WMS、PMS都是由它来创建的
在上一篇说道启动systemserver
启动systemserver AOSP/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}
forkSystemServer
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
...
/* Hardcoded command line to start the system server */
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}
【1】ZygoteConnection.Arguments(args); AOSP/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java 里面的一个静态内部类 它将上述String数组中的参数传递进去
class ZygoteConnection {
private static final String TAG = "Zygote";
...
static class Arguments {
...
Arguments(String args[]) throws IllegalArgumentException {
parseArgs(args);
}
...
}
}
parseArgs 传递的参数就是
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"com.android.server.SystemServer",
};
接下类进入循环 根据每个字符串进行参数配置 直到字符串中不存在任何匹配后跳出
由parseArgs可以看出 因为参数字符串中并未出现 --preload-default 所以代码进入
remainingArgs = new String[args.length - curArg];
System.arraycopy(args, curArg, remainingArgs, 0, remainingArgs.length);
arraycopy将args中剩余的参数拷贝到remainingArgs 由程序可知剩余参数为 "com.android.server.SystemServer"
private void parseArgs(String args[])
throws IllegalArgumentException {
int curArg = 0;
boolean seenRuntimeArgs = false;
for ( /* curArg */ ; curArg < args.length; curArg++) {
String arg = args[curArg];
if (arg.equals("--")) {
curArg++;
break;
} else if (arg.startsWith("--setuid=")) {
if (uidSpecified) {
throw new IllegalArgumentException(
"Duplicate arg specified");
}
uidSpecified = true;
uid = Integer.parseInt(
arg.substring(arg.indexOf('=') + 1));
} else if (arg.startsWith("--setgid=")) {
if (gidSpecified) {
throw new IllegalArgumentException(
"Duplicate arg specified");
}
gidSpecified = true;
gid = Integer.parseInt(
arg.substring(arg.indexOf('=') + 1));
...
} else if (arg.equals("--preload-default")) {
preloadDefault = true;
} else {
break;
}
}
if (abiListQuery) {
if (args.length - curArg > 0) {
throw new IllegalArgumentException("Unexpected arguments after --query-abi-list.");
}
} else if (preloadPackage != null) {
if (args.length - curArg > 0) {
throw new IllegalArgumentException(
"Unexpected arguments after --preload-package.");
}
} else if (!preloadDefault) {
if (!seenRuntimeArgs) {
throw new IllegalArgumentException("Unexpected argument : " + args[curArg]);
}
remainingArgs = new String[args.length - curArg];
System.arraycopy(args, curArg, remainingArgs, 0, remainingArgs.length);
}
}
}
【2】 forkSystemServer 上一篇也讲到主要是调用fork函数进行进程复制 在子进程中返回的pid为0 因为是子进程所以不需要Zrgote的ServerSocket所以将这个关掉
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
handleSystemServerProcess 参数为解析出来的对象
Os.getenv("SYSTEMSERVERCLASSPATH") 得出来的字符串
generic_x86_64:/ # env
...
SYSTEMSERVERCLASSPATH=/system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar:/system/framework/com.android.location.provider.jar
可以看到get dalvik.vm.profilesystemserver 返回为空
127|generic_x86_64:/ # getprop dalvik.vm.profilesystemserver
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
...
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
if (systemServerClasspath != null) {
performSystemServerDexOpt(systemServerClasspath);
// Capturing profiles is only supported for debug or eng builds since selinux normally
// prevents it.
boolean profileSystemServer = SystemProperties.getBoolean(
"dalvik.vm.profilesystemserver", false);
if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
try {
File profileDir = Environment.getDataProfilesDePackageDirectory(
Process.SYSTEM_UID, "system_server");
File profile = new File(profileDir, "primary.prof");
profile.getParentFile().mkdirs();
profile.createNewFile();
String[] codePaths = systemServerClasspath.split(":");
VMRuntime.registerAppInfo(profile.getPath(), codePaths);
} catch (Exception e) {
Log.wtf(TAG, "Failed to set up system server profile", e);
}
}
}
if (parsedArgs.invokeWith != null) {
String[] args = parsedArgs.remainingArgs;
// If we have a non-null system server class path, we'll have to duplicate the
// existing arguments and append the classpath to it. ART will handle the classpath
// correctly when we exec a new process.
if (systemServerClasspath != null) {
String[] amendedArgs = new String[args.length + 2];
amendedArgs[0] = "-cp";
amendedArgs[1] = systemServerClasspath;
System.arraycopy(args, 0, amendedArgs, 2, args.length);
args = amendedArgs;
}
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(), null, args);
throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
/*
* Pass the remaining arguments to SystemServer.
*/
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
/* should never reach here */
}
if (parsedArgs.invokeWith != null) 这块因为当初传递参数并没有 --invoke-with 选项所以为空 走else
else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
/*
* Pass the remaining arguments to SystemServer.
*/
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
ZygoteInit.zygoteInit AOSP/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
ZygoteInit.nativeZygoteInit(); 据此分析这块是调用了native层的方法 用来启动binder线程池 这样SystemServer进程就可以使用Binder与其他进程进行通信
nativeZygoteInit 是一个native方法所以应该找到它的jni文件 AOSP/frameworks/base/core/jni/AndroidRuntime.cpp
int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
{
const JNINativeMethod methods[] = {
{ "nativeZygoteInit", "()V",
(void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
};
return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
methods, NELEM(methods));
}
这里面存在JNINativeMethod的对应函数映射表,可以直到这块调用了com_android_internal_os_ZygoteInit_nativeZygoteInit
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}
这块的gCurRuntime 是一个AndroidRuntime类型的指针 实际上最终调用的是它的子类AppRuntime ( class AppRuntime : public AndroidRuntime ) 它在app_main.cpp中定义
onZygoteInit AOSP/frameworks/base/cmds/app_process/app_main.cpp
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\\n");
proc->startThreadPool();
}
proc->startThreadPool(); 用来启动一个Binder线程池这样SystemServer进程就可以与其他进程进行通信了 看到这里我们知道ZygoteInit.nativeZygoteInit()主要是用来启动Binder线程池的
再回到AOSP/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java 继续分析
这个传递链条要从 说起
forkSystemServer
parsedArgs = new ZygoteConnection.Arguments(args); ---> remainingArgs = new String[args.length - curArg];
return handleSystemServerProcess(parsedArgs);
handleSystemServerProcess
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
这里面的parsedArgs.remainingArgs就是
"com.android.server.SystemServer"
RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader)
applicationInit AOSP/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java argv = "com.android.server.SystemServer"
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
...
// Remaining arguments are passed to the start class's static main
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
这里的 args.startClass 这里的 args.startClass 是由这句话封装而来的
Arguments args = new Arguments(argv);
Arguments(String args[]) throws IllegalArgumentException {
parseArgs(args);
}
parseArgs(args)
private void parseArgs(String args[])
throws IllegalArgumentException {
int curArg = 0;
for (; curArg < args.length; curArg++) {
String arg = args[curArg];
if (arg.equals("--")) {
curArg++;
break;
} else if (!arg.startsWith("--")) {
break;
}
}
if (curArg == args.length) {
throw new IllegalArgumentException("Missing classname argument to RuntimeInit!");
}
startClass = args[curArg++];
startArgs = new String[args.length - curArg];
System.arraycopy(args, curArg, startArgs, 0, startArgs.length);
}
最后startClass就为"com.android.server.SystemServer"
findStaticMain 没什么好说的这里面就是根据传递进来的参数进行反射调用main函数
private static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
/*
* This throw gets caught in ZygoteInit.main(), which responds
* by invoking the exception's run() method. This arrangement
* clears up all the stack frames that were required in setting
* up the process.
*/
return new MethodAndArgsCaller(m, argv);
}
这里的run方法里面就是反射调用
static class MethodAndArgsCaller implements Runnable {
...
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
...
}
}
这里就可以一直返回到
启动systemserver AOSP/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
就是本文开头的那部分代码调用了run方法就调用到了"com.android.server.SystemServer"的main方法
以上是关于android8.1启动过程 SystemServer的主要内容,如果未能解决你的问题,请参考以下文章