Android系统揭秘(三)-Android系统启动概述

1,226 阅读5分钟

前言

本来写了Activity和Service,应该继续写另外两个组件的,但是这里面会有很多重复内容,而且基本是触类旁通的,再照之前的方式写下去就未免有水文的嫌疑了。

后面有时间的话我再对其进行完整的梳理,那时候或许还有一读的价值。

本文要讲的系统的启动

init 进程 -- 一切的开始

正如我们的程序会先走init方法一样,Android系统第一个进程是init,进程号为1, 它会进行Zygote,属性服务等的创建

系统的启动

img
安卓手机启动方式有BootLoader,Recovery等模式,默认按下电源键启动的是BootLoader,会执行系统的启动

Android系统的启动,也是linux系统的启动。

启动内核时,会执行设置缓存,加载驱动等步骤,然后查找init.rc文件(配置文件),并启动init进程

启动init进程

img init的入口函数是main(),我们看下它的源码实现

system/core/init/init.cpp(安卓8,9)

int main(int argc , char** argv) {
    ....
    bool is_first_stage = (getenv ("INIT_SECOND_STAGE") == nullptr); 
    if (is_first_stage) { 
        // 创建和挂载启动所需的文件目录
        mount ("tmpfs","/dev","tmpfs" , MS NOSUID,"mode=0755") ;
        ...
    }
    ....
    //对属性服务进行初始化
    property_init ();
    ...
    // 启动属性服务
    start_property_service();
    ...
    if (bootscript.empty()) { 
    // 解析init.rc 配置文件
    parser.ParseConfig ("/init.rc") ;
    ...
}

安卓10开始这块代码有些不同,但大体流程是一样的,安卓11没有大变动

img

system/core/init/main.cpp(安卓10,11)

int main(int argc, char** argv) {
    ...

    if (argc > 1) {
        if (!strcmp(argv[1], "subcontext")) {
            android::base::InitLogging(argv, &android::base::KernelLogger);
            const BuiltinFunctionMap function_map;
            return SubcontextMain(argc, argv, &function_map);
        }

        if (!strcmp(argv[1], "selinux_setup")) {
            return SetupSelinux(argv);
        }
        // argc > 1 时启动第二阶段函数
        if (!strcmp(argv[1], "second_stage")) {
            return SecondStageMain(argc, argv);
        }
    }
    // 启动第一阶段函数
    return FirstStageMain(argc, argv);
}

system/core/init/first_stage_init.cpp(安卓10,11)

int FirstStageMain(int argc, char** argv) {
    
    ...
    // 创建和挂载启动所需的文件目录
    CHECKCALL(mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"));
    ....

    return 1;
}

system/core/init/init.cpp(安卓10,11)

int SecondStageMain(int argc, char** argv) {
  
    ...
    // 对属性服务进行初始化
    property_init();
    ...
    // 启动属性服务
    StartPropertyService(&epoll);
    ...
    // 解析init.rc 配置文件
    LoadBootScripts(am, sm);
    ...
    return 0;
}


static void LoadBootScripts(ActionManager& action_manager, ServiceList& service_list) {
    Parser parser = CreateParser(action_manager, service_list);

    std::string bootscript = GetProperty("ro.boot.init_rc", "");
    if (bootscript.empty()) {
        parser.ParseConfig("/init.rc");
        ...
    }
    ...
}

可以知道init进程主要做了以下几件事情:

  • 创建和挂载启动所需的文件目录
  • 对属性服务进行初始化
  • 启动属性服务
  • 解析init.rc 配置文件, 启动Zygote进程

属性服务

属性服务用于记录用户、软件的一些使用信息,比如系统设置,以键值对存在,分为普通属性和控制属性

  • 普通属性:如语言信息,wifi信息
  • 控制属性:用来执行一些命令,比如开机动画

Zygote

Zygote又称孵化器,用于创建DVM(Dalvik虚拟机)和ART、应用程序进程以及运行系统的关键服务的SystemServer进程

工作原理

通过fock(复制进程)的形式来创建应用程序进程和SystemServer进程。
Zygote的Java框架层中会创建一个Server端的Socket,这个Socket用来等待AMS请求Zygote来创建新的应用程序进程。

启动

Zygote的启动是在init.rc配置文件里面调用的,通过ro.zygote的属性选择引入脚本。主方法为main() 方法

system/core/rootdir/init.rc

import /init.${ro.zygote}.rc
on nonencrypted
    class_start main
    class_start late_start

ro.zygote属性的取值有以下4种:

属性说明
init.zygote32.rc支持纯32位程序,
init.zygote32_64.rc既支持32位程序也支持64位程序
init.zygote64.rc支持纯64位程序,
init.zygote64_32.rc既支持32位程序也支持64位程序

init启动Zygote流程(过程有所简化)

img

Zygote进程启动

Zygote进程启动共做了如下几件事:

  • 创建AppRuntime并调用其start方挂,启动Zygote进程。
  • 创建Java虚拟机并为Java虚拟机注册JNI方法。
  • 通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层。
  • 通过registerZygoteSocket方法创建服务器端Socket,并通过runSelectLoop方法等待AMS的请求来创建新的应用程序进程。
  • 启动SystemServer进程。

Zygote进程启动流程分析

Zygote的启动比较重要,这里啰嗦下,从源码角度分析下

AndroidRuntime启动Zygote

img

frameworks/base/core/jni/AndroidRuntime.cpp

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
    ...
    /* start the virtual machine */
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;

    // 创建JVM虚拟机
    if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
        return;
    }
    onVmCreated(env);

    /*
     * Register android functions.
     */
    // 为JVM虚拟机注册JNI方法
    if (startReg(env) < 0) {
        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.
     * className:com.android.internal.os.ZygoteInit
     */
    char* slashClassName = toSlashClassName(className != NULL ? 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");
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
            // 通过JNI调用ZygoteInit的main方法
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
    ...
}

调用CallStaticVoidMethod方法之后进入了ZygoteInit的主方法,这一步开始进入Java框架层,后面的代码安卓10之后有所不同

ZygoteInit 初始化

img

这一步安卓10开始有所不同,安卓10之前通过registerServerSocket创建Socket, 安卓10开始则在ZygoteServer构造时创建Socket,但大体流程不变

安卓8,9源码

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

public static void main(String argv[]) {
      ...
        // 创建Server 端Socket ,socketName:"zygote"
        zygoteServer.registerServerSocket(socketName);
        if (!enableLazyPreload) {
            ...
            // 预加载类和资源
            preload(bootTimingsTraceLog);
            ...
        } else {
            Zygote.resetNicePriority();
        }

        ...
        if (startSystemServer) {
            // 启动SystemServer进程(8.0为startSystemServer)
            Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
            if (r != null) {
                r.run();
                return;
            }
        }

        Log.i(TAG, "Accepting command socket connections");

        // 等待AMS请求
        caller = zygoteServer.runSelectLoop(abiList);
    } catch (Throwable ex) {
        Log.e(TAG, "System zygote died with exception", ex);
        throw ex;
    } finally {
        zygoteServer.closeServerSocket();
    }
    
    if (caller != null) {
        caller.run();
    }
}

安卓10,11源码

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

public static void main(String argv[]) {
      ...
        if (!enableLazyPreload) {
            ...
            // 预加载类和资源
            preload(bootTimingsTraceLog);
            ...
        } else {
            Zygote.resetNicePriority();
        }

        // 创建Server端Socket
        zygoteServer = new ZygoteServer(isPrimaryZygote);
        ...
        if (startSystemServer) {
            // 启动SystemServer进程(8.0为startSystemServer)
            Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
            if (r != null) {
                r.run();
                return;
            }
        }

        Log.i(TAG, "Accepting command socket connections");

        // 等待AMS请求
        caller = zygoteServer.runSelectLoop(abiList);
    } catch (Throwable ex) {
        Log.e(TAG, "System zygote died with exception", ex);
        throw ex;
    } finally {
        zygoteServer.closeServerSocket();
    }
    
    if (caller != null) {
        caller.run();
    }
}

frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

ZygoteServer(boolean isPrimaryZygote) {
    mUsapPoolEventFD = Zygote.getUsapPoolEventFD();

    if (isPrimaryZygote) {
        mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);
        mUsapPoolSocket =
                Zygote.createManagedSocketFromInitSocket(
                        Zygote.USAP_POOL_PRIMARY_SOCKET_NAME);
    } else {
        mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.SECONDARY_SOCKET_NAME);
        mUsapPoolSocket =
                Zygote.createManagedSocketFromInitSocket(
                        Zygote.USAP_POOL_SECONDARY_SOCKET_NAME);
    }

    mUsapPoolSupported = true;
    fetchUsapPoolPolicyProps();
}

SystemServer

SystemServer是由Zygote启动的进程,用于创建系统服务,如AMS,WMS,PMS等

SystemServer进程被创建后,主要做了如下工作:

  • 启动Binder线程池,这样就可以与其他进程进行通信。
  • 创建SystemServiceManager,其用于对系统的服务进行创建、启动和生命周期管理。
  • 启动各种系统服务。

Launcher

Launcher就是我们平时看到的桌面,由AMS启动,下篇文章会介绍下Launcher的启动流程

参考文献

[1]刘望舒.Android进阶解密[M]:电子工业出版社,2018-10