本文主要介绍 Android 系统的启动过程,以 Androidinit 进程之后部分为主, init 之前部分同标准 Linux 内核启动完全相同。于 Android 启动过程复杂,涉及 C C++ java 部分内容,本文以流程分析为主线旨在让大家在分析 Android 系统时有个清晰的思路。鉴于本人水平有限,如有阐述不正之处,还请不吝指正,感激不尽!

系统启动大致可分为一下几个阶段:

  • bootloader---初始化、从Flash读取Kernel镜像及一些必须的配置信息,引导kernel启动

  • linuxkernel启动linux内核

  • init进程启动

  • init进程读取init.rc启动必要的daemon程序,如:adbdvoldnetd、等

  • init进程启动servicemanager---随后详细分析其过程

  • init进程启动zygote ---随后详细分析其过程

  • JAVA部分的Service启动
  • init进程启动mediaserver---多媒体本地服务启动

本文主要分析android部分的启动,涉及范围为servicemanager启动到android系统的Java部分的Service;

    1. 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指向的链表来维护,其主要包括servicenamehandle等;其中namehandle都是添加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进程进入无限循环,不再返回,执行孵化工作具体下面接着分析 */


未完待叙-----

更多相关文章

  1. Android(安卓)Service,startService binderService 以及 AIDL
  2. Android(安卓)如何将定制的Launcher成为系统中唯一的Launcher
  3. 用C/C++开发android应用
  4. Android多进程使用及其带来的问题
  5. Android应用程序注册广播接收器(registerReceiver)的过程分析
  6. Android之AIDL进程之间的通信
  7. Android应用程序注冊广播接收器(registerReceiver)的过程分析
  8. Android属性系统
  9. 箭头函数的基础使用

随机推荐

  1. Android(安卓)ImageView的scaleType属性
  2. Android(安卓)Duplicate files copied in
  3. EditText属性详解
  4. 【Android(安卓)应用开发】 Ubuntu 安装
  5. android 模拟抢红包 原理
  6. Android——init.rc脚本
  7. 探讨android图片资源的抖动处理和格式转
  8. Android中ExpandableListView控件基本使
  9. 小记初学android过程中遇到的小问题(andro
  10. Android的用户界面