android 系统的熟悉少不了对开机流程研究。因此这里简略看一下开机流程。 并没有各个大佬的详细,勿喷。
一、涉及的类文件:
./base/services/java/com/android/server/SystemServer.java
./base/core/java/com/android/internal/os/ZygoteInit.java
./base/core/java/com/android/internal/os/Zygote.java
./base/cmds/app_process/app_main.cpp
./base/core/java/com/android/internal/os/RuntimeInit.java
framework/base/core/jni/AndroidRuntime.cpp
......
二、android开机流程简略图
Android系统的开机流程主要部分有下面几个,本篇文章主要是研究system server进程到启动服务阶段的源代码。
三,Zygote进程的启动
在.rc文件中脚本描述
在android 5.1.1的代码中,*.rc 有64和32位的区别,因此比之前的版本多了几个rc文件
./core/rootdir/init.trace.rc
./core/rootdir/init.zygote64_32.rc
./core/rootdir/init.rc
./core/rootdir/init.zygote64.rc
./core/rootdir/init.zygote32.rc
./core/rootdir/init.zygote32_64.rc
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
其中: service , class ,socket 等的含义。
上面的--zygot --start-system-server --socket-name = zygote 为参数配置。
上面的参数解析,在
./base/cmds/app_process/app_main.cpp main()
方法中完成、。
int main(int argc, char* const argv[])
{
......
// Parse runtime arguments. Stop at first unrecognized option.
//这里解析参数配置信息确定zygote 以及nicename等参数
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;
}
}
......
//这里设置process name 从配置信息我们可以看到,process name 为zygote
if (!niceName.isEmpty()) {
runtime.setArgv0(niceName.string());
set_process_name(niceName.string());
}
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args);
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args);
} else {
//参数配置错误
......
}
}
接下来在AndroidRuntime的start方法
framework/base/core/jni/AndroidRuntime.cpp
/*
* Start the Android runtime. This involves starting the virtual machine
* and calling the "static void main(String[] args)" method in the class
* named by "className".
*
* Passes the main function two arguments, the class name and the specified
* options string.
*/
void AndroidRuntime::start(const char* className, const Vector<String8>& options)
{
static const String8 startSystemServer("start-system-server");
......
创建根目录/system ...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);
JNIEnv* env;
if (startVm(&mJavaVM, &env) != 0) {
return;
}
onVmCreated(env);
注册JNI方法/*
* Register android functions.
*/
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
...... 封装className等参数信息
/*
* 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 {
重点在这里,接下来进入ZygoteInit.java的main方法//com.android.internal.os.ZygoteInit mainenv->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
free(slashClassName);
......
}
接下来在ZygoteInit.java中main方法
framework/base/core/java/com/android/internal/os/ZygoteInit.java
//fulairy
public static void main(String argv[]) {
try {
......
boolean startSystemServer = false;
String socketName = "zygote";
String abiList = null;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = 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)) { //SOCKET_NAME_ARG = --socket-name=
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.");
}
注册socket监听
registerZygoteSocket(socketName);
加载资源文件
preload(); 加载资源class,resource,library etc
触发垃圾回收
// Do an initial gc to clean up after startup
gc();
if (startSystemServer) {
startSystemServer(abiList, socketName);
}
runSelectLoop(abiList);
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
//MethodAndArgsCaller异常很重要
caller.run();
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
从后面的代码跟踪可以看到,startSystemServer会抛出MetthodAndArgsCaller异常,caller.run然后再去调用SystemServer的main方法。
三、system server 进程启动
由startSystemServer方法,
/**
* Prepare the arguments and fork for the system server process.
*/
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
long capabilities = posixCapabilitiesAsBits(
OsConstants.CAP_BLOCK_SUSPEND,
OsConstants.CAP_KILL,
OsConstants.CAP_NET_ADMIN,
OsConstants.CAP_NET_BIND_SERVICE,
OsConstants.CAP_NET_BROADCAST,
OsConstants.CAP_NET_RAW,
OsConstants.CAP_SYS_MODULE,
OsConstants.CAP_SYS_NICE,
OsConstants.CAP_SYS_RESOURCE,
OsConstants.CAP_SYS_TIME,
OsConstants.CAP_SYS_TTY_CONFIG
);
/* 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,1032,3001,3002,3003,3006,3007",
"--capabilities=" + capabilities + "," + capabilities,
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
//这里将参数封装为ZygoteConnection.Arguments 参数类型
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
/* Request to fork the system server process */
//为啥不直接把parsedArgs传递过去就完了....因为需要传递的信息只需要一部分,保证了程序安全性。
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);
}
接下来
handleSystemServerProcess(parsedArgs);
}
return true;
}
需要了解一下fork method
handleSystemServerProcess
/**
* Finish remaining work for the newly forked system server process.
*/
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
if (parsedArgs.invokeWith != null) {
......
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
Thread.currentThread().setContextClassLoader(cl);
}
/*
* Pass the remaining arguments to SystemServer.
*/
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
/* should never reach here */
}
接下来在RuntimeInit的zygoteInit方法中
./base/core/java/com/android/internal/os/RuntimeInit.java
/**
* The main function called when started through the zygote process. This
* could be unified with main(), if the native code in nativeFinishInit()
* were rationalized with Zygote startup.<p>
*
* Current recognized args:
* <ul>
* <li> <code> [--] <start class name> <args>
* </ul>
*
* @param targetSdkVersion target SDK version
* @param argv arg strings
*/
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
redirectLogStreams(); // about print android log
//一下三个方法是比较重要的
commonInit();//包含uncaughtexception,timezone,logmanager,HTTP user Agent,NetworkManagementSocketTagger
nativeZygoteInit(); // native init
//things init that pre
applicationInit(targetSdkVersion, argv, classLoader);
}
这里要特别看一下applicationInit 方法,算是上面几个init方法中最重要的一个
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
// If the application calls System.exit(), terminate the process
// immediately without running any shutdown hooks. It is not possible to
// shutdown an Android application gracefully. Among other things, the
// Android runtime shutdown hooks close the Binder driver, which can cause
// leftover running threads to crash before the process actually exits.
nativeSetExitWithoutCleanup(true);
// We want to be fairly aggressive about heap utilization, to avoid
// holding on to a lot of memory that isn't needed.
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);//之前的版本好像没有这个方法,应该是5.1中新增,设置sdk版本
final Arguments args;
try {
args = new Arguments(argv);
} catch (IllegalArgumentException ex) {
Slog.e(TAG, ex.getMessage());
// let the process exit
return;
}
// Remaining arguments are passed to the start class's static main
接下来有invokeStaticMain方法
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
/**
* Invokes a static "main(argv[]) method on class "className".
* Converts various failing exceptions into RuntimeExceptions, with
* the assumption that they will then cause the VM instance to exit.
*
* @param className Fully-qualified class name
* @param argv Argument vector for main()
* @param classLoader the classLoader to load {@className} with
*/
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
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);
}
... the main method must be static main
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
//之前我们在ZygoteInit.java中的main方法看到有MethoddAndArgsCaller异常的捕捉 caller.run()
/*
* 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.
*/
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}
题外话: 从上面的流程跟踪下来,
个人感觉,google大佬们也在做一些优化,整合。比起4.x甚至3.x的版本。
接下来就是在SystemServer中的main方法,启动各个system service
四、 SystemServer 启动各个service
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
我们可以看到MethodAndArgsCaller 类中run实现,即 直接应用参数Method反射
/**
884 * Helper exception class which holds a method and arguments and
885 * can call them. This is used as part of a trampoline to get rid of
886 * the initial process setup stack frames.
887 */
888 public static class MethodAndArgsCaller extends Exception
889 implements Runnable {
890 /** method to call */
891 private final Method mMethod;
892
893 /** argument array */
894 private final String[] mArgs;
895
896 public MethodAndArgsCaller(Method method, String[] args) {
897 mMethod = method;
898 mArgs = args;
899 }
900
901 public void run() {
902 try {
903 mMethod.invoke(null, new Object[] { mArgs });
904 } catch (IllegalAccessException ex) {
905 throw new RuntimeException(ex);
906 } catch (InvocationTargetException ex) {
907 Throwable cause = ex.getCause();
908 if (cause instanceof RuntimeException) {
909 throw (RuntimeException) cause;
910 } else if (cause instanceof Error) {
911 throw (Error) cause;
912 }
913 throw new RuntimeException(ex);
914 }
915 }
916 }
...... 后面的世界面孔那就多了......
上面部分大致的流程图就是这样,图画的比较随性,