Android系统启动过程详解

来源:互联网 发布:geo数据库使用方法 编辑:程序博客网 时间:2024/04/30 15:15

前言

一直想研究Android完整的启动过程,网上看了不少资料,也看了书上的一些说明,对这些观点有些怀疑,于是自己分析了系统启动的完整过程。从内核启动第一个用户程序init开始说起,直到Home应用的启动,每一步都有源代码展示。希望能解除读者对Android系统启动过程中的困惑,若有什么疑问,欢迎留言交流。本研究基于CM10.1源码,读者若能对照源代码查看效果会更好。

1) init启动servicemanager和 zygote两个service

Android底层是Linux内核,和linux类似,内核初始化后启动的第一个用户进程是init,它会解析init.rc脚本,启动init.rc里声明的service,并执行一些action。在init.rc里有启动Andriod空间的一些关键服务,代码如下:

123456789101112131415161718
#…service servicemanager /system/bin/servicemanager    class core    user system    group system    critical    onrestart restart zygote    onrestart restart media    onrestart restart surfaceflinger    onrestart restart drmservice 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#…

servicemanager负责管理所有的binder service, 这些binder service有native的,也有java的。native的binder service有surfaceflinger,drm,media等,java的binder service就有我们平常熟悉的很多管理服务了,ActivityManagerService,WindowManagerService,BatteryService,PowerManagerService,InputManagerService等等。service manager并不负责这些binder service的创建,native的binder service大多由init启动init.rc里的service时创建并启动,java层的binder service大多由zygote创建并启动的,接下来会详细这些service是如何被启动的。

2) zygote service启动java层的ZygoteInit

zygote服务是java层所有程序进程的父进程,它是Android空间程序的孵化器,Android空间所有程序都是由zygote进程启动的。zygote service对应/system/bin/app_process程序,源代码位于frameworks/base/cmds/app_process/app_main.cpp,启动时的main函数代码如下:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
int main(int argc, const char* const argv[]){//.../*runtime就是dalvik虚拟机实例,启动Java层应用时, *会fork 一个子进程,复制虚拟机,许多书上将runtime看作一个进程, *然后再启动zygote进程,个人觉得这是错误的  */ AppRuntime runtime;//... while (i < argc) {    const char* arg = argv[i++];    if (!parentDir) {        parentDir = arg;  /*init.rc启动app_main会设置参数--zygote*/     } else if (strcmp(arg, "--zygote") == 0) {        zygote = true;        niceName = "zygote"; //进程的名字  /*init.rc启动app_main会设置参数--start-system-server,   *表示需启动systemserver   */    } else if (strcmp(arg, "--start-system-server") == 0) {        startSystemServer = true; /*启动应用时会使用--application参数*/                 } else if (strcmp(arg, "--application") == 0) {        application = true;/*--nice-name=参数表示要设置的进程名字*/                } 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) {/*虚拟机里启动com.android.internal.os.ZygoteInit, *并传递参数start-system-server */    runtime.start("com.android.internal.os.ZygoteInit",            startSystemServer ? "start-system-server" : "");} else if (className) {            /*若不是zygote,则启动的第一个类是com.android.internal.os.RuntimeInit,     *RumtimeInit初始化后会启动mClassName     */    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 service将运行dalvik虚拟机,并在虚拟机里执行com.android.internal.os.ZygoteInit,还给它传递了参数start-system-server

3) ZygoteInit启动SystemServer

ZygoteInit启动时的相关源代码:

12345678910111213141516171819202122232425262728293031323334
public static void main(String argv[]) {{try {      //...   //在某个描述符上监听连接请求,   //其它Android空间的程序的启动都是通过连接zygote才孵化出来的   registerZygoteSocket();   //...    if (argv[1].equals("start-system-server")) {        //启动SystemServer        startSystemServer();    } else if (!argv[1].equals("")) {        throw new RuntimeException(argv[0] + USAGE_STRING);    }   //...   /*ZYGOTE_FORK_MODE默认为false,如果为true的话,每收到一个连接请求,    *就会建立一个新进程,然后再运行连接请求所要求执行的命令,此时会建立另一个新进程    */    if (ZYGOTE_FORK_MODE) {        runForkMode();    } else {       //使用Select poll的方式来建立新进程,收到连接请求后,也会建立进程启动某个程序        runSelectLoopMode();    }     closeServerSocket();} catch (MethodAndArgsCaller caller) {    caller.run();} catch (RuntimeException ex) {    Log.e(TAG, "Zygote died with exception", ex);    closeServerSocket();    throw ex;}}

从上述代码可知道会调用startSystemServer以启动SystemServer,相关源代码如下:

1234567891011121314151617181920212223242526272829303132333435363738394041424344
private static boolean startSystemServer(){/* Hardcoded command line to start the system server *///启动SystemServer使用的参数String args[] = {    "--setuid=1000",    "--setgid=1000",    "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,3001,3002,3003,3004,3006,3007,3009",    "--capabilities=130104352,130104352",    "--runtime-init",    "--nice-name=system_server",    //注意:就是在这里设置要启动的SystemServer包名及类名,故此后续才能启动SystemServer    "com.android.server.SystemServer",};ZygoteConnection.Arguments parsedArgs = null;int pid;try {    /*将args参数传给ZygoteConnection进行转化,--形式的参数将全部被接收     * 但是要启动的类的类名com.android.server.SystemServer会放在     *ZygoteConnection.Arguments的remainingArgs里,后来调用handleSystemServerProcess时会用到     */    parsedArgs = new ZygoteConnection.Arguments(args);     /*添加额外运行参数*/    ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);    ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);     /*开启新进程*/    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会执行ZygoteConnection.Arguments的remainingArgs参数   *所指定的类,即com.android.server.SystemServer      */    handleSystemServerProcess(parsedArgs);}}

ZygoteInit的startSystemServer会调用forkSystemServer,然后:

ZygoteInit.forkSystemServer -> Zygote.nativeForkSystemServer-> dalvik_system_Zygote.cpp 里的Dalvik_dalvik_system_Zygote_forkSystemServer-> forkAndSpecializeCommon->fork建立新进程

ZygoteInit的startSystemServer会调用handleSystemServerProcess来真正启动systemserver,相关源代码如下:

12345678910111213141516171819
private static void handleSystemServerProcess(            ZygoteConnection.Arguments parsedArgs)            throws ZygoteInit.MethodAndArgsCaller {//... if (parsedArgs.niceName != null) {    Process.setArgV0(parsedArgs.niceName);}//启动systemserver时invokeWith为nullif (parsedArgs.invokeWith != null) {    WrapperInit.execApplication(parsedArgs.invokeWith,            parsedArgs.niceName, parsedArgs.targetSdkVersion,            null, parsedArgs.remainingArgs);} else {    /*     * 启动systemserver时,parsedArgs.remainingArgs为com.android.server.SystemServer.     */    RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);}}

然后的流程是

RuntimeInit.zygoteInit-> applicationInit,applicationInit的代码如下所示:

12345678910111213141516
private static void applicationInit(int targetSdkVersion, String[] argv){//...final Arguments args;try {    //参数转换,系统启动时,argv里有一个参数是com.android.server.SystemServer    args = new Arguments(argv);} catch (IllegalArgumentException ex) {    Slog.e(TAG, ex.getMessage());    // let the process exit    return;}//...//终于在此启动了SystemServerinvokeStaticMain(args.startClass, args.startArgs)}

4) SystemServer 启动过程

执行com.android.server.SystemServer时,main函数里会调用init1函数,init1函数是一个本地函数,init1的实现放在frameworks/base/services/jni/com_android_server_SystemServer.cpp里,对应的jni函数是android_server_SystemServer_init1,在该函数里会调用system_init,而system_init的实现是在frameworks/base/cmds/system_server/library/system_init.cpp,该函数的实现代码如下所示:

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
extern "C" status_t 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;}//反过来调用Java里SystemServer的init2函数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");}

5) 启动Java层的各种binder service

调用SystemServer的init2函数后,会开启新线程android.server.ServerThread,在新线程里会启动各种Java层的binder service,并在service manager里注册,这些Service大多开启了新线程运行,故此都是systemserver的子线程,添加的Service列表如下所示:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
ServiceManager.addService("entropy", new EntropyMixer());ServiceManager.addService(Context.POWER_SERVICE, power);ServiceManager.addService(Context.DISPLAY_SERVICE, display, true);ServiceManager.addService("telephony.registry", telephonyRegistry);ServiceManager.addService(Context.SCHEDUL
0 0
原创粉丝点击