Android啟動模式
- recovery升級模式:啟動recovery分區內核和文件系統
- 正常啟動模式:引導內核和啟動Android系統
- 啟動電源以及系統啟動:加載引導程序Bootloader到RAM
- Bootloader :主要啟動系統OS
- Linux Kenel :啟動內核,設置緩存、被保護存儲器、計劃列表,加載驅動;查找init文件,啟動init進程
- init進程啟動 : init進程PID是1,父進程為linux系統內核的0號進程;初始化和啟動屬性服務,并且啟動Zygote進程
- Zygote進程啟動 : 創建DVM虛擬機并注冊JNI,創建服務端Socket,啟動SystemSrver進程
- SystemServer進程啟動 : 啟動Binder線程池和SystemServiceManager,并啟動各種系統服務
- Launcher啟動 在SystemServer進程中啟動ActivityManagerService服務后啟動Launcher,桌面程序啟動后顯示已安裝應用的快捷圖標
一. Android init進程
init進程執行程序所在位置/init
,其源代碼所在目錄system/core/init
;作為用戶空間的第一個進程,被賦予了很多及其重要的工作職責,比如創建zygote(孵化器)和屬性服務等。
init進程主要工作內容
- 第一個應用程序
- 創建目錄,并掛載設備
- 解析啟動腳本(init.rc腳本),觸發Action及啟動Service(例如啟動zygote進程)
- 提供系統property服務管理及完成對應的觸發事件
- 維護系統及Service
init.rc
init.rc
是一個配置文件,內部有Android初始化語言編寫的腳本。在Android7.0中對init.rc
進行了拆分,每個服務對應一個rc文件。Android重要的zygote服務的啟動腳本則在init.zygoteXX.rc中定義,例如64位處理器則是init.zygote64.rc。
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main
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
writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
通知init進程創建zygote的service進程,程序路徑為/system/bin/app_process64,啟動的class name 是main。
在init進程中,通過解析
init.rc
資源文件,fork()一個子線程并啟動zygote線程。
二. Zygote進程
在Android系統中,DVM(Dalvik虛擬機)、應用程序進程以及運行系統的關鍵服務的SystemServer進程都是由Zygote進程通過fork(復制進程)創建的。Zygote進程在啟動時會創建DVM,因此fork而來的進程應用程序進程和SystemServer進程都可以在內部獲取到一個DVM實例拷貝。
Zygote啟動流程
- zygote進程是由app_process程序執行后更改名稱而來,在
frameworks/base/cmds/app_process/app_main.cpp
中調用AppRuntime.start()
啟動Java層的ZygoteInit
int main(int argc, char* const argv[])
{
//...
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
//...
Vector<String8> args;
if (!className.isEmpty()) {
//非zygote模式,
args.add(application ? String8("application") : String8("tool"));
runtime.setClassNameAndArgs(className, argc - i, argv + i);
} else {
// zygote模式下,初始化設置一些參數供后面的zygote使用
maybeCreateDalvikCache();
if (startSystemServer) {
args.add(String8("start-system-server"));//1
}
//...
}
if (!niceName.isEmpty()) {
//修改進程名稱,將app_process改為zygote
runtime.setArgv0(niceName.string());
set_process_name(niceName.string());
}
if (zygote) {
//zygote模式下調用ZygoteInit
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
//...
}
}
- AppRuntime繼承了AndroidRuntime,
runtime.start
實際調用了AndroidRuntime.start()
方法。
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
//...
//初始化JNI
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
//創建DVM虛擬機
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
//注冊JNI
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
//通過反射機制調用com.android.internal.os.ZygoteInit的main函數
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);
//從app_main的main函數得知className為com.android.internal.os.ZygoteInit
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);
}
char* slashClassName = toSlashClassName(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");//3
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
//通過JNI調用ZygoteInit的main函數
env->CallStaticVoidMethod(startClass, startMeth, strArray);//4
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
...
}
- Zygote進程啟動Java框架層,執行ZygoteInit
//com.android.internal.os.ZygoteInit
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
ZygoteHooks.startZygoteNoThreadCreation();
//...
try {
//...
boolean startSystemServer = false;
String socketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
//讀取argv[]參數
//...
//1.注冊zygote服務使用的socket,zygote與其他進程通信使用了socket方式,而不是Binder.
zygoteServer.registerServerSocket(socketName);
if (!enableLazyPreload) {
//2.記載類以及各種資源
preload(bootTimingsTraceLog);
} else {
Zygote.resetNicePriority();
}
//...
//3.創建系統服務SystemServer進程,啟動一些系統核心程序
if (startSystemServer) {
startSystemServer(abiList, socketName, zygoteServer);
}
//4.監聽客戶端請求,并調用相應的函數進行處理
zygoteServer.runSelectLoop(abiList);
zygoteServer.closeServerSocket();
} catch (Zygote.MethodAndArgsCaller caller) {
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
zygoteServer.closeServerSocket();
throw ex;
}
}
-
zygoteServer.registerServerSocket()
創建LocalServerSocket
,也就是服務端的Socket。待Zygote進程將SystemServer進程啟動后,
//com.android.internal.os.ZygoteServer
void registerServerSocket(String socketName) {
if (mServerSocket == null) {
int fileDesc;
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);
mServerSocket = new LocalServerSocket(fd);
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}
- 通過
Zygote.forkSystemServer
方式創建SystemServer
進程;handleSystemServerProcess(parsedArgs)
調用ZygoteInit.zygoteInit()
來進行native層的初始化,并通過jnvokeStaticMain()
反射方式調用com.android.server.SystemServer.main
方法
//com.android.internal.os.ZygoteInit
private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
throws Zygote.MethodAndArgsCaller, RuntimeException {
//...
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();
handleSystemServerProcess(parsedArgs);
}
return true;
}
//com.android.server.SystemServer
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
try {
//初始化一些系統屬性參數
//配置虛擬機的一些參數等等之類工作
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
Looper.prepareMainLooper();
// 初始化Native層android_servers
System.loadLibrary("android_servers");
// Check whether we failed to shut down last time we tried.
// This call may not return.
performPendingShutdown();
// 創建系統層級的Context上下文
createSystemContext();
// 創建初始化SystemServiceManager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
SystemServerInitThreadPool.get();
} finally {
traceEnd();
}
// 初始化啟動Framework層的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");
}
-
runSelectLoop()
監聽客戶端請求(例如ActivityManagerService發送請求,經過一些列的調用最終調用Process.zygoteSendArgsAndGetResult()方法),ServerSocket
監聽處理請求,在ZygoteConnection.run()
方法中fork一個子進程并由子進程來處理。
//com.android.internal.os.ZygoteInit
void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
//....
while (true) {
//....
for (int i = pollFds.length - 1; i >= 0; --i) {
//...
if (i == 0) {
//獲取Socket連接
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
//對每個連接調用runOnce處理
boolean done = peers.get(i).runOnce(this);
if (done) {
peers.remove(i);
fds.remove(i);
}
}
}
}
}
//com.android.internal.os.ZygoteConnection
boolean runOnce(ZygoteServer zygoteServer) throws Zygote.MethodAndArgsCaller {
//...
//fork出一個子進程
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
parsedArgs.appDataDir);
if (pid == 0) {
zygoteServer.closeServerSocket();
//...
//子進程處理函數
handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
//...
}
//...
}
Zygote進程總結
流程圖
- main方法中創建AppRuntime并調用其start方法
- 在runtime.start方法中創建DVM虛擬機,并未DVM注冊JNI
- 通過JNI反射方式調用
ZygoteInit
的mian函數進入Zygote的Java框架層 - 通過
registerZygoteSocket
函數創建服務端的Socket,并通過runSelectLoop
函數等待ActivityManagerService等請求來fork新的應用程序進程 - fork啟動SystemServer進程