概述:
???? 在Android系統(tǒng)中巢钓,所有的應(yīng)用程序進(jìn)程,以及用來運(yùn)行系統(tǒng)關(guān)鍵服務(wù)的System進(jìn)程都是由Zygote進(jìn)程負(fù)責(zé)創(chuàng)建的界阁,因此疮跑,我們將它成為進(jìn)程孵化器。Zygote進(jìn)程是通過復(fù)制自身的方式來創(chuàng)建System進(jìn)程和應(yīng)用程序進(jìn)程。由于Zygote進(jìn)程在啟動(dòng)時(shí)會在內(nèi)部創(chuàng)建一個(gè)虛擬機(jī)實(shí)例叠必,因此荚孵,通過復(fù)制Zygote進(jìn)程而得到的System進(jìn)程和應(yīng)用程序進(jìn)程可以快速地在內(nèi)部獲得一個(gè)虛擬機(jī)實(shí)例拷貝。
???? Zygote進(jìn)程啟動(dòng)完成以后纬朝,會馬上將system進(jìn)程啟動(dòng)起來收叶,以便它可以將系統(tǒng)關(guān)鍵服務(wù)啟動(dòng)起來。
init 進(jìn)程概述:
init進(jìn)程是Android啟動(dòng)后的玄组,由內(nèi)核啟動(dòng)的第一個(gè)用戶級進(jìn)程
Android 的init進(jìn)程提供四大功能:
- init進(jìn)程處理子進(jìn)程的終止與再啟動(dòng)
- init 進(jìn)程分析init.rc 啟動(dòng)腳本文件滔驾,并根據(jù)相關(guān)中包含的內(nèi)容谒麦,執(zhí)行相應(yīng)的功能俄讹;
- init進(jìn)程提供屬性服務(wù);
- init進(jìn)程生成設(shè)備節(jié)點(diǎn)文件
11. 1 zygote進(jìn)程的啟動(dòng)腳本
???? Zygote進(jìn)程是由Android系統(tǒng)的第一個(gè)進(jìn)程init啟動(dòng)起來的绕德。init進(jìn)程是在內(nèi)核加載完成之后就啟動(dòng)起來的(也就是用戶空間的第一個(gè)進(jìn)程)患膛,它的啟動(dòng)過程中,會讀取根目錄下的一個(gè)腳本文件init.rc耻蛇,以便可以將其他需要開啟的進(jìn)程也一起啟動(dòng)起來踪蹬。
???? Zygote進(jìn)程在腳本文件init.rc 中的啟動(dòng)腳本
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
socket zygote stream 666
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
???? 第一行表示Zygote進(jìn)程是以服務(wù)的形式啟動(dòng)的,并且它所對應(yīng)的應(yīng)用程序文件為 /system/bin/app_process臣咖。接下來的四個(gè)選項(xiàng)是Zygote進(jìn)程的啟動(dòng)參數(shù)跃捣,其中,
最后一個(gè)參數(shù) "--start-system-server" 表示Zygote進(jìn)程在啟動(dòng)完成之后夺蛇,需要馬上將System進(jìn)程也啟動(dòng)起來疚漆。
???? 第二行表示Zygote進(jìn)程在啟動(dòng)的過程中,需要再內(nèi)部創(chuàng)建一個(gè)名稱為 "zygote" 的socket刁赦。這個(gè)Socket是用來執(zhí)行進(jìn)程間通信的娶聘,
它的訪問權(quán)限被這只為666,即所有用戶都可以對它進(jìn)行讀寫甚脉。
???? 由于Zygote進(jìn)程在腳本文件init.rc中配置了以服務(wù)的形式來啟動(dòng)丸升,因此,init進(jìn)程在啟動(dòng)時(shí)牺氨,就會調(diào)用函數(shù)service_start來啟動(dòng)它狡耻,
11.2 Zygote 進(jìn)程的啟動(dòng)過程
app_main.cpp # main
int main(int argc, const char* const argv[])
{
...
// Next arg is startup classname or "--zygote"
if (i < argc) {
arg = argv[i++];
// zygote 啟動(dòng)流程
if (0 == strcmp("--zygote", arg)) {
bool startSystemServer = (i < argc) ?
strcmp(argv[i], "--start-system-server") == 0 : false;
setArgv0(argv0, "zygote");
set_process_name("zygote");
runtime.start("com.android.internal.os.ZygoteInit",
startSystemServer);
} else {
....
}
} else {
....
}
}
通過AppRuntime (父類:AndroidRuntime) 來啟動(dòng)java 虛擬機(jī),運(yùn)行com.android.internal.os.ZygoteInit 的main函數(shù)
AndroidRuntime.cpp # start
來啟動(dòng)java 虛擬機(jī)猴凹,運(yùn)行com.android.internal.os.ZygoteInit 的main函數(shù)
void AndroidRuntime::start(const char* className, const bool startSystemServer)
{
char* slashClassName = NULL;
char* cp;
JNIEnv* env;
blockSigpipe();
/*
* 'startSystemServer == true' means runtime is obslete and not run from
* init.rc anymore, so we print out the boot start event here.
*/
if (startSystemServer) {
/* track our progress through the boot sequence */
const int LOG_BOOT_PROGRESS_START = 3000;
LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,
ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
}
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.");
goto bail;
}
setenv("ANDROID_ROOT", rootDir, 1);
}
//const char* kernelHack = getenv("LD_ASSUME_KERNEL");
//LOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);
/* start the virtual machine */
if (startVm(&mJavaVM, &env) != 0)
goto bail;
/*
* Register android functions.
*/
if (startReg(env) < 0) {
LOGE("Unable to register all android natives\n");
goto bail;
}
/*
* We want to call main() with a String array with arguments in it.
* At present we only have one argument, the class name. Create an
* array to hold it.
*/
jclass stringClass;
jobjectArray strArray;
jstring classNameStr;
jstring startSystemServerStr;
stringClass = env->FindClass("java/lang/String");
assert(stringClass != NULL);
strArray = env->NewObjectArray(2, stringClass, NULL);
assert(strArray != NULL);
classNameStr = env->NewStringUTF(className);
assert(classNameStr != NULL);
env->SetObjectArrayElement(strArray, 0, classNameStr);
startSystemServerStr = env->NewStringUTF(startSystemServer ?
"true" : "false");
env->SetObjectArrayElement(strArray, 1, startSystemServerStr);
/*
* Start VM. This thread becomes the main thread of the VM, and will
* not return until the VM exits.
*/
jclass startClass;
jmethodID startMeth;
slashClassName = strdup(className);
for (cp = slashClassName; *cp != '\0'; cp++)
if (*cp == '.')
*cp = '/';
startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
...
} else {
startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
...
} else {
env->CallStaticVoidMethod(startClass, startMeth, strArray);
...
}
}
...
bail:
free(slashClassName);
}
ZygoteInit # main
public static void main(String argv[]) {
try {
VMRuntime.getRuntime().setMinimumHeapSize(5 * 1024 * 1024);
// 創(chuàng)建一個(gè)Server端Socket, 等待 ActivityManagerservice 的請求來創(chuàng)建新的進(jìn)程酝豪。
registerZygoteSocket();
preloadClasses();
//cacheRegisterMaps();
preloadResources();
// Do an initial gc to clean up after startup
gc();
if (argv[1].equals("true")) {
// 啟動(dòng) system server
startSystemServer();
}
// ZYGOTE_FORK_MODE 的值默認(rèn)為true
if (ZYGOTE_FORK_MODE) {
// 調(diào)用這個(gè)函數(shù),來等待ActivityManagerService 請求Zygote進(jìn)程創(chuàng)建新的應(yīng)用程序精堕。
// 不過孵淘,這種情況下,對于每一個(gè)請求歹篓,Zygote進(jìn)程都會創(chuàng)建一個(gè)新的進(jìn)程來處理瘫证,這樣會浪費(fèi)大量的進(jìn)程資源揉阎。
// 因此, 為了讓所有的創(chuàng)建應(yīng)用程序進(jìn)程請求都在同一個(gè)進(jìn)程中處理,我們將ZygoteInit類的靜態(tài)成員變量 ZYGOTE_FORK_MODE 設(shè)置為false
runForkMode();
} else {
runSelectLoopMode();
}
closeServerSocket();
} catch (MethodAndArgsCaller caller) { ... } catch (RuntimeException ex) { ... }
}
ZygoteInit#startSystemServer
啟動(dòng)System Server 進(jìn)程
/**
* Prepare the arguments and fork for the system server process.
*/
private static boolean startSystemServer()
throws MethodAndArgsCaller, RuntimeException {
// System Server 進(jìn)程的啟動(dòng)參數(shù)
/* 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,3001,3002,3003",
"--capabilities=130104352,130104352",
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
/*
* Enable debugging of the system process if *either* the command line flags
* indicate it should be debuggable or the ro.debuggable system property
* is set to "1"
*/
int debugFlags = parsedArgs.debugFlags;
if ("1".equals(SystemProperties.get("ro.debuggable")))
debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids, debugFlags, null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
handleSystemServerProcess(parsedArgs);
}
return true;
}
System Server 進(jìn)程的啟動(dòng)
由于System進(jìn)程復(fù)制了Zygote進(jìn)程的地址空間背捌,因此它就會獲得Zygote進(jìn)程在啟動(dòng)過程中創(chuàng)建的一個(gè)socket毙籽。System進(jìn)程不需要使用這個(gè)Socket,因此毡庆,需要調(diào)用closeServerSocket 來關(guān)閉它坑赡。
接下來需要調(diào)用RuntimeInit 的 zygoteInit 來進(jìn)一步啟動(dòng)System進(jìn)程。
/**
* Finish remaining work for the newly forked system server process.
*/
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
closeServerSocket();
/*
* Pass the remaining arguments to SystemServer.
* "--nice-name=system_server com.android.server.SystemServer"
*/
RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
/* should never reach here */
}
RuntimeInit # zygoteInit
/**
* The main function called when started through the zygote process. This
* could be unified with main(), if the native code in finishInit()
* were rationalized with Zygote startup.<p>
*
* Current recognized args:
* <ul>
* <li> --nice-name=<i>nice name to appear in ps</i>
* <li> <code> [--] <start class name> <args>
* </ul>
*
* @param argv arg strings
*/
public static final void zygoteInit(String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
// 設(shè)置System進(jìn)程的回去和鍵盤布局等通用信息
commonInit();
// 在System進(jìn)程中啟動(dòng)一個(gè)Binder線程池
zygoteInitNative();
int curArg = 0;
for ( /* curArg */ ; curArg < argv.length; curArg++) {
String arg = argv[curArg];
if (arg.equals("--")) {
curArg++;
break;
} else if (!arg.startsWith("--")) {
break;
} else if (arg.startsWith("--nice-name=")) {
String niceName = arg.substring(arg.indexOf('=') + 1);
Process.setArgV0(niceName);
}
}
if (curArg == argv.length) {
Slog.e(TAG, "Missing classname argument to RuntimeInit!");
// let the process exit
return;
}
// Remaining arguments are passed to the start class's static main
String startClass = argv[curArg++];
String[] startArgs = new String[argv.length - curArg];
System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
// 啟動(dòng) com.android.server.SystemServer類的main函數(shù)
invokeStaticMain(startClass, startArgs);
}
SystemServer # main
進(jìn)入SystemServer進(jìn)程的java世界
public static void main(String[] args) {
// The system server has to run all of the time, so it needs to be
// as efficient as possible with its memory usage.
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
System.loadLibrary("android_servers");
// 啟動(dòng)一些使用C++語言開發(fā)的系統(tǒng)服務(wù)么抗,
// com_android_server_SystemServer.cpp
// android_server_SystemServer_init1 方法
init1(args);
}
system_init.cpp # system_init
extern "C" status_t system_init()
{
LOGI("Entered system_init()");
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p\n", sm.get());
sp<GrimReaper> grim = new GrimReaper();
sm->asBinder()->linkToDeath(grim, grim.get(), 0);
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsurfaceflinger", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// Start the SurfaceFlinger
SurfaceFlinger::instantiate();
}
// Start the sensor service
SensorService::instantiate();
// On the simulator, audioflinger et al don't get started the
// same way as on the device, and we need to start them here
if (!proc->supportsProcesses()) {
// Start the AudioFlinger
AudioFlinger::instantiate();
// Start the media playback service
MediaPlayerService::instantiate();
// Start the camera service
CameraService::instantiate();
// Start the audio policy service
AudioPolicyService::instantiate();
}
// And now start the Android runtime. We have to do this bit
// of nastiness because the Android runtime initialization requires
// some of the core system services to already be started.
// All other servers should just start the Android runtime at
// the beginning of their processes's main(), before calling
// the init function.
LOGI("System server: starting Android runtime.\n");
AndroidRuntime* runtime = AndroidRuntime::getRuntime();
LOGI("System server: starting Android services.\n");
runtime->callStatic("com/android/server/SystemServer", "init2");
// If running in our own process, just go into the thread
// pool. Otherwise, call the initialization finished
// func to let this process continue its initilization.
if (proc->supportsProcesses()) {
LOGI("System server: entering thread pool.\n");
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
LOGI("System server: exiting thread pool.\n");
}
return NO_ERROR;
}
SystemServer#init2
public static final void init2() {
Slog.i(TAG, "Entered the Android system server!");
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
}
SystemServer#ServerThread#
@Override
public void run() {
Looper.prepare();
((ActivityManagerService)ActivityManagerNative.getDefault())
.systemReady(new Runnable() {
public void run() {
Slog.i(TAG, "Making services ready");
...
}
});
Looper.loop();
Slog.d(TAG, "System ServerThread is exiting!");
}