android 启动流程到SystemServer

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/michael_yt/article/details/78603600

本篇博客基于 android7.1 主要介绍android启动流程中,从init开始到启动SystemServer结束为止,整个流程中各个方法里面主要做了哪些初始化操作,以便于对整个系统的启动有一定的了解。

整体介绍图

这里写图片描述
图片来源于http://blog.csdn.net/dd864140130/article/details/57624948

整体流程图

这里写图片描述

流程中各部分的实现细节

基于Linux内核的android系统,在内核初始化完成后将创建第一个用户进程Init,实现了内核空间到用户空间的转变

init.cpp

int main(int argc, char** argv) {
    if (is_first_stage) {
        //挂载基本的四类文件系统,tmpfs、devpts、proc、sysfs
        mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
        mkdir("/dev/pts", 0755);
        mkdir("/dev/socket", 0755);
        mount("devpts", "/dev/pts", "devpts", 0, NULL);
        #define MAKE_STR(x) __STRING(x)
        mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
        mount("sysfs", "/sys", "sysfs", 0, NULL);
    }
    ......省略部分代码
    open_devnull_stdio();//将标准输入输出,错误输出重定向到/dev/_null_设备中
    klog_init(); //初始化内核log系统
    property_init(); //初始化属性服务
    // If arguments are passed both on the command line and in DT,
    // properties set in DT always have priority over the command-line ones.
    process_kernel_dt();
    process_kernel_cmdline();
    selinux_initialize(is_first_stage); //初始化selinux
    parser.ParseConfig("/init.rc"); //解析并执行init.rc文件
    am.QueueEventTrigger("early-init"); //执行init.rc中的early-init action
    am.QueueEventTrigger("init"); //执行init.rc中的init action
    am.QueueEventTrigger("late-init"); //执行init.rc中的late-init
    ......省略部分代码
    restart_processes();//启动ServiceManager
    return 0;
}

init.rc

import <path>  //用来引入一个要解析的其他配置文件,通常用于当前配置文件的扩展,在当前文件解析完成后再解析 

on <trgger> [&& <trigger>]* //trgger触发器,事件触发:通过trigger”命令或QueueEventTrigger()触发、属性触发:指定属性的变量值变成指定值时触发,其格式为property:<name>=*

   <command> //Commands代表一组命令,在为Action设置了触发器后,就需要为其定义一组命令(command)了
   ...

service <name> <pathname> [ <argument> ]* //Service:是一些在系统初始化时就启动或者退出时需要重启的程序、name:service名字、patchname:执行程序路径、argument:给执行程序的配置参数

        <option> //option用来修饰服务,决定了服务在什么时候运行以及怎样运行
        ...

//例子
import /init.${ro.zygote}.rc //引入了zygote
on early-init
    # Set init and its forked children's oom_adj.
    write /proc/1/oom_score_adj -1000

    # Disable sysrq from keyboard
    write /proc/sys/kernel/sysrq 0
service healthd /sbin/healthd
    class core
    critical
    seclabel u:r:healthd:s0
    group root system wakelock

以上具体的command和option的含义请参考system/core/init/readme.txt中的官方解释

init.zygote64.rc

在init.rc中,Zygote进程被启动.Zygote进程是其他所有进程的孵化器.init.rc通过include引入init.zygote.rc,这里以init.zygote64.rc为例:

service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server //创建一个名为zygote的进程服务,它的执行程序路径为/system/bin/app_process64,后面的是它的参数,启动zygote和启动systemserver
    class main  //为当前service设定一个类别.相同类别的服务将会同时启动或者停止,默认类名是default.
    socket zygote stream 660 root system // 创建一个名为zygote的socket,,该socket用来实现进程间的通信,当新启动一个应用时,ActivityManagerService想向该Socket发起请求,请求zygote进程fork出一个新的进程.
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on  
    onrestart restart audioserver   // 当服务重启时执行该命令
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart netd
    writepid /dev/cpuset/foreground/tasks // 当fork一个子进程时,写子进程的pid到一个给定的文件。是给cgroup/cpuset使用

通过上面init.rc中关于zygote的AIL语言分析,我们可以知道接下来它会执行/system/bin/app_process,
位于/frameworks/base/cmds/app_process/app_main.cpp,其入口函数是main():

app_main.cpp

int main(int argc, char* const argv[])
{
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv)); //创建AppRuntime 
    while (i < argc) {
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true; //根据init.zygote64.rc中的配置设置启动zygote
            niceName = ZYGOTE_NICE_NAME;
        } else if (strcmp(arg, "--start-system-server") == 0) {
            startSystemServer = true; //根据init.zygote64.rc中的配置设置启动SystemServer
            ......省略部分代码
    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);// 通过AppRuntime启动ZygoteInit
        .......省略部分代码

因为AppRuntime继承自AndroidRuntime,所以最终调用的是AndroidRuntime中的start方法

AppRuntime.cpp

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
    /* start the virtual machine */
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL); //创建JniInvocation并执行Init方法,通过读取persist.sys.dalvik.vm.lib.2 这个属性值来判断是创建Dalvik还是ART虚拟机,libart.so ART、libdvm.so Dalvik
    JNIEnv* env;
    if (startVm(&mJavaVM, &env, zygote) != 0) { //启动虚拟机
        return;
    }
    onVmCreated(env);

    /*
     * Register android functions.
     */
    if (startReg(env) < 0) { //注册JNI方法
        ALOGE("Unable to register all android natives\n");
        return;
    }
        /*
     * 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);
        /* keep going */
    } else {
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main", 
            "([Ljava/lang/String;)V"); //通过JNI启动ZygoteInit.main方法
            ..........省略部分代码

通过上面的代码流程和系统参数的初始化,我们来到了ZygoteInit.java 的main方法

ZygoteInit.java

public static void main(String argv[]) {
    // Start profiling the zygote initialization.
    SamplingProfilerIntegration.start(); //开始解析并初始化zygote
    registerZygoteSocket(socketName); //创建Socket,它将作为服务端用来和作为客户端的ActivityManagerService进行通信 
    preload();//预加载framework和众多App所需要的通用资源,Classes、Resources、OpenGL、SharedLibraries、TextResources等等
            if (startSystemServer) {
                startSystemServer(abiList, socketName); //通过startSystemServer()方法来启动SystemServer 
            }
            Log.i(TAG, "Accepting command socket connections");
            runSelectLoop(abiList);//使刚才创建的Socket进入无限循环,以等待来自ActivityManagerService请求
            ......省略部分代码

    /**
     * Prepare the arguments and fork for the system server process.
     */
private static boolean startSystemServer(String abiList, String socketName)
            throws MethodAndArgsCaller, RuntimeException {
                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); //创建SystemServer,与其相似还有forkAndSpecialize(),用于创建一个普通应用进程
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }
        /* For child process */
        if (pid == 0) {//创建成功返回0
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
            handleSystemServerProcess(parsedArgs);
        }

private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {
        closeServerSocket(); //因为是通过zygote创建的但是SystemServer不需要socket所以将其关闭
        if (systemServerClasspath != null) {
            performSystemServerDexOpt(systemServerClasspath);//执行dex2oat
        }
        RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);//通过这个方法进一步启动SystemServer组件
        ......省略部分代码

RuntimeInit.java

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)throws ZygoteInit.MethodAndArgsCaller {
        commonInit();//为当前进程的VM设置未捕获异常处理器
        nativeZygoteInit();//Binder驱动初始化,该方法完成后,就可以通过该Binder进行进程通信
        applicationInit(targetSdkVersion, argv, classLoader); //主要用调用com.android.server.SystemServer类的main()方法

通过RuntimeInit类的出来我们就来到了SystemServer

SystemServer.java

private void run() {
    if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
        Slog.w(TAG, "System clock is before 1970; setting to 1970.");
        SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);//如果系统时间早于1970则修改为1970
    }
    SystemProperties.set("persist.sys.locale", languageTag);//设置系统默认语言是在AndroidRuntime获取的
    SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());//设置虚拟机
    Looper.prepareMainLooper();//初始化一个当前线程的looper
    System.loadLibrary("android_servers");//初始化native_service
    createSystemContext();//创建system上下文
    mSystemServiceManager = new SystemServiceManager(mSystemContext);创建manager
    startBootstrapServices();//启动引导服务,比如AMS,PMS等
    startCoreServices(); //启动核心服务,比如BatteryService等
    startOtherServices(); //启动其他服务,比如NetworkStatsService等.
    Looper.loop(); //启动消息循环

参考 http://blog.csdn.net/dd864140130/article/details/57624948

猜你喜欢

转载自blog.csdn.net/michael_yt/article/details/78603600