本文主要介绍 Android 系统的启动过程,以 Androidinit 进程之后部分为主, init 之前部分同标准 Linux 内核启动完全相同。于 Android 启动过程复杂,涉及 C 、 C++ 及 java 部分内容,本文以流程分析为主线旨在让大家在分析 Android 系统时有个清晰的思路。鉴于本人水平有限,如有阐述不正之处,还请不吝指正,感激不尽!
系统启动大致可分为一下几个阶段:
bootloader---初始化、从Flash读取Kernel镜像及一些必须的配置信息,引导kernel启动
linuxkernel启动linux内核
init进程启动
init进程读取init.rc启动必要的daemon程序,如:adbd、vold、netd、等
init进程启动servicemanager---随后详细分析其过程
init进程启动zygote ---随后详细分析其过程
- JAVA部分的Service启动
init进程启动mediaserver---多媒体本地服务启动
本文主要分析android部分的启动,涉及范围为servicemanager启动到android系统的Java部分的Service;
servicemanager启动
首先看init.rc中的servicemanager启动命令如下:
serviceservicemanager /system/bin/servicemanager
其执行源码位于:frameworks/base/cmds/servicemanager
文件:Android.mk bctest.c binder.c binder.h service_manager.c
service_manager.c main函数: struct binder_state { int fd; void *mapped; unsigned mapsize; }; #define BINDER_SERVICE_MANAGER ((void*) 0) int main(int argc, char **argv) { struct binder_state *bs; void *svcmgr = BINDER_SERVICE_MANAGER; bs = binder_open(128*1024); //打开binder设备,执行binder相应的初始化,构建一个binder_state对象 if (binder_become_context_manager(bs)) { //将这个binder_state设置为manger,整个系统仅此一个manger LOGE("cannot become context manager (%s)\n", strerror(errno)); return -1; } svcmgr_handle = svcmgr; binder_loop(bs, svcmgr_handler); /*循环处理针对上面定义的bs对象的所有操作,svcmgr_handler作为处理函数,真正处理针对这个系统唯一的manger binder对象的所有操作; 总结svcmgr_handler处理的操作有: 获取service 查看service是否存在 添加service 列出service清单 这是servicemanager 的核心,用的最多的就是获取、添加;当然从具体的实现代码可以看出,service的实现完全依赖与binder机制,设置该函数构建的binder对象为系统唯一的manager是通过ioctl操作binder驱动来实现的; */ return 0; }
svcmgr_handler 的处理函数如下:
int svcmgr_handler(struct binder_state *bs, struct binder_txn *txn, struct binder_io *msg, struct binder_io *reply) { struct svcinfo *si; uint16_t *s; unsigned len; void *ptr; uint32_t strict_policy; if (txn->target != svcmgr_handle) return -1; // Equivalent to Parcel::enforceInterface(), reading the RPC // header with the strict mode policy mask and the interface name. // Note that we ignore the strict_policy and don't propagate it // further (since we do no outbound RPCs anyway). strict_policy = bio_get_uint32(msg); s = bio_get_string16(msg, &len); if ((len != (sizeof(svcmgr_id) / 2)) || memcmp(svcmgr_id, s, sizeof(svcmgr_id))) { fprintf(stderr,"invalid id %s\n", str8(s)); return -1; } switch(txn->code) { case SVC_MGR_GET_SERVICE: case SVC_MGR_CHECK_SERVICE: s = bio_get_string16(msg, &len); ptr = do_find_service(bs, s, len); if (!ptr) break; bio_put_ref(reply, ptr); return 0; case SVC_MGR_ADD_SERVICE: s = bio_get_string16(msg, &len); ptr = bio_get_ref(msg); if (do_add_service(bs, s, len, ptr, txn->sender_euid)) return -1; break; case SVC_MGR_LIST_SERVICES: { unsigned n = bio_get_uint32(msg); si = svclist; while ((n-- > 0) && si) si = si->next; if (si) { bio_put_string16(reply, si->name); return 0; } return -1; } default: LOGE("unknown code %d\n", txn->code); return -1; } bio_put_uint32(reply, 0); return 0; } struct svcinfo { struct svcinfo *next; void *ptr; struct binder_death death; unsigned len; uint16_t name[0]; }; struct svcinfo *svclist = 0;
所有的service由全局指针变量svclist指向的链表来维护,其主要包括service的name和handle等;其中name和handle都是添加service时通过binder传递过来的;具体可依据前面路径给粗的代码分析;
至此,servicemanger启动分析完成,该进程一直在binder_loop的死循环中等待处理service相关的各种请求;
2. Zygote启动
由init.rc可知接下来init进程会启动zygote
servicezygote /system/bin/app_process -Xzygote /system/bin --zygote--start-system-server
由启动命令可知zygote实际执行的是app_process
其源码位于:frameworks/base/cmds/app_process
文件:Android.mk app_main.cpp只有一个app_main.cpp文件
我们先进入该文件的main函数分析:
int main(int argc, const char* const argv[]) { // These are global variables in ProcessState.cpp mArgC = argc; mArgV = argv; mArgLen = 0; for (int i=0; i
下面进一步分析: runtime.start("com.android.internal.os.ZygoteInit",startSystemServer);源码位置:AndroidRuntime.cpp(frameworks\base\core\jni)
void AndroidRuntime::start(const char* className, const bool startSystemServer) { LOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n", className != NULL ? className : "(unknown)"); 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 */ //启动一个Dalvic虚拟机,需要执行许多寄存器等方面的复杂工作,这里不做分析,后面有时间单独分析,我们简单认为启动了一个虚拟机即可; 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. */ /*我们目前只有有一个类名,我们需要调用相关函数以一个String类型的数组来保存其参数,下面来构建这个参数数组*/ 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); /* 新的string class strArray[0] = “true”; strArray[1] = “com.android.internal.os.ZygoteInit”; */ /* * 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 = '/'; /* slashClassName = “com/android/internal/os/ZygoteInit” */ startClass = env->FindClass(slashClassName); if (startClass == NULL) { LOGE("JavaVM unable to locate class '%s'\n", slashClassName); /* keep going */ } else { /*这个参数决定了我们接下来执行的是zygoteInit.java的main函数 */ startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V"); if (startMeth == NULL) { LOGE("JavaVM unable to find main() in '%s'\n", className); /* keep going */ } else { env->CallStaticVoidMethod(startClass, startMeth, strArray); /*这个函数启动Dalvik虚拟机后执行的最重要的函数就是这个函数,通过jni调用 com/android/internal/os/ZygoteInit包的main函数, 参数 strArray[0] = “true”;strArray[1] = “com.android.internal.os.ZygoteInit”; 调用之后不再返回这里;*/ #if 0 if (env->ExceptionCheck()) threadExitUncaughtException(env); #endif } } LOGD("Shutting down VM\n"); if (mJavaVM->DetachCurrentThread() != JNI_OK) LOGW("Warning: unable to detach main thread\n"); if (mJavaVM->DestroyJavaVM() != 0) LOGW("Warning: VM did not shut down cleanly\n"); bail: free(slashClassName); }
下面我们继续分析 zygoteInit 的 main 函数,这也正是 zygote 进程进一步执行的路线:源码位置:frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
publicstatic void main(String argv[]) { try{ VMRuntime.getRuntime().setMinimumHeapSize(5* 1024 * 1024); //Start profiling the zygote initialization. SamplingProfilerIntegration.start(); registerZygoteSocket(); /* 注册zygotesocket */ EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, SystemClock.uptimeMillis()); preloadClasses(); /* 加载必要的类 */ //cacheRegisterMaps(); preloadResources(); /* 加载必要的资源 */ EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, SystemClock.uptimeMillis()); //Finish profiling the zygote initialization. SamplingProfilerIntegration.writeZygoteSnapshot(); //Do an initial gc to clean up after startup gc(); /*初始化GC垃圾回收机制*/ //If requested, start system server directly from Zygote if(argv.length != 2) { thrownew RuntimeException(argv[0] + USAGE_STRING); } /* 上阶段分析是传递过来的参数列表的第二个参数,也就是startsystemserver=”true” 启动systemserver, 在startSystemServer函数中会fork一个新的进程命名为system_server执行的是com.android.server包中的SystemServer.java文件中的main函数, 源码位置:frameworks/base/services/java/com/android/server/,具体功能后面分析;*/ if(argv[1].equals("true")) { startSystemServer(); }else if (!argv[1].equals("false")) { thrownew RuntimeException(argv[0] + USAGE_STRING); } /*Zygote 进程继续执行,这也正是Zygote进程的主要功能就是孵化新的进程 */ Log.i(TAG,"Accepting command socket connections"); if(ZYGOTE_FORK_MODE) { /* ZYGOTE_FORK_MODE 永远为flase */ runForkMode(); }else { runSelectLoopMode(); /* Zygote进程进入无限循环,不再返回,执行孵化工作具体下面接着分析 */ } closeServerSocket(); }catch (MethodAndArgsCaller caller) { caller.run(); }catch (RuntimeException ex) { Log.e(TAG,"Zygote died with exception", ex); closeServerSocket(); throwex; } }
从这里开始android启动分为两条线走,分别是:
startSystemServer(); ---------- Zygote的子进程
runSelectLoopMode(); /* Zygote进程进入无限循环,不再返回,执行孵化工作具体下面接着分析 */
未完待叙-----