看了很多相关博客,今天也来自己梳理以下~~~
Android从Linux系统启动

init进程启动
Native服务启动
System Server, Android 服务启动
Home启动

总体启动框架:

2012111315182764.jpg

Init进程启动

首先uboot引导Linux内核启动,然后在用户空间中启动init进程,再启动其他系统进程。在系统启动完成完成后,init将变为守护进程监视系统其他进程。Android是基于Linux的操作系统,所以init也是Android系统中用户空间的第一个进程,它的进程号是1。

Init的主要职责是:

作为守护进程
解析核执行init.rc文件
生成设备节点
属性服务

源码在/system/core/init/init.c

int main(int argc, char **argv) {    //启动uevent守护进程    if (!strcmp(basename(argv[0]), "ueventd"))        return ueventd_main(argc, argv);    //启动看门狗守护进程    if (!strcmp(basename(argv[0]), "watchdogd"))        return watchdogd_main(argc, argv);    umask(0);    //创建并挂在启动所需的文件目录     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);    close(open("/dev/.booting", O_WRONLY | O_CREAT, 0000));    //重定向标准输入/输出/错误输出到/dev/_null_    open_devnull_stdio();    klog_init();//log初始化     property_init();//属性服务初始化      //从/proc/cpuinfo中读取Hardware名,在后面的mix_hwrng_into_linux_rng_action函 数中会将hardware的值设置给属性ro.hardware      get_hardware_name(hardware, &revision);    //导入并设置内核变量      process_kernel_cmdline();    ......    INFO("property init\n");    if (!is_charger)        property_load_boot_defaults();    INFO("reading config file\n");    init_parse_config_file("/init.rc");//解析init.rc配置文件    /*      * 解析完init.rc后会得到一系列的action等,下面的代码将执行处于early-init阶段的 action。      * init将action按照执行时间段的不同分为early-init、init、early-boot、boot。      * 进行这样的划分是由于有些动作之间具有依赖关系,某些动作只有在其他动作完成后才能执行,所以就有了先后的区别。      * 具体哪些动作属于哪个阶段是在init.rc中的配置决定的      */     action_for_each_trigger("early-init", action_add_queue_tail);    ......    for(;;) {//init进入无限循环        ......        execute_one_command();        restart_processes();//重启已经死去的进程         ......         nr = poll(ufds, fd_count, timeout); //等待事件发生        if (nr <= 0)            continue;        for (i = 0; i < fd_count; i++) {            if (ufds[i].revents == POLLIN) {                if (ufds[i].fd == get_property_set_fd())//处理属性服务事件                     handle_property_set_fd();                else if (ufds[i].fd == get_keychord_fd())//处理keychord事件                    handle_keychord();                else if (ufds[i].fd == get_signal_fd())                    handle_signal();//处理SIGCHLD信号事件            }        }    }    return 0;}

看看init.rc脚本

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

ps:(1)这里描述了孵化器zygote的启动(init是zygote的父进程,而系统服务进程system_server和其他所有的com.xxx结尾的应用程序都是从zygote fork 而来)。
(2)前面的关键字service告诉init进程创建一个名为"zygote"的进程,这个zygote进程要执行的程序是/system/bin/app_process,后面是要传给app_process的参数。最后的一系列onrestart关键字表示这个zygote进程重启时需要执行的命令。

了解了这个信息之后,我们就知道Zygote进程要执行的程序便是system/bin/app_process了,它的源代码位于frameworks/base/cmds/app_process/app_main.cpp文件中,入口函数是main。

int main(int argc, char* const argv[]){     ......    // These are global variables in ProcessState.cpp    mArgC = argc;    mArgV = argv;    mArgLen = 0;    for (int i=0; i

main函数的主要作用就是创建一个AppRuntime变量,然后调用它的start函数。它的定义也在同一文件app_main.cpp下面class AppRuntime : public AndroidRuntime
(AndroidRuntime的源码在/frameworks/base/core/jni下,它是抽象基类);
在AndroidRuntime.h中定义了4种启动模式

enum StartMode {        Zygote,//启动Zygote        SystemServer,//启动系统服务        Application,//启动应用程序        Tool,//    };

再看看具体的start函数做了什么

/* * Start the Android runtime.  This involves starting the virtual machine * and calling the "static void main(String[] args)" method in the class * named by "className". * * Passes the main function two arguments, the class name and the specified * options string. *///上面的解释是开始android运行时环境。将开始虚拟机,然后用类似反射的机制去调用类名为参数className的main()方法!void AndroidRuntime::start(const char* className, const char* options){    if (strcmp(options, "start-system-server") == 0) {        /* 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.");            return;        }        setenv("ANDROID_ROOT", rootDir, 1);    }    /* start the virtual machine */    JniInvocation jni_invocation;    jni_invocation.Init(NULL);    JNIEnv* env;    if (startVm(&mJavaVM, &env) != 0) {//开启虚拟机        return;    }    onVmCreated(env);    /*     * Register android functions. 注册本地native函数     */    if (startReg(env) < 0) {        ALOGE("Unable to register all android natives\n");        return;    }    jclass stringClass;    jobjectArray strArray;    jstring classNameStr;    jstring optionsStr;    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);    optionsStr = env->NewStringUTF(options);    env->SetObjectArrayElement(strArray, 1, optionsStr);    /*     * Start VM.  This thread becomes the main thread of the VM, and will     * not return until the VM exits.     */    //激活虚拟机,当前线程变成虚拟机下的主线程。    char* slashClassName = toSlashClassName(className);    jclass startClass = env->FindClass(slashClassName);    if (startClass == NULL) {        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);    } else {        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",            "([Ljava/lang/String;)V");        if (startMeth == NULL) {            ALOGE("JavaVM unable to find main() in '%s'\n", className);            /* keep going */        } else {            env->CallStaticVoidMethod(startClass, startMeth, strArray);        }    }  }

通过源代码的分析知道,其实上面主要是给一个应用程序分配一个虚拟机环境(虚拟机拷贝),然后通过JNI的方式去调java里某个className类的main()方法。

还记得runtime.start("com.android.internal.os.ZygoteInit", startSystemServer ? "start-system-server" : "");

实际执行com.android.internal.os.ZygoteInit类的main()(源码地址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[1].equals("start-system-server")) {                startSystemServer();//启动system_server进程              } else if (!argv[1].equals("")) {                throw new RuntimeException(argv[0] + USAGE_STRING);            }          ......            runSelectLoop();            closeServerSocket();        } catch (MethodAndArgsCaller caller) {            caller.run();        } catch (RuntimeException ex) {            ......        }    }

它主要作了三件事情:
1、调用registerZygoteSocket函数创建了一个socket接口,用来和ActivityManagerService通讯;
2、调用startSystemServer函数来启动SystemServer组件;
3、调用runSelectLoopMode函数进入一个无限循环在前面创建的socket接口上等待ActivityManagerService请求创建新的应用程序进程。

这里Zygote进程初始化完毕,开始大循环了~~~
仔细分析下第二步startSystemServer启动系统服务组件

/**     * Prepare the arguments and fork for the system server process.     */    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,1032,3001,3002,3003,3006,3007",            "--capabilities=" + capabilities + "," + capabilities,            "--runtime-init",            "--nice-name=system_server",            "com.android.server.SystemServer",        };        ZygoteConnection.Arguments parsedArgs = null;        int pid;        try {            parsedArgs = new ZygoteConnection.Arguments(args);            ......            /* 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) {            ......        }        /* For child process */        if (pid == 0) {//pid==0说明是子进程,父进程为Zygote             handleSystemServerProcess(parsedArgs);        }        return true;    }

在startSystemServer中先设置了Zygote.forkSystemServer所需的参数,然后通过forkSystemServer方法fork出SystemServer进程,最后通过handleSystemServerProcess处理新进程中的琐事。

首先看一下参数:

1、setuid=1000,这里1000代表SYSTEM_UID,即系统进程,关于进程ID的说明可以参见:/frameworks/base/core/java/android/os/Process.java。
2、nice-name=system_server表示制定进程的名字为“system_server”
3、com.android.server.SystemServer表示SystemServer类的位置。

接下来看一下forkSystemServer的实现:
libcore/dalvik/src/main/java/dalvik/system/Zygote.java

/**     * Special method to start the system server process. In addition to the     * common actions performed in forkAndSpecialize, the pid of the child     * process is recorded such that the death of the child process will cause     * zygote to exit.     * 注意由zygote fork 出的system_service进程如果死了,则zygote进程也退出     */    public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {        preFork();        int pid = nativeForkSystemServer(                uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);        postFork();        return pid;    }    native public static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags,            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);

forkSystemServer最后调nativeForkSystemServer,而它是通过JNI实现,源码:/dalvik/vm/native/dalvik_system_Zygote.cpp:

static void Dalvik_dalvik_system_Zygote_forkSystemServer(        const u4* args, JValue* pResult){    pid_t pid;    pid = forkAndSpecializeCommon(args, true);    /* The zygote process checks whether the child process has died or not. */    if (pid > 0) {//pid大于0,说明是在父进程中,Zygote进程往下执行        int status;        gDvm.systemServerPid = pid;        /* There is a slight window that the system server process has crashed         * but it went unnoticed because we haven't published its pid yet. So         * we recheck here just to make sure that all is well.         */        if (waitpid(pid, &status, WNOHANG) == pid) {            ALOGE("System server process %d has died. Restarting Zygote!", pid);            kill(getpid(), SIGKILL);//一旦上面的等待返回,说明进程pid(system_server)已终止,此时Zygote杀死自己          }    }    RETURN_INT(pid);}//native函数注册const DalvikNativeMethod dvm_dalvik_system_Zygote[] = {    { "nativeFork", "()I",      Dalvik_dalvik_system_Zygote_fork },    { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;)I",      Dalvik_dalvik_system_Zygote_forkAndSpecialize },    { "nativeForkSystemServer", "(II[II[[IJJ)I",      Dalvik_dalvik_system_Zygote_forkSystemServer },    { NULL, NULL, NULL },};

SystemServer创建之后交给handleSystemServerProcess处理!

回到 frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

   /**     * Finish remaining work for the newly forked system server process.     * 完成新建的system server进程的剩余工作     */    private static void handleSystemServerProcess(            ZygoteConnection.Arguments parsedArgs)            throws ZygoteInit.MethodAndArgsCaller {        closeServerSocket();//关闭从Zygote复制过来的socket         // set umask to 0077 so new files and directories will default to owner-only permissions.        Libcore.os.umask(S_IRWXG | S_IRWXO);//设置文件的默认权限,去除文件所有者之外的权限        if (parsedArgs.niceName != null) {            Process.setArgV0(parsedArgs.niceName);        }        if (parsedArgs.invokeWith != null) {            WrapperInit.execApplication(parsedArgs.invokeWith,                    parsedArgs.niceName, parsedArgs.targetSdkVersion,                    null, parsedArgs.remainingArgs);        } else {            /*             * Pass the remaining arguments to SystemServer.传递剩下的参数给SystemServer             */            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);        }        /* should never reach here */    }

最后将参数往下传给RuntimeInit.zygoteInit(,)
源码:frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

   /**     * The main function called when started through the zygote process. This     * could be unified with main(), if the native code in nativeFinishInit()     * were rationalized with Zygote startup.     */    public static final void zygoteInit(int targetSdkVersion, String[] argv)            throws ZygoteInit.MethodAndArgsCaller {        if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");        redirectLogStreams();//将System.out 和 System.err 输出重定向到Android 的Log系统     /*      * 初始化了一些系统属性,其中最重要的一点就是设置了一个未捕捉异常的handler,      * 当代码有任何未知异常,就会执行它,      * 调试过Android代码的同学经常看到的"*** FATAL EXCEPTION IN SYSTEM PROCESS" 打印就出自这里      */          commonInit();    /*      * 最终会调用app_main的onZygoteInit函数      * 这里的作用是在新进程中引入Binder,也就说通过nativeZygoteInit以后,新的进程就可以使用Binder进程通信了      */          nativeZygoteInit();        applicationInit(targetSdkVersion, argv);//应用初始化    }      private static void applicationInit(int targetSdkVersion, String[] argv)            throws ZygoteInit.MethodAndArgsCaller {        // If the application calls System.exit(), terminate the process        // immediately without running any shutdown hooks.  It is not possible to        // shutdown an Android application gracefully.  Among other things, the        // Android runtime shutdown hooks close the Binder driver, which can cause        // leftover running threads to crash before the process actually exits.        nativeSetExitWithoutCleanup(true);        // We want to be fairly aggressive about heap utilization, to avoid        // holding on to a lot of memory that isn't needed.        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);        final Arguments args;        try {            args = new Arguments(argv);        } catch (IllegalArgumentException ex) {            Slog.e(TAG, ex.getMessage());            // let the process exit            return;        }        // Remaining arguments are passed to the start class's static main        invokeStaticMain(args.startClass, args.startArgs);    }

这里invokeStaticMain的args.startClass的值为com.android.server.SystemServer。接下来SystemServer类的main函数将会被调用,我太机智了~。

源码:frameworks/base/services/java/com/android/server/SystemServer.java

public static void main(String[] args) {        /*         * In case the runtime switched since last boot (such as when         * the old runtime was removed in an OTA), set the system         * property so that it is in sync.         */        SystemProperties.set("persist.sys.dalvik.vm.lib",                             VMRuntime.getRuntime().vmLibrary());        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {//调整时间            Slog.w(TAG, "System clock is before 1970; setting to 1970.");            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);        }         ......        // Mmmmmm... more memory!        dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();        // 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);        Environment.setUserRequired(true);        System.loadLibrary("android_servers");        Slog.i(TAG, "Entered the Android system server!");        // Initialize native services.        nativeInit();//初始化本地所以服务 > SensorService        // This used to be its own separate thread, but now it is        // just the loop we run on the main thread.        ServerThread thr = new ServerThread();        thr.initAndLoop();    }

在main中会加载libandroid_servers.so库,然后调用nativeInit初始化native层的Service。
ServerThread初始化一堆android服务。

小结一下:

  1. Linux的init在启动若干守护进程之后,就启动了Android的runtime和zygote,Zygote进程负责后续Android应用程序框架层的其它进程的创建和启动工作。
  1. Zygote进程会首先创建一个SystemServer进程,SystemServer进程负责启动系统的关键服务,如包管理服务PackageManagerService和应用程序组件管理服务ActivityManagerService。
  2. 当我们需要启动一个Android应用程序时,ActivityManagerService会通过Socket进程间通信机制,通知Zygote进程为这个应用程序创建一个新的进程。

更多相关文章

  1. Android下的binder机制和IPC原理
  2. Android(安卓)技能图谱学习路线
  3. Task和Activity相关
  4. Android(安卓)开发艺术探索笔记(18)
  5. Android(安卓)Service 详解(上)
  6. Android(安卓)代理自动配置PAC研究
  7. Android的Activity的启动流程分析
  8. AndroidO SystemUI-QuickSettings
  9. 如何让android的service一直在后台运行

随机推荐

  1. mysql中binglog底层原理分析
  2. MySQL利用Navicat导出数据字典
  3. mysql故障---is not allowed to connect
  4. MYSQL导入导出命令详解
  5. windows安装mysql 遇到错误193的解决办法
  6. linux安装mysql、tomcat和jdk1.7、Androi
  7. 向数据库添加1的PHP Onclick事件(SQL)
  8. 在4个表上使用JOIN和GROUP BY进行复杂的S
  9. 再放100分,问:你是如何备份大于5M的mysql
  10. Visual C ++ 2010连接到MySQL