系统启动流程
我们知道,Android系统是基于Linux改造出来的,所以继承了Linux很多特性,包括进程管理。在系统启动过程中,第一个启动的进程是Init进程,后面所有Fork出来的进程都是它的子孙后代,包括跟Android紧密联系的Zygote进程也是Init进程衍生的。
1、系统启动前期-Init进程
当按下开机按钮后,系统启动开始挂载设备,初始化Init进程,其中入口函数里,解析了一个叫做init.rc脚本程序,里面运用脚本命令启动了Zygote进程
2、Android的受精卵阶段-Zygote进程
fork出Zygote进程,执行了c++程序frameworks/base/cmds/app_process/app_main.cpp,该程序
是被cmd启动的,它做了一件主要的事情,初始化AppRuntime 对象,它负责启动java层的ZygoteInit类的main入口函数。代码如下:
int main(int argc, char* const argv[])
{
...
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);//1
} 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.");
return 10;
}
}
从底层眼看要来到Java层了,AppRuntime是还做了另外一个更有趣的事情。在启动运行Java文件之前肯定要有Davilk虚拟机,所以在这里会先调用startVm()来启动Davilk虚拟机-DVM。然后在cpp层调用拿到ZygoteInit类,调用CallStaticVoidMethod()来启动了com.android.internal.os.ZygoteInit的main函数。里面调用了runtime对象的start()方法传入ZygoteInit类名创建,代码如下:
/*
* 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".
*/
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
static const String8 startSystemServer("start-system-server");
//启动VM
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
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);
...省略若干行...
/*
* 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 {
//拿到方法对应的id
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 {
//调用main方法
env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
free(slashClassName);
}
3、完成使命,进入胚胎时期ZygoteInit.java -> SystemServer.java
1.在这时候,跟Java有关的第一个进程Zygote进程启动了,在main函数里,它建立了一个socket通讯服务端,通过文件描述符 /dev/socket/zygote 初始化LocalServerSocket服务端,这个服务端后面会跟AMS(ActivityManagerService)来建立socket通讯,初始化然后接着调用startSystemServer()启动SystemServer进程,然后调用runSelectLoopMode()等待AMS的连接.
public static void main(String argv[]) {
try {
//。。。省略n行。。。
1.建立ActivityManagerService(据说,求举证)连接
registerZygoteSocket(socketName);
//。。。省略n行。。。
2.启动SystemServer.java
if (startSystemServer) {
startSystemServer(abiList, socketName);
}
//。。。省略n行。。。
//执行死循环等待连接
3.runSelectLoopMode()
//
4.关闭连接
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();
} catch (RuntimeException ex) {
closeServerSocket();
throw ex;
}
}
tips:为什么这里用socket通讯而不用Binder? 因为还没有启动,在接下来的Systemserver启动时会启动Binder机制。
在startSystemServer中,调用了Zygote.forSystemServer()来fork出新的进程,叫SystemServer进程.
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
/* 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,1032,3001,3002,3003,3006,3007",
"--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);
}
//...
return true;
}
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
VM_HOOKS.preFork();
int pid = nativeForkSystemServer(
uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
// Enable tracing as soon as we enter the system_server.
if (pid == 0) {
Trace.setTracingEnabled(true);
}
VM_HOOKS.postForkCommon();
return pid;
}
具体怎么fork出来的呢,可以看到调用了nativeForkSystemServer()的native方法.具体的实现在:/dalvik/vm/native/dalvik_system_Zygote.cpp,具体的实现forkSystemServer()方法中,做了两个事
1.调用forkAndSpecializeCommon()
2.杀死Zygote进程自己,脱壳退场.
const DalvikNativeMethod dvm_dalvik_system_Zygote[] = {
{ "nativeFork", "()I",
Dalvik_dalvik_system_Zygote_fork },
{ "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;)I",
Dalvik_dalvik_system_Zygote_forkAndSpecialize },
{ "nativeForkSystemServer", "(II[II[[IJJ)I",
Dalvik_dalvik_system_Zygote_forkSystemServer },
{ NULL, NULL, NULL },
};
/*
* native public static int nativeForkSystemServer(int uid, int gid,
* int[] gids, int debugFlags, int[][] rlimits,
* long permittedCapabilities, long effectiveCapabilities);
*/
static void Dalvik_dalvik_system_Zygote_forkSystemServer(
const u4* args, JValue* pResult)
{
pid_t pid;
pid = forkAndSpecializeCommon(args, true);
/* The zygote process checks whether the child process has died or not. */
if (pid > 0) {
int status;
ALOGI("System server process %d has been created", pid);
gDvm.systemServerPid = pid;
/* There is a slight window that the system server process has crashed
* but it went unnoticed because we haven't published its pid yet. So
* we recheck here just to make sure that all is well.
*/
if (waitpid(pid, &status, WNOHANG) == pid) {
ALOGE("System server process %d has died. Restarting Zygote!", pid);
kill(getpid(), SIGKILL);
}
}
RETURN_INT(pid);
}
4、成功变成宝宝-SystemServer进程启动系统服务
Zygote进程fork出新的进程SystemServer了,完成了受精卵时期。来到另外一个万花筒年代.一个新的进程开始,按照旧惯例还是以main函数作为入口,里面直接粗暴的new了一个本类对象执行了run方法(社会社会)。
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
run方法里启动了三种服务
1.引导服务
startBootstrapServices();
2.核心服务
startCoreServices();
3.增值服务
startOtherServices();
主要逻辑部分代码如下:
// Initialize the system context.
createSystemContext();
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Start services.
try {
//1.引导服务
startBootstrapServices();
//2.核心服务
startCoreServices();
//3增值服务
startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
}
AMS是第一个被启动的,当他以及一系列服务(WindowManagerService、PackageManagerService…)启动执行被启动后(迎接第一个高潮),接下来AMS就去干两件非常重要的事情,就是去告诉邻居和开门。
1.AMS会启动桌面程序Launcher。
2.接着会通知SurfaceFlinger关闭它的bootanimation(开机的时候启动开机动画)。这时候桌面就会显示出来了。
总结一下:
1.系统挂载和Init进程初始化
3.在里面appruntime对象启动Davilk并fork出Zygote进程
4.受精卵建立socket服务端等待AMS连接。同时并fork一个子进程出来启动SystemServer
5.SystemServer启动各种服务,其中包括AMS,和其他系统服务。AMS启动后会连接Zygote进程。然后启动Launcher和关闭开机动画。
6.调用各种服务起来之后纷纷调用各自的systemReady()方法;接下来的关心的事情就是:Launcher的启动流程
(后面将分享Binder进程间通讯的机制&Launcher的启动流程)