Android(安卓)启动过程分析 (一)
本文主要介绍 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<argc; i++) { mArgLen += strlen(argv[i]) + 1; } mArgLen--; AppRuntime runtime; const char *arg; const char *argv0; argv0 = argv[0]; // Process command line arguments/* 实际真正执行的命令: system/bin/app_process -Xzygote /system/bin --zygote –start-system-serverargc = 5;argv[0] = “system/bin/app_process”;argv[1] = “-Xzygote”;argv[2] = “/system/bin”;argv[3] = “--zygote”;argv[4] = “–start-system-server”;*/ // ignore argv[0] argc--; argv++;/* 此时 argc = 4 ,argv[0] 指向 -Xzygote,以此类推 */ // Everything up to '--' or first non '-' arg goes to the vm int i = runtime.addVmArguments(argc, argv);/* 经过runtime.addVmArguments()函数处理返回的 i=1,这里不列出该函数的详细代码,如有兴趣请查源码分析 */ // Next arg is parent directory if (i < argc) { runtime.mParentDir = argv[i++];/* runtime.mParentDir = argv[1] = “/system/bin” ,之后 i=2 */ } // Next arg is startup classname or "--zygote" if (i < argc) { arg = argv[i++]; if (0 == strcmp("--zygote", arg)) { bool startSystemServer = (i < argc) ? strcmp(argv[i], "--start-system-server") == 0 : false;/* startSystemServer = true ,这个bool变量决定着后面执行runtime.start时是否启动systemserver,其实就是启动java 部分的所有service,这里启动的所有service会被添加到前面的servicemanager的service 列表中,并由其来进行管理源码位置:frameworks\base\services\java\com\android\server\* */ setArgv0(argv0, "zygote"); set_process_name("zygote"); //设置进程名 runtime.start("com.android.internal.os.ZygoteInit", startSystemServer);//执行AndroidRuntime::start函数,不再返回,改进成就是zygote进程 } else { set_process_name(argv0); runtime.mClassName = arg; // Remainder of args get passed to startup class main() runtime.mArgC = argc-i; runtime.mArgV = argv+i; LOGV("App process is starting with pid=%d, class=%s.\n", getpid(), runtime.getClassName()); runtime.start(); } } else { LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied."); fprintf(stderr, "Error: no class name or --zygote supplied.\n"); app_usage(); return 10; }}
下面进一步分析: 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 startupgc(); /*初始化GC垃圾回收机制*///If requested, start system server directly from Zygoteif(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进程进入无限循环,不再返回,执行孵化工作具体下面接着分析 */
未完待叙-----
更多相关文章
- Android(安卓)Service,startService binderService 以及 AIDL
- Android(安卓)如何将定制的Launcher成为系统中唯一的Launcher
- 用C/C++开发android应用
- Android多进程使用及其带来的问题
- Android应用程序注册广播接收器(registerReceiver)的过程分析
- Android之AIDL进程之间的通信
- Android应用程序注冊广播接收器(registerReceiver)的过程分析
- Android属性系统
- 箭头函数的基础使用