Android 系统启动流程分析(基于9.0.0源码)

1、启动电源:当电源键按下是引导芯片从预定义地方开始执行,加载引导程序BootLoader到RAM中,然后执行;

2、引导程序BootLoader拉起Linux;

3、Linux内核启动完成后会在系统文件中寻找init.rc文件(init.rc文件是一个非常重要的配置文件,它由AIL语言(Android Init Language)编写),并启动init进程

4、init进程的入口函数main所在文件为system/core/init/init.cpp

int main(int argc,char ** argv){
    
    ...
    bool is_first_stage = (getenv("INIT_SECOND_STAGE") == nullptr);
    if(is_first_stage){

         clearenv();
         setenv("PATH", _PATH_DEFPATH, 1);
        //创建和挂在启动所需要的文件目录
        mount("tmpfs","/dev","tmpfs",MS_NOSUID,"mode=0755");
        mkdir("/dev/pts",0755);
        //创建和挂在很多...
        ...
    }
    
    ...
    //对属性服务进行初始化,类似Windows的注册表
    property_init();
    
    ...

    //启动属性服务
    start_property_service();
    
    ...
    
    //加载启动脚本
    LoadBootScripts(am, sm);
    
    ...
}

在LoadBootScripts函数中解析init.rc文件

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");
        if (!parser.ParseConfig("/system/etc/init")) {
            late_import_paths.emplace_back("/system/etc/init");
        }
        if (!parser.ParseConfig("/product/etc/init")) {
            late_import_paths.emplace_back("/product/etc/init");
        }
        if (!parser.ParseConfig("/odm/etc/init")) {
            late_import_paths.emplace_back("/odm/etc/init");
        }
        if (!parser.ParseConfig("/vendor/etc/init")) {
            late_import_paths.emplace_back("/vendor/etc/init");
        }
    } else {
        parser.ParseConfig(bootscript);
    }
}

解析init.rc文件后创建Zygote进程,该进程入口函数在:frameworks/base/cmds/app_process/app_main.cpp

int main(int argc, char* const argv[])
{
    if (!LOG_NDEBUG) {
      String8 argv_String;
      for (int i = 0; i < argc; ++i) {
        argv_String.append("\"");
        argv_String.append(argv[i]);
        argv_String.append("\" ");
      }
      ALOGV("app_process main with argv: %s", argv_String.string());
    }
    
    // 创建一个APPRuntime(继承自AndroidRuntime)
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));

    ...

    // 启动
    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    }
}

AndroidRuntime是Dalvik虚拟机的升级版,5.0之前用的是Dalvik,之后就用AndroidRuntime了,下来我们看下AndroidRuntime的start函数

void AndroidRuntime::start(const char* className,const Vector<String8>& options,bool zygote){
    ...
    
    //startVm函数用于启动Java虚拟机
    if(startVm(&mJavaVM,&env,zygote)!=0){
        return;
    }
    onVmCreated(env);

    //为Java虚拟机注册JNI方法
    if(startReg(env)<0){
        ALOGE("Unable to register all android natives\n");
        return;
    }
    ...
    //从app_main的main方法中得知,className是com.android.internal.os.ZygoteInit
    classNameStr=env->NewStringUTF(className);
    
    ...
    
    //找到ZygoteInit类
    jclass startClass=env->FindClass(slashClassName);
    
    ...
    //找到ZygoteInit的main方法
    jmethodID startMeth=env->GetStaticMethodID(startClass,"main","([Ljava/lang/String;)V");
    
    ...
    //通过JNI调用ZygoteInit的main方法
    env->CallStaticVoidMethod(startClass,startMeth,strArray);
}

调用ZygoteInit类的Main方法 frameworks/base/core/java/com/android/internal/os/ZygoteInit.java:

public static void main(String argv[]){
    ...
    //创建一个Server端的Socket,socketName值为:zygote
    zygoteServer.registerServerSocketFromEnv(socketName);
    
    if(!enableLazyPreload){
        ...
        //预加载类和资源
        preload(bootTimingsTraceLog);
    }else{
        ...
    }
    
    if(startSystemServer){
        Runnable r = forkSystemServer(abiList, socketName, zygoteServer);

        // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
        // child (system_server) process.
        if (r != null) {
            r.run();
            return;
        }
    }
    //等待AMS的请求
    caller = zygoteServer.runSelectLoop(abiList);
    zygoteServer.closeServerSocket();

    if (caller != null) {
        caller.run();
    }
}

private static Runnable forkSystemServer(String abiList, String socketName,
    ZygoteServer zygoteServer) {
    ...
    pid = Zygote.forkSystemServer(
        parsedArgs.uid, parsedArgs.gid,
        parsedArgs.gids,
        parsedArgs.runtimeFlags,
        null,
        parsedArgs.permittedCapabilities,
        parsedArgs.effectiveCapabilities);
    } catch (IllegalArgumentException ex) {
        throw new RuntimeException(ex);
    }

    /* For child process */
    if (pid == 0) {
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }

        zygoteServer.closeServerSocket();
        return handleSystemServerProcess(parsedArgs);
    }

    return null;
}

handleSystemServerProcess 函数实现

private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
    ...
    ClassLoader cl=null;
    if(systemServerClasspath!=null){
        //在这里创建了PathClassLoader
        cl = createPathClassLoader(systemServerClasspath,parsedArgs.targetSdkVersion);
        Thread.currentThread().setContextClassLoader(cl);
    }
    //zygoteInit方法
    /*
      * Pass the remaining arguments to SystemServer.
    */
    return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
zygoteInit 函数
 public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
    RuntimeInit.redirectLogStreams();

    RuntimeInit.commonInit();

    ZygoteInit.nativeZygoteInit();

    return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

nativeZygoteInit方法一看名称,就知道是在Native层的代码。用来启动Binder线程池,这样SystemServer进程就可以使用Binder与其他进程进行通信了。

再讲一下RuntimeInit的applicationInit方法,该方法用于启动SystemServer(以及后来我们的应用程序进程的启动)。

frameworks/base/core/java/com/android/internal/os/RuntimeInit.java:

protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
    nativeSetExitWithoutCleanup(true);
    VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
    VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

    final Arguments args = new Arguments(argv);

    // The end of of the RuntimeInit event (see #zygoteInit).
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

    // Remaining arguments are passed to the start class's static main
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}

这里我们重点看下findStaticMain函数

protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
    Class<?> cl;

    // 找到SystemServer类
    try {
        //className是com.android.server.SystemServer
        cl = Class.forName(className, true, classLoader);
    } catch (ClassNotFoundException ex) {
    throw new RuntimeException(
        "Missing class when invoking static main " + className,ex);
    }


    // 找到Main方法
    Method m;
    try {
        m = cl.getMethod("main", new Class[] { String[].class });
    } catch (NoSuchMethodException ex) {
        throw new RuntimeException(
        "Missing static main on " + className, ex);
    } catch (SecurityException ex) {
        throw new RuntimeException(
        "Problem getting static main on " + className, ex);
    }

    int modifiers = m.getModifiers();
    if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
        throw new RuntimeException(
        "Main method is not public and static on " + className);
    }
    
    // 返回一个Runnable
    return new MethodAndArgsCaller(m, argv);
}


static class MethodAndArgsCaller implements Runnable {
/** method to call */
private final Method mMethod;

/** argument array */
private final String[] mArgs;

public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}

public void run() {
    try {
        mMethod.invoke(null, new Object[] { mArgs });
    } catch (IllegalAccessException ex) {
        throw new RuntimeException(ex);
    } catch (InvocationTargetException ex) {
            Throwable cause = ex.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            } else if (cause instanceof Error) {
                throw (Error) cause;
            }
            throw new RuntimeException(ex);
        }
    }
}

这里我们可以看出,通过反射找到com.android.server.SystemServer类的main方法,然后返回一个Runnable对象,这点和之前的的版本有点不一样,之前的版本这里是抛出一个异常,然后在异常处理中做mMethod.invoke(null, new Object[] { mArgs });,而9.0版本是返回一个Runnable对象,在ZygoteInit类的main函数中直接调用run()来执行

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

public static void main(String[] args) {
    new SystemServer().run();
}

private void run(){
    ...
    //创建消息Looper
    Looper.prepareMainLooper();

    //加载动态库
    System.loadLibrary("android_servers");

    // 创建系统 context.
    createSystemContext();

    //创建SystemServiceManager
    mSystemServiceManager=new SystemServiceManager(mSystemContext);
    
    ...
    //启动引导服务
    startBootstrapServices();
    //启动核心服务
    startCoreServices();
    //启动其他服务
    startOtherServices();
    
    ...
}

所有服务都启动之后,ActivityManagerService则会启动Launcher

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值