以Android9.0為基礎,分析一下Android系統啟動過程。
從裝置開始上電,BootLoader會引導Linux核心啟動,當核心啟動時,會設定緩存,被保護存儲器,計劃清單,加載驅動等。當核心完成系統設定時,首先會在檔案系統中查找init.rc檔案,并啟動init程序。
init是系統第一個被啟動的程序,程序id為1
init程序會解析rc檔案,啟動zygote程序(孵化器)。
Zygote程序啟動
下面從init.rc開始分析:
system\core\rootdir\init.rc
重點看一下late-init,zygote-start這及部分
# Copyright (C) 2012 The Android Open Source Project
#
# IMPORTANT: Do not create world writable files or directories.
# This is a common source of Android security bugs.
#
import /init.environ.rc
import /init.usb.rc
import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
import /init.usb.configfs.rc
import /init.${ro.zygote}.rc #我的環境是高通開發闆,導入的是 init.zygote64_32.rc
......
# Healthd can trigger a full boot from charger mode by signaling this
# property when the power button is held.
on property:sys.boot_from_charger_mode=1
class_stop charger
trigger late-init #當按下power按鈕,觸發late-init觸發器
......
# Mount filesystems and start core system services.
on late-init
trigger early-fs
# Mount fstab in init.{$device}.rc by mount_all command. Optional parameter
# '--early' can be specified to skip entries with 'latemount'.
# /system and /vendor must be mounted by the end of the fs stage,
# while /data is optional.
trigger fs
trigger post-fs
# Mount fstab in init.{$device}.rc by mount_all with '--late' parameter
# to only mount entries with 'latemount'. This is needed if '--early' is
# specified in the previous mount_all command on the fs stage.
# With /system mounted and properties form /system + /factory available,
# some services can be started.
trigger late-fs
# Now we can mount /data. File encryption requires keymaster to decrypt
# /data, which in turn can only be loaded when system properties are present.
trigger post-fs-data
# Now we can start zygote for devices with file based encryption
trigger zygote-start #觸發zygote-start觸發器
# Load persist properties and override properties (if enabled) from /data.
trigger load_persist_props_action
# Remove a file to wake up anything waiting for firmware.
trigger firmware_mounts_complete
trigger early-boot
trigger boot
......
# It is recommended to put unnecessary data/ initialization from post-fs-data
# to start-zygote in device's init.rc to unblock zygote start.
#根據磁盤加密的情況,啟動zygote和zygote_secondary,我使用的高通開發闆,property:ro.crypto.state=unsupported
on zygote-start && property:ro.crypto.state=unencrypted
# A/B update verifier that marks a successful boot.
exec_start update_verifier_nonencrypted
start netd
start zygote
start zygote_secondary
on zygote-start && property:ro.crypto.state=unsupported
# A/B update verifier that marks a successful boot.
exec_start update_verifier_nonencrypted
start netd
start zygote
start zygote_secondary
on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file
# A/B update verifier that marks a successful boot.
exec_start update_verifier_nonencrypted
start netd
start zygote
start zygote_secondary
......
system\core\rootdir\init.zygote64_32.rc
看到zygote服務是 /system/bin/app_process64的二進制bin,後面跟着的是入參,會被傳遞到main函數中。
另外還可以看到有一個zygote_secondary,其執行程式是/system/bin/app_process32,是針對32位程式的孵化器。目前來說64位程式比較普及了,暫時不研究這個服務。
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
class main
priority -20
user root
group root readproc reserved_disk
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
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
service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload
class main
priority -20
user root
group root readproc reserved_disk
socket zygote_secondary stream 660 root system
onrestart restart zygote
writepid /dev/cpuset/foreground/tasks
通過檢視mk可知,frameworks\base\cmds\app_process\app_main.cpp會編出app_process64這個程序。
frameworks\base\cmds\app_process\app_main.cpp
int main(int argc, char* const argv[])
{
......
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
// 如果目前處在zygote程序,則把zygote變量置為true。為什麼會有此判斷?因為zygote建立子程序時都是通過fork方式建立的,它本身和它建立出來的子程序都能進入main函數,故在此設定flag為了區分是zygote本身還是它的子程序。
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {
//需要啟動SystemServer
startSystemServer = true;
} else if (strcmp(arg, "--application") == 0) {
//啟動普通程式,init.zygote64_32.rc裡沒有這個入參
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
niceName.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
//如果是啟動普通程式,通過--參數指定其class。在zygote階段,不會走到這個分支
className.setTo(arg);
break;
} else {
--i;
break;
}
}
......
if (!niceName.isEmpty()) {
runtime.setArgv0(niceName.string(), true /* setProcName */);
}
if (zygote) {
//啟動ZygoteInit
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
//通過RuntimeInit啟動一個程式,在zygote階段,不會走到這個分支
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.");
}
}
從main函數可以看出,是通過AppRuntime.start進行Zygote初始化的。
frameworks\base\core\jni\AndroidRuntime.cpp
//className是 com.android.internal.os.ZygoteInit,
//options添加了 start-system-server,abi-list,以及其他在rc裡面的入參
//zygote = true
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
......
/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
//啟動java虛拟機
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
/*
* Register android functions. 注冊JNI方法,JNI方法清單在gRegJNI[]這個靜态數組裡
*/
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
//建立了一個String類型的數組strArray,index 0存的是className,即com.android.internal.os.ZygoteInit
//把入參存入strArray
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);
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);
}
//把className中的.換成/
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
//找到ZygoteInit的main函數
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.java的main方法
env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
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");
}
可以看到在61行,調用了ZygoteInit.java的main方法,從這個點開始,zygote進入了java層。
frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
......
//建立一個Server socket,名字是"zygote"
zygoteServer.registerServerSocketFromEnv(socketName);
// In some configurations, we avoid preloading resources and classes eagerly.
// In such cases, we will preload things prior to our first fork.
if (!enableLazyPreload) {
......
//預加載資源
preload(bootTimingsTraceLog);
......
} else {
Zygote.resetNicePriority();
}
......
if (startSystemServer) {//init.zygote64_32.rc裡面入參含有--start-system-server
//啟動systemserver程序
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;
}
}
Log.i(TAG, "Accepting command socket connections");
//loop循環,等待AMS發送請求
caller = zygoteServer.runSelectLoop(abiList);
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
zygoteServer.closeServerSocket();
}
// We're in the child process and have exited the select loop. Proceed to execute the
// command.
if (caller != null) {
caller.run();
}
}
通過分析可以發現ZygoteInit主要做了以下幾件事:
- 建立socket server服務
- 預加載類和資源
- 啟動systemserver程序
-
等待AMS請求以便建立新的程序
具體看下這幾個過程,建立socket server服務registerServerSocketFromEnv
frameworks\base\core\java\com\android\internal\os\ZygoteServer.java
void registerServerSocketFromEnv(String socketName) {
if (mServerSocket == null) {
int fileDesc;
//socket全名 ANDROID_SOCKET_zygote
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
try {
String env = System.getenv(fullSocketName);
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
throw new RuntimeException(fullSocketName + " unset or invalid", ex);
}
try {
//建立檔案描述符
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
//建立socket并監聽,等待socket消息。注意這裡的socket是本地socket,通過fd進行通信,而不是具體某個ip+端口
mServerSocket = new LocalServerSocket(fd);
mCloseSocketFd = true;
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}
預加載類和資源preload(bootTimingsTraceLog);
frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
static void preload(TimingsTraceLog bootTimingsTraceLog) {
Log.d(TAG, "begin preload");
bootTimingsTraceLog.traceBegin("BeginIcuCachePinning");
beginIcuCachePinning();
bootTimingsTraceLog.traceEnd(); // BeginIcuCachePinning
bootTimingsTraceLog.traceBegin("PreloadClasses");
//預加載/system/etc/preloaded-classes檔案中的類
preloadClasses();
bootTimingsTraceLog.traceEnd(); // PreloadClasses
bootTimingsTraceLog.traceBegin("PreloadResources");
//預加載資源,包含drawable和color資源
preloadResources();
bootTimingsTraceLog.traceEnd(); // PreloadResources
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
nativePreloadAppProcessHALs();
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
//預加載OpenGL
preloadOpenGL();
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
//預加載共享庫"android" "compiler_rt" "jnigraphics"
preloadSharedLibraries();
//預加載 文本連接配接符資源
preloadTextResources();
// Ask the WebViewFactory to do any initialization that must run in the zygote process,
// for memory sharing purposes.
//僅用于zygote程序,用于記憶體共享的程序
WebViewFactory.prepareWebViewInZygote();
endIcuCachePinning();
warmUpJcaProviders();
Log.d(TAG, "end preload");
sPreloadComplete = true;
}
啟動systemserver程序 forkSystemServer(abiList, socketName, zygoteServer);
frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
......
/* Hardcoded command line to start the system server */
//設定啟動參數
String args[] = {
"--setuid=1000",//使用者id
"--setgid=1000",//使用者組id
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",//擁有1001,1002....使用者組的權限
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
//将args[]轉化成ZygoteConnection.Arguments對象
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
boolean profileSystemServer = SystemProperties.getBoolean(
"dalvik.vm.profilesystemserver", false);
if (profileSystemServer) {
parsedArgs.runtimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
}
/* Request to fork the system server process */
//建立子程序 systemserver
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.runtimeFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
//pid == 0說明此代碼運作在子程序中
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();
return handleSystemServerProcess(parsedArgs);
}
return null;
}
frameworks\base\core\java\com\android\internal\os\Zygote.java
public static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
VM_HOOKS.preFork();
// Resets nice priority for zygote process.
resetNicePriority();
//jni調用fork systemserver程序
int pid = nativeForkSystemServer(
uid, gid, gids, runtimeFlags, rlimits, permittedCapabilities, effectiveCapabilities);
// Enable tracing as soon as we enter the system_server.
if (pid == 0) {
Trace.setTracingEnabled(true, runtimeFlags);
}
VM_HOOKS.postForkCommon();
return pid;
}
通過JNI,調用native的fork方法
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 runtime_flags, jobjectArray rlimits, jlong permittedCapabilities,
jlong effectiveCapabilities) {
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
runtime_flags, rlimits,
permittedCapabilities, effectiveCapabilities,
MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
NULL, false, NULL, NULL);
if (pid > 0) {
// The zygote process checks whether the child process has died or not.
ALOGI("System server process %d has been created", pid);
gSystemServerPid = 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.
int status;
if (waitpid(pid, &status, WNOHANG) == pid) {
ALOGE("System server process %d has died. Restarting Zygote!", pid);
RuntimeAbort(env, __LINE__, "System server process has died. Restarting Zygote!");
}
bool low_ram_device = GetBoolProperty("ro.config.low_ram", false);
bool per_app_memcg = GetBoolProperty("ro.config.per_app_memcg", low_ram_device);
if (per_app_memcg) {
// Assign system_server to the correct memory cgroup.
// Not all devices mount /dev/memcg so check for the file first
// to avoid unnecessarily printing errors and denials in the logs.
if (!access("/dev/memcg/system/tasks", F_OK) &&
!WriteStringToFile(StringPrintf("%d", pid), "/dev/memcg/system/tasks")) {
ALOGE("couldn't write %d to /dev/memcg/system/tasks", pid);
}
}
}
return pid;
}
fork完SystemServer後,SystemServer複制了Zygote程序的位址空間,是以也能拿到Zygote建立的socket.
回到java層:
frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
......
//pid == 0說明此代碼運作在子程序中
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket();//此Socket對SystemServer沒有作用,故關閉
return handleSystemServerProcess(parsedArgs);
}
return null;
}
......
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
......
if (parsedArgs.invokeWith != null) {
......
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
//建立pathClassLoader
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
//重點關注
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
/* should never reach here */
}
......
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();
//jni調用,啟動binder線程池,SystemServer就具備了使用binder通信的能力
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
在zygoteInit中,會調用nativeZygoteInit啟動線程池,對應的natvie方法在AndroidRuntime.cpp中,
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));
}
......
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
//gCurRuntime是AndroidRuntime類型的指針,指向的是AppRuntime
gCurRuntime->onZygoteInit();
}
......
frameworks\base\cmds\app_process\app_main.cpp
virtual void onZygoteInit()
{
//啟動binder線程池
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}
當binder線程池啟動完,回到ZygoteInit.java的zygoteInit最後一行,會調用RuntimeInit.applicationInit
frameworks\base\core\java\com\android\internal\os\RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
// 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 = new Arguments(argv);
// The end of of the RuntimeInit event (see #zygoteInit).
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
//傳回一個runnable,run的内容是反射SystemServer的main函數調用
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
......
protected 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 {
//找到main方法
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);
}
......
static class MethodAndArgsCaller implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
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);
}
}
}
在RuntimeInit中建立的MethodAndArgsCaller會傳回到ZygoteInit的main函數裡執行。
最後,在ZygoteInit中會執行循環runSelectLoop,等待AMS請求。
frameworks\base\core\java\com\android\internal\os\ZygoteServer.java
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
fds.add(mServerSocket.getFileDescriptor());
peers.add(null);
while (true) {
StructPollfd[] pollFds = new StructPollfd[fds.size()];
for (int i = 0; i < pollFds.length; ++i) {
pollFds[i] = new StructPollfd();
pollFds[i].fd = fds.get(i);
pollFds[i].events = (short) POLLIN;
}
try {
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
for (int i = pollFds.length - 1; i >= 0; --i) {
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
try {
ZygoteConnection connection = peers.get(i);
final Runnable command = connection.processOneCommand(this);
if (mIsForkChild) {
// We're in the child. We should always have a command to run at this
// stage if processOneCommand hasn't called "exec".
if (command == null) {
throw new IllegalStateException("command == null");
}
return command;
} else {
// We're in the server - we should never have any commands to run.
if (command != null) {
throw new IllegalStateException("command != null");
}
// We don't know whether the remote side of the socket was closed or
// not until we attempt to read from it from processOneCommand. This shows up as
// a regular POLLIN event in our regular processing loop.
if (connection.isClosedByPeer()) {
connection.closeSocket();
peers.remove(i);
fds.remove(i);
}
}
} catch (Exception e) {
if (!mIsForkChild) {
// We're in the server so any exception here is one that has taken place
// pre-fork while processing commands or reading / writing from the
// control socket. Make a loud noise about any such exceptions so that
// we know exactly what failed and why.
Slog.e(TAG, "Exception executing zygote command: ", e);
// Make sure the socket is closed so that the other end knows immediately
// that something has gone wrong and doesn't time out waiting for a
// response.
ZygoteConnection conn = peers.remove(i);
conn.closeSocket();
fds.remove(i);
} else {
// We're in the child so any exception caught here has happened post
// fork and before we execute ActivityThread.main (or any other main()
// method). Log the details of the exception and bring down the process.
Log.e(TAG, "Caught post-fork exception in child process.", e);
throw e;
}
} finally {
// Reset the child flag, in the event that the child process is a child-
// zygote. The flag will not be consulted this loop pass after the Runnable
// is returned.
mIsForkChild = false;
}
}
}
}
}
至此Zygote程序啟動完成,下面進入SystemServer程序的啟動。
SystemServer程序啟動
SystemServer主要建立各種系統服務,包括AMS,WMS,PMS等。我們平時熟悉的各個系統服務,實際上都屬于SystemServer程序中的各個服務線程處理的。
frameworks\base\services\java\com\android\server\SystemServer.java
......
//被zygote反射執行
public static void main(String[] args) {
new SystemServer().run();
}
....
private void run() {
......
// Start services.
try {
traceBeginAndSlog("StartServices");
startBootstrapServices(); //啟動引導服務
startCoreServices(); //啟動核心服務
startOtherServices(); //啟動其他服務
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
......
//進入無限循環
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
SystemServer啟動了3種類型的服務,這些服務是Android系統運作的基礎,有興趣的可以再深入了解各種服務的作用。
至此Android系統啟動基本完成,總結一下,主要分為以下幾個過程
- 系統上電,bootLoader啟動,核心啟動
- init程序啟動
- Zygote程序啟動
- SystemServer程序啟動
參考資料
<<Android進階揭秘>>
android系統啟動流程之init.rc詳細分析筆記
Android系統啟動流程—— init程序zygote程序SystemServer程序啟動流程