zoukankan      html  css  js  c++  java
  • Android系统启动过程详解【转】

    前言

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

    1) init启动servicemanager和 zygote两个service

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

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

    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函数代码如下:

    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.
    ");
        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启动时的相关源代码:

    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,相关源代码如下:

    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,相关源代码如下:

    private static void handleSystemServerProcess(
                ZygoteConnection.Arguments parsedArgs)
                throws ZygoteInit.MethodAndArgsCaller {
    //... 
    if (parsedArgs.niceName != null) {
        Process.setArgV0(parsedArgs.niceName);
    }
    //启动systemserver时invokeWith为null
    if (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的代码如下所示:

    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;
    }
    //...
    //终于在此启动了SystemServer
    invokeStaticMain(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,该函数的实现代码如下所示:

    extern "C" status_t system_init()
    {
    //... 
    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();
    ALOGI("ServiceManager: %p
    ", 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.
    ");
    AndroidRuntime* runtime = AndroidRuntime::getRuntime();
    ALOGI("System server: starting Android services.
    ");
    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.
    ");
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
    ALOGI("System server: exiting thread pool.
    ");
    }

    5) 启动Java层的各种binder service

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

    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.SCHEDULING_POLICY_SERVICE,
    ServiceManager.addService(Context.USER_SERVICE,UserManagerService.getInstance());
    ServiceManager.addService(Context.ACCOUNT_SERVICE, accountManager);
    ServiceManager.addService("battery", battery);
    ServiceManager.addService("vibrator", vibrator);
    ServiceManager.addService(Context.ALARM_SERVICE, alarm);
    ServiceManager.addService(Context.WINDOW_SERVICE, wm);
    ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
    ServiceManager.addService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, bluetooth);
    ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
    ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,new AccessibilityManagerService(context));
    ServiceManager.addService("mount", mountService);
    ServiceManager.addService("lock_settings", lockSettings);
    ServiceManager.addService(Context.DEVICE_POLICY_SERVICE, devicePolicy);
    ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
    ServiceManager.addService(Context.CLIPBOARD_SERVICE,new ClipboardService(context));
    ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement);
    ServiceManager.addService(Context.TEXT_SERVICES_MANAGER_SERVICE, tsms);
    ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats);
    ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);
    ServiceManager.addService(Context.WIFI_P2P_SERVICE, wifiP2p);
    ServiceManager.addService(Context.WIFI_SERVICE, wifi);
    ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
    ServiceManager.addService(Context.NSD_SERVICE, serviceDiscovery);
    ServiceManager.addService(Context.THROTTLE_SERVICE, throttle);
    ServiceManager.addService("fm_receiver",new FmReceiverService(context));
    ServiceManager.addService("fm_transmitter",new FmTransmitterService(context));
    ServiceManager.addService(Context.UPDATE_LOCK_SERVICE,new UpdateLockService(context));
    ServiceManager.addService(Context.PROFILE_SERVICE, profile);
    ServiceManager.addService(Context.NOTIFICATION_SERVICE, notification);
    ServiceManager.addService(DeviceStorageMonitorService.SERVICE,
    ServiceManager.addService(Context.LOCATION_SERVICE, location);
    ServiceManager.addService(Context.COUNTRY_DETECTOR, countryDetector);
    ServiceManager.addService(Context.SEARCH_SERVICE,new SearchManagerService(context));
    ServiceManager.addService(Context.DROPBOX_SERVICE,new DropBoxManagerService(context, new File("/data/system/dropbox")));
    ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);
    ServiceManager.addService(Context.AUDIO_SERVICE, new AudioService(context));
    ServiceManager.addService(Context.USB_SERVICE, usb);
    ServiceManager.addService(Context.SERIAL_SERVICE, serial);
    ServiceManager.addService(Context.BACKUP_SERVICE,new BackupManagerService(context));
    ServiceManager.addService(Context.APPWIDGET_SERVICE, appWidget);
    ServiceManager.addService("diskstats", new DiskStatsService(context));
    ServiceManager.addService("samplingprofiler", new SamplingProfilerService(context));
    ServiceManager.addService("commontime_management", commonTimeMgmtService);
    ServiceManager.addService(DreamService.DREAM_SERVICE, dreamy);
    ServiceManager.addService("assetredirection", new AssetRedirectionManagerService(context));
    ServiceManager.addService("pieservice", pieService);

    上述并没有看到将ActivityManagerService添加到servicemanager管理,它的添加过程比较特别。在线程android.server.ServerThread里会调用ActivityManagerService.setSystemProcess();setSystemProcess函数的代码如下所示:

    public static void setSystemProcess() {
    //
    ActivityManagerService m = mSelf;            
    ServiceManager.addService("activity", m, true);
    ServiceManager.addService("meminfo", new MemBinder(m));
    ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
    ServiceManager.addService("dbinfo", new DbBinder(m));
    if (MONITOR_CPU_USAGE) {
        ServiceManager.addService("cpuinfo", new CpuBinder(m));
    }
    ServiceManager.addService("permission", new PermissionController(m));
    ApplicationInfo info =
        mSelf.mContext.getPackageManager().getApplicationInfo(
                    "android", STOCK_PM_FLAGS);
    mSystemThread.installSystemApplicationInfo(info);
    //
    }

    可以看到ActivityManagerService采用了单例模式,并调用ServiceManager.addService(“activity”, m, true);将ActivityManagerService交给servicemanager管理,在ActivityManagerService里还添加了别的binder service,像MemBinder,GraphicsBinder,DbBinder。

    最后会调用Looper.loop();进入loop循环,等待和别的程序通信。

    6) 启动系统界面

    线程android.server.ServerThread里有如下代码:

    ActivityManagerService.self().systemReady(new Runnable() {
        public void run() {
            Slog.i(TAG, "Making services ready");
     
            if (!headless) startSystemUi(contextF);
            //...
         }
    }

    startSystemUi就是用于启动系统界面的,代码如下:

    static final void startSystemUi(Context context) {
            Intent intent = new Intent();
            intent.setComponent(new ComponentName("com.android.systemui",
                        "com.android.systemui.SystemUIService"));
            //Slog.d(TAG, "Starting service: " + intent);
            context.startServiceAsUser(intent, UserHandle.OWNER);
    }

    这样便启动了com.android.systemui应用,该应用将启动PowerUI和RingtonePlayer两个线程。

    7) 启动Home 程序

    线程android.server.ServerThread里有如下代码:

    //
    ActivityManagerService.self().systemReady(new Runnable() {
                public void run() {
                      //
                    }
        });
    //

    ActivityManagerService.self().systemReady有如下代码:

    //
    mMainStack.resumeTopActivityLocked(null);
    //

    ActivityStack. resumeTopActivityLocked()有如下代码:

    resumeTopActivityLocked(prev, null);

    resumeTopActivityLocked的实现有如下代码:

    //
    if (next == null) {
        // There are no more activities!  Let's just start up the
        // Launcher...
        if (mMainStack) {
            ActivityOptions.abort(options); 
            return mService.startHomeActivityLocked(mCurrentUser);
        }
    }
    //

    mService类型是ActivityManagerService,ActivityManagerService. startHomeActivityLocked的实现有如下代码:

    boolean startHomeActivityLocked(int userId) {
    //
    Intent intent = new Intent(
        mTopAction,
        mTopData != null ? Uri.parse(mTopData) : null);
    intent.setComponent(mTopComponent);
    //这里便添加了Intent.CATEGORY_HOME,
    //所有的Home应用都会都带有该类型的Activity,只有这样才会被认为是Home应用
    if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
        intent.addCategory(Intent.CATEGORY_HOME);
    }
    ActivityInfo aInfo =
        resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
    if (aInfo != null) {
        intent.setComponent(new ComponentName(
                aInfo.applicationInfo.packageName, aInfo.name));
        // Don't do this if the home app is currently being
        // instrumented.
        aInfo = new ActivityInfo(aInfo);
        aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
        ProcessRecord app = getProcessRecordLocked(aInfo.processName,
                aInfo.applicationInfo.uid);
        if (app == null || app.instrumentationClass == null) {
            intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
            mMainStack.startActivityLocked(null, intent, null, aInfo,
                    null, null, 0, 0, 0, 0, null, false, null);
        }
    }
    }

    这样先找到使用Intent.CATEGORY_HOME声明的Activity组件,然后再调用mMainStack.startActivityLocked启动该Activity。

    system server启动Home程序总结:

    android.server.ServerThread->ActivityManagerService.self().systemReady->mMainStack.resumeTopActivityLocked->resumeTopActivityLocked-> mService.startHomeActivityLocked-> intent.addCategory(Intent.CATEGORY_HOME);mMainStack.startActivityLocked

    总结

    内核初始化好后,运行的第一个用户程序是init,init将启动init.rc里声明的多个service,跟Android空间相关的有servicemanager和zygote,servicemanager负责管理所有的binder service,zygote负责孵化所有Android空间的程序。zygote service对应的程序是app_process,不过加了一些启动参数,所以它会启动Java层的ZygoteInit,在ZygoteInit里会启动SystemServer,SystemServer分为两个阶段:本地的init1和Java层的init2,init2里会启动线程android.server.ServerThread。在android.server.ServerThread线程里会启动Java层的各种binder service,比如ActivityManagerService,PackageManagerService,WindowManagerService。然后调用ActivityManagerService的systemReady方法,在该方法里会启动系统界面以及Home程序。

    原文:http://www.cloudchou.com/android/post-361.html

  • 相关阅读:
    java——testNG——工作复习——xml详解
    转义符,re模块,rangdom随机数模块,
    nyoj 814又见拦截导弹
    Soj题目分类
    Xcode 性能优化
    python使用pip安装模块出现ReadTimeoutError: HTTPSConnectionPool的解决方法(pip使用豆瓣源)
    浅谈模拟退火
    43-正则表达式(1)
    命令行上的narrowing(随着输入逐步减少备选项)工具
    有效决策,这么做就对了!
  • 原文地址:https://www.cnblogs.com/chenlong-50954265/p/5729767.html
Copyright © 2011-2022 走看看