不知你是否也和我一样,会好奇整个系统给的启动过程是怎样的?
今天我们先来看下整个过程重要的一个环节SystemServer的内容
如图所示,在系统启动好,到了第4步的时候
首先,Zygote
进程由init
进程解析init.rc
文件后fork生成。(Zygote进程主要为加载ZygoteInit
类、注册Zygote Socket
服务端套接字、加载虚拟机、preloadClasses、preloadResouces等),
然后,Zygote
进程fork
出System Server
进程。System Server
进程很重要,负责启动和管理整个Framework
内容,包括ActivityManager
,PowerManager
等服务。
接着, 在孵化出上面的SystemServer
后,孵化出的第一个App进程是Launcher
,就是我们的桌面; 除此之外,它还会创建各种系统App,例如电话phone,信息Message等程序。
上面作为整个流程的大致介绍,现在我们就来看下SystemServer的内容吧!
前进
API:23
让我们先从他的启动开始说起吧,在ZygoteInit
里面
public static void main(String argv[]) {
RuntimeInit.enableDdms();//启动DDMS,这个名字熟悉吧?
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;
}
...
}
...
if (startSystemServer) {
startSystemServer(abiList, socketName);
}
}
这是启动SystemServer的起点
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,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;
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);
//孵出子进程system_server
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
//Finish remaining work for the newly forked system
//server process.//我们的主线2
handleSystemServerProcess(parsedArgs);
}
return true;
}
我们看下叫Zygote类的内容
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;
}
通过native层去fork我们的SystemServer。那么他的native最后跑到哪里去呢?
看frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
内容
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,
jlong effectiveCapabilities) {
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
debug_flags, rlimits,
permittedCapabilities,
effectiveCapabilities,
MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true,
NULL,NULL, NULL);
...
return pid;
}
嗯,跳去另外一个
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray
javaGids,jint debug_flags, jobjectArray javaRlimits,jlong permittedCapabilities,
jlong effectiveCapabilities,jint mount_external,jstring java_se_info,
jstring java_se_name,bool is_system_server, jintArray fdsToClose,
jstring instructionSet, jstring dataDir) {
SetSigChldHandler();
//fork子进程
pid_t pid = fork();
if (pid == 0) {
...
env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags,
is_system_server ? NULL : instructionSet);
...
} else if (pid > 0) {
// the parent process
}
return pid;
}
int register_com_android_internal_os_Zygote(JNIEnv* env) {
gZygoteClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, kZygoteClassName));
gCallPostForkChildHooks = GetStaticMethodIDOrDie(env, gZygoteClass,
"callPostForkChildHooks","(ILjava/lang/String;)V");
return RegisterMethodsOrDie(env, "com/android/internal/os/Zygote", gMethods,
NELEM(gMethods));
}
主要是创建工作,我们回头看下主线2handleSystemServerProcess()
的内容
/**
* Finish remaining work for the newly forked system server process.
*/
private static void handleSystemServerProcess( ZygoteConnection.Arguments parsedArgs){
...
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(parsedArgs.remainingArgs, 0, amendedArgs, 2,
parsedArgs.remainingArgs.length);
}
//创建出应用进程!
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(), null, args);
} 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);
}
}
没什么好说的,继续看下RuntimeInit.zygoteInit()的内容
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader){
...
commonInit();//一些初始化工作
nativeZygoteInit(); //跳来跳去...看得好累..zygote初始化
applicationInit(targetSdkVersion, argv, classLoader);
}
private static final void commonInit() {
if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");
/* set default handler; this applies to all threads in the VM */
Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler());
/*
* Install a TimezoneGetter subclass for ZoneInfo.db
*/
TimezoneGetter.setInstance(new TimezoneGetter() {
@Override
public String getId() {
//哈,获取时区居然是硬编码在这里
return SystemProperties.get("persist.sys.timezone");
}
});
TimeZone.setDefault(null);
/*
* Sets handler for java.util.logging to use Android log facilities.
* The odd "new instance-and-then-throw-away" is a mirror of how
* the "java.util.logging.config.class" system property works. We
* can't use the system property here since the logger has almost
* certainly already been initialized.
*/
LogManager.getLogManager().reset();
new AndroidConfig();
/*
* Sets the default HTTP User-Agent used by HttpURLConnection.
*
* getDefaultUserAgent() Returns an HTTP user agent of the form
* "Dalvik/1.1.0 (Linux; U; Android Eclair Build/MASTER)".
*/
String userAgent = getDefaultUserAgent();
System.setProperty("http.agent", userAgent);
/*
* Wire socket tagging to traffic stats.
*/
NetworkManagementSocketTagger.install();
/*
* If we're running in an emulator launched with "-trace", put the
* VM into emulator trace profiling mode so that the user can hit
* F9/F10 at any time to capture traces. This has performance
* consequences, so it's not something you want to do always.
*/
String trace = SystemProperties.get("ro.kernel.android.tracing");
if (trace.equals("1")) {
Slog.i(TAG, "NOTE: emulator trace profiling enabled");
Debug.enableEmulatorTraceOutput();
}
initialized = true;
}
我们的曙光终于来了
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);
final Arguments args;
try {
args = new Arguments(argv);
} catch (IllegalArgumentException ex) {
Slog.e(TAG, ex.getMessage());
// let the process exit
return;
}
// The end of of the RuntimeInit event (see #zygoteInit).
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// Remaining arguments are passed to the start class's static main
invokeStaticMain(args.startClass, args.startArgs, classLoader);
//最后这句是线索.
}
invokeStaticMain()
private static void invokeStaticMain(String className, String[] argv,
ClassLoader classLoader){
//在startSystemServer()的硬编码初始化参数列表中,我有提到过一次总要参数
//显然此处args.startClass就是"com.android.server.SystemServer"啦!
Class<?> cl= Class.forName(className, true, classLoader);
Method m= cl.getMethod("main", new Class[] { String[].class });
...
/*
* 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);
}
这样我们来看下main函数的内容
public static void main(String argv[]) {
try{
RuntimeInit.enableDdms();
// Start profiling the zygote initialization.
SamplingProfilerIntegration.start();
...
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());
}
...
}
...
//终于!!!!!!!!!!!
if (startSystemServer) {
startSystemServer(abiList, socketName);
}
} catch (MethodAndArgsCaller caller) {
caller.run(); //重要的一句!!!!
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
...
}
我们去看下run的内容:
public static class MethodAndArgsCaller extends Exception
implements Runnable {
public void run() {
try {
//根据参数,反射调用的就是SystemServer.main()方法!!!
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}
}
前进–SystemServer.Main
好了,看了前面一堆的内容,创建和初始化一堆内容。
我们终于知道最后反射调的地方在那里!就是SystemServer.Main()
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
//初始最小时间为1970年!
}
// Here we go! 是的,俺老孙来也
Slog.i(TAG, "Entered the Android system server!");
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());
//6.0用libart.so
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
// Enable the sampling profiler.
if (SamplingProfilerIntegration.isEnabled()) {
SamplingProfilerIntegration.start();
mProfilerSnapshotTimer = new Timer();
//一小时采集一次的分析器。
mProfilerSnapshotTimer.schedule(new TimerTask() {
@Override
public void run() {
SamplingProfilerIntegration.writeSnapshot("system_server", null);
}
}, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
}
// Mmmmmm... more Mmmmmmmm...memory!
VMRuntime.getRuntime().clearGrowthLimit();
// The system server has to run all of the time, so it needs to be
// as efficient as possible with its memory usage.
//设置内存的使用率是0.8,尴尬的内存,以后6G内存普及就会好点了
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
// Some devices rely on runtime fingerprint generation, so make sure
// we've defined it before booting further.
Build.ensureFingerprintProperty();
// Within the system server, it is an error to access Environment paths without
// explicitly specifying a user.
Environment.setUserRequired(true);
// Ensure binder calls into the system always run at foreground priority.
BinderInternal.disableBackgroundScheduling(true);
// Prepare the main looper thread (this thread).
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
Looper.prepareMainLooper();
// Initialize native services.
System.loadLibrary("android_servers");
// Check whether we failed to shut down last time we tried.
// This call may not return.
//检测上次关机过程是否失败
performPendingShutdown();
// Initialize the system context.
createSystemContext();
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Start services.
//重要的内容,启动引导,核心等服务
startBootstrapServices();
startCoreServices();
startOtherServices();
...
// Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
想说的是最后面的start service 的三个函数内容
/**
* Starts the small tangle of critical services that are needed to get
* the system off the ground. These services have complex mutual dependencies
* which is why we initialize them all in one place here. Unless your service
* is also entwined in these dependencies, it should be initialized in one of
* the other functions.
* 注释说明了为什么一次性的在这里初始这么多service的原因
* 打头阵都是有点原因哈,需要给别人提供服务
*/
private void startBootstrapServices() {
// Wait for installd to finish starting up so that it has a chance to
// create critical directories such as /data/user with the appropriate
//就是等和installd建立socket通道
Installer installer = mSystemServiceManager.startService(Installer.class);
//启动AMS,对他熟悉了
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
//电源管理部分,这个我还没看过,他需要早点启动因为别的服务需要它
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
//嗯,为何不是PMS自己初始自己呢?稍后细看
mActivityManagerService.initPowerManagement();
// 负责LEDs 、背光灯部分的服务
mSystemServiceManager.startService(LightsService.class);
// Display manager is needed to provide display metrics before package manager
// starts up.
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
// We need the default display before we can initialize the package manager.
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
// 加密设备是只运行核心的内容,嗯,没加密过
String cryptState = SystemProperties.get("vold.decrypt");
if (ENCRYPTING_STATE.equals(cryptState)) {
Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
mOnlyCore = true;
} else if (ENCRYPTED_STATE.equals(cryptState)) {
Slog.w(TAG, "Device encrypted - only parsing core apps");
mOnlyCore = true;
}
// PMS,最近也经常遇到他
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
//UMS内容,目录:/data/user
ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());
// Initialize attribute cache used to cache resources from packages.
AttributeCache.init(mSystemContext);
// Set up the Application instance for the system process and get started.
mActivityManagerService.setSystemProcess();
// The sensor service needs access to package manager service, app ops
// service, and permissions service, therefore we start it after them.
//因为SensorService需要PMS的服务等,所以被安排到最后面
startSensorService();
}
我们看完这个,核心就是一堆的AMS,PMS,LS,DMS,PMS,UMS和Sensor的初始化。具体的启动过程代码即不贴了,很长,也很复杂。
然后我们继续看另外两个函数的内容
/**
* Starts some essential services that are not tangled up in the bootstrap process.
*/
private void startCoreServices() {
// Tracks the battery level. Requires LightService.
//计算电池容量的,需要LS,所以前面先启动了
mSystemServiceManager.startService(BatteryService.class);
// Tracks application usage stats.
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
// Update after UsageStatsService is available, needed before performBootDexOpt.
mPackageManagerService.getUsageStatsIfNoPackageUsageInfo();
// Tracks whether the updatable WebView is in a ready state and watches for update installs.
mSystemServiceManager.startService(WebViewUpdateService.class);
}
然后那个启动别的服务的函数800行的代码,呵呵,不敢贴上来
主要也是启动服务,包括:CameraService,AudioAservice,VibratorService等等
小结
好吧,总算大致的看了下这个启动过程的一个节点SystemServer的内容
赫,感觉和看那些内核解析/情景源码解析书类似。贴一堆的代码。呵呵
看这部分代码,让我想起了一本书,高德纳的Surreal Numbers