Android系统较为庞大,要搞清楚系统运行原理需要长期努力。系统启动部分看了几遍但没有总结,今天简单总结一下。

Android首先重点是启动zygote进程,这个进程来源于init.rc的读取,zygote进程主要用于孵化新的app程序,还包括启动android大量的服务SystemService

本人研究的源码是4.1的,其它版本的可能略有差异。


init.rc 文件作为启动配置重要的入口出,init.c将会读取这个文件,核心的相关进程也将开启。

/Android41/system/core/init/init.c

重点是解析了init.rc文件,并且开始处理相关指令。找到main入口,贴出部分代码

    mkdir("/dev", 0755);    mkdir("/proc", 0755);    mkdir("/sys", 0755);    mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");    mkdir("/dev/pts", 0755);    mkdir("/dev/socket", 0755);    mount("devpts", "/dev/pts", "devpts", 0, NULL);    mount("proc", "/proc", "proc", 0, NULL);    mount("sysfs", "/sys", "sysfs", 0, NULL);        /* indicate that booting is in progress to background fw loaders, etc */    close(open("/dev/.booting", O_WRONLY | O_CREAT, 0000));        /* We must have some place other than / to create the         * device nodes for kmsg and null, otherwise we won't         * be able to remount / read-only later on.         * Now that tmpfs is mounted on /dev, we can actually         * talk to the outside world.         */    open_devnull_stdio();    klog_init();    property_init();    get_hardware_name(hardware, &revision);    process_kernel_cmdline();#ifdef HAVE_SELINUX    INFO("loading selinux policy\n");    selinux_load_policy();#endif    is_charger = !strcmp(bootmode, "charger");    INFO("property init\n");    if (!is_charger)        property_load_boot_defaults();    INFO("reading config file\n");    init_parse_config_file("/init.rc"); //读取rc文件

前面的都是初始化关键目录和挂载文件系统,系统硬件设备,系统属性等。

找到Android41/system/core/rootdir/init.rc

这个文件里面还包括,ServiceManager IPC服务管理者启动,surfaceflinger图像服务,bootanim启动动画,media媒体服务等。

service zygote /system/bin/app_process -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 media    onrestart restart netd

app_process包括2个东西zygote和system server的启动

app_process启动代码在 frameworks/base/cmds/app_process/app_main.cpp
main中的主要代码。

    while (i < argc) {        const char* arg = argv[i++];        if (!parentDir) {            parentDir = arg;        } else if (strcmp(arg, "--zygote") == 0) {            zygote = true;            niceName = "zygote";        } else if (strcmp(arg, "--start-system-server") == 0) {            startSystemServer = true;        } else if (strcmp(arg, "--application") == 0) {            application = true;        } else if (strncmp(arg, "--nice-name=", 12) == 0) {            niceName = arg + 12;        } else {            className = arg;            break;        }    }    if (niceName && *niceName) {        setArgv0(argv0, niceName);        set_process_name(niceName);    }    runtime.mParentDir = parentDir;    if (zygote) {        <strong>runtime.start("com.android.internal.os.ZygoteInit",                startSystemServer ? "start-system-server" : "");</strong>    } else if (className) {        // Remainder of args get passed to startup class main()        runtime.mClassName = className;        runtime.mArgC = argc - i;        runtime.mArgV = argv + i;        runtime.start("com.android.internal.os.RuntimeInit",                application ? "application" : "tool");    } else {        fprintf(stderr, "Error: no class name or --zygote supplied.\n");        app_usage();        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");        return 10;    }

前面是解析传入的参数,判断是否启动zygote和RuntimeInit,AppRuntime是Android dvm 启动对象,

虚拟机的启动在/Android41/frameworks/base/core/jni/AndroidRuntime.cpp 里面包含了大量的初始化比如heap大小内存分配等,这里暂时不说。

先看ZygoteInit代码

/Android41/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

    public static void main(String argv[]) {        try {            // Start profiling the zygote initialization.            SamplingProfilerIntegration.start();            registerZygoteSocket();            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,                SystemClock.uptimeMillis());            preload();            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();            // If requested, start system server directly from Zygote            if (argv.length != 2) {                throw new RuntimeException(argv[0] + USAGE_STRING);            }            if (argv[1].equals("start-system-server")) {                startSystemServer();            } else if (!argv[1].equals("")) {                throw new RuntimeException(argv[0] + USAGE_STRING);            }            Log.i(TAG, "Accepting command socket connections");            if (ZYGOTE_FORK_MODE) {                runForkMode();            } else {                runSelectLoopMode();            }            closeServerSocket();        } catch (MethodAndArgsCaller caller) {            caller.run();        } catch (RuntimeException ex) {            Log.e(TAG, "Zygote died with exception", ex);            closeServerSocket();            throw ex;        }    }

zygote主要是孵化app的,通过启动一个socketServer来接受app启动的请求,app启动是靠ActivityManagerService来发送Socket通信的。

下面看看启动SystemService

    private static boolean startSystemServer()            throws MethodAndArgsCaller, RuntimeException {        /* 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,3006,3007",            "--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);            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) {            handleSystemServerProcess(parsedArgs);        }        return true;    }

这地方需要调用Zygote的静态方法

/Android41/libcore/dalvik/src/main/java/dalvik/system/Zygote.java 其实是需要调用对应的native方法.

forkSystemServer fork一个独立进程用于SystemServer

native方法在 /Android41/dalvik/vm/native/dalvik_system_zygote.cpp

fork成功后,就调用传入的参数com.android.server.SystemServer.java


SystemServer开启了Android应用层的大部分服务,包括电源管理,电池,网络 AMS WMS等。

frameworks/base/services/java/com/android/server/SystemServer 目录下面也包含了大量的相应的服务代码。


    public static final void init2() {        Slog.i(TAG, "Entered the Android system server!");        Thread thr = new ServerThread();        thr.setName("android.server.ServerThread");        thr.start();    }

init2函数是native方法

有 native public static void init1(String[] args);调用。

找到对应的底层代码。

/AndroidSource/Android41/frameworks/base/services/jni/com_android_server_SystemServer.cpp

namespace android {extern "C" int system_init();static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz){    system_init();}/* * JNI registration. */static JNINativeMethod gMethods[] = {    /* name, signature, funcPtr */    { "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 },//注册了init1方法};int register_android_server_SystemServer(JNIEnv* env){    return jniRegisterNativeMethods(env, "com/android/server/SystemServer",            gMethods, NELEM(gMethods));}}; // namespace android


system_init()是个外部函数,到那找到函数体?

/AndroidSource/Android41/frameworks/base/services/jni/Android.mk文件中有添加静态Library

LOCAL_SHARED_LIBRARIES := \    libandroid_runtime \    libandroidfw \    libcutils \    libhardware \    libhardware_legacy \    libnativehelper \    libsystem_server \    libutils \    libui \    libinput \    libskia \    libgui \    libusbhost \    libsuspend

system_server和android_runtime是个关键.

system_server 在/AndroidSource/Android41/frameworks/base/cmds/system_server 可以找到,可以看Android.mk文件知道模块都编译了那些文件

看System_init.cpp代码方法

extern "C" status_t system_init(){    ALOGI("Entered system_init()");    sp<ProcessState> proc(ProcessState::self());    sp<IServiceManager> sm = defaultServiceManager();    ALOGI("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();    }    property_get("system_init.startsensorservice", propBuf, "1");    if (strcmp(propBuf, "1") == 0) {        // Start the sensor service        SensorService::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.    ALOGI("System server: starting Android runtime.\n");    AndroidRuntime* runtime = AndroidRuntime::getRuntime();    ALOGI("System server: starting Android services.\n");    JNIEnv* env = runtime->getJNIEnv();    if (env == NULL) {        return UNKNOWN_ERROR;    }    jclass clazz = env->FindClass("com/android/server/SystemServer");    if (clazz == NULL) {        return UNKNOWN_ERROR;    }    jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");    if (methodId == NULL) {        return UNKNOWN_ERROR;    }    env->CallStaticVoidMethod(clazz, methodId);    ALOGI("System server: entering thread pool.\n");    ProcessState::self()->startThreadPool();    IPCThreadState::self()->joinThreadPool();    ALOGI("System server: exiting thread pool.\n");    return NO_ERROR;}

上面是jni相关操作,并不难理解。找到com.android.server.SystemServer类,执行init2方法

init2方法启动了线程开始了Android服务的加载和启动。


基本流程就是启动Zygote进程,虚拟机的创建,然后是SystemServer加载服务,当然还同时启动了其它服务包括ServiceManager,SurfaceFlinger程序。

下一部分详细分析SystemServer启动和ActivityManagerService启动应用程序。


画个图容易记住。




本文粗浅的介绍了一下Android启动流程,若有问题,请指出 谢谢。




更多相关文章

  1. 【转】Android内核开发:如何统计系统的启动时间
  2. Android(安卓)获取ROOT权限原理解析
  3. 定制android设备启动后进入的初始界面
  4. Android本地视频播放器开发--ffmpeg解码视频文件中的音频(1)
  5. Android(安卓)AsyncTask完全解析,带你从源码的角度彻底理解
  6. 浅谈Java中Collections.sort对List排序的两种方法
  7. NPM 和webpack 的基础使用
  8. Python list sort方法的具体使用
  9. 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程

随机推荐

  1. jquery插件ztree的总结
  2. jQuery -> 获取后代元素的三种方法
  3. JQuery操作<select>元素
  4. web前端复习(二):js日期操作,实现时间显
  5. Jquery验证插件,获取错误字符串
  6. 打开后,JQuery ui对话框调整大小
  7. jQuery Sortable - 事件被调用太多次了
  8. Ajax_04之jQuery中封装的Ajax函数
  9. 从零搭建个人博客(3)-如何在webpack环境
  10. jquery过滤class为aa的div