Android Boot: After kernel stage

来源:互联网 发布:淘宝美迪惠尔假货 编辑:程序博客网 时间:2024/06/01 09:07
本来一直在分析WIFI service,后来一直往底层追溯,就跟踪到了Android的service manager等“大户”的启动,再往上追就到了init了。先大概记录一下启动的流程,以后有空了再补充某些步骤的细节。由于分析的是Kernel起来之后剩下的启动过程,所以从init进程开始:

一,init
Init是由kernel启动的用户级进程,它始终是第一个存在进程。init起来之后会解析init.rc和init.{hardware}.rc,然后根据其内容启动基本服务和做些其他的东西。init*rc里面可以有(Actions, Commands, Services, Options)四种类型的声明,另外再分析。下面先看看init.rc里面的两行:
service servicemanager /system/bin/servicemanager
    ...
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    ...

二,ServiceMangaer与app_process
其中servicemanager的代码为frameworks/base/cmds/servicemanager/service_manager.c,ServiceManager总管所有service(frameworks层次的service)的注册与查找(详情点击这里),先运行它主要是为后面的app_process启动zygote的过程提供前提条件。

app_prceoss的代码为frameworks/base/cmds/app_process/app_main.cpp,其主函数如下:
int main(int argc, const char* const argv[])
{
         ...
    AppRuntime runtime;
         ...    
    // Next arg is startup classname or "--zygote"
    if (i < argc) {
        arg = argv[i++];
        if (0 == strcmp("--zygote", arg)) {
            bool startSystemServer = (i < argc) ?
                    strcmp(argv[i], "--start-system-server") == 0 : false;
            setArgv0(argv0, "zygote");
            set_process_name("zygote");
            runtime.start("com.android.internal.os.ZygoteInit",
                startSystemServer);

        } else {
         ...
        }
    } else {
         ...
    }

}
其中以"com.android.internal.os.ZygoteInit"为类名调用AppRuntime : public AndroidRuntime的start()函数来启动zygote,其代码在frameworks/base/core/jni/AndroidRuntime.cpp中,start函数如下:
void AndroidRuntime::start(const char* className, const bool startSystemServer)
{
         ...
    if (startVm(&mJavaVM, &env) != 0)
        goto bail;
         ...
    if (startReg(env) < 0) {
        LOGE("Unable to register all android natives\n");
        goto bail;
    }
         ...
    startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        LOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
        startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            LOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
         ...
}
startVm启动dalvik虚拟机,startReg负责把注册一些jni函数,然后就是找到名字为ZygoteInit的类并运行其main()函数。

三,ZygoteInit类
下面看看这个类的main函数,代码在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java,主函数如下:
  public static void main(String argv[]) {
        try {
                  ...
            if (argv[1].equals("true")) {
                startSystemServer();
            } else if (!argv[1].equals("false")) {
                throw new RuntimeException(argv[0] + USAGE_STRING);
            }
                 ...
            if (ZYGOTE_FORK_MODE) {
                runForkMode();
            } else {
                runSelectLoopMode();
            }

            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
            caller.run();
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }
因为在AndroidRuntime::start中,"true"参数由strArray带进来,所以会调用到 startSystemServer()函数:
private static boolean startSystemServer()
            throws MethodAndArgsCaller, RuntimeException {
        /* Hardcoded command line to start the system server */
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003",
            "--capabilities=130104352,130104352",
            "--runtime-init",
            "--nice-name=system_server",
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
                   ...
            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(    // 具体实现查看dalvik/vm/InternalNative.c
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids, debugFlags, null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        if (pid == 0) {
            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }
设置一堆启动参数之后,调用forkSystemServer启动子进程来跑handleSystemServerProcess(),父进程返回继续忙其他的事情(就是runForkMode或者runSelectLoopMode),然后这个函数又绕到了RuntimeInit.zygoteInit(parsedArgs.remainingArgs):
public static final void zygoteInit(String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
            ...
        commonInit();   // 做些初始化的工作
        zygoteInitNative();

            ...
        String startClass = argv[curArg++];
        String[] startArgs = new String[argv.length - curArg];

        System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
        invokeStaticMain(startClass, startArgs);
    }
invokeStaticMain这个函数在根据startArgs找到类名为"com.android.server.SystemServer"的main函数(还检查了public和static属性),然后通过throw new ZygoteInit.MethodAndArgsCaller(m, argv)返回。注意观察中间这些函数都带throws ZygoteInit.MethodAndArgsCaller的,所以这个 ZygoteInit.MethodAndArgsCaller最后会被ZygoteInit的main函数catch到然后通过 caller.run();启动SystemServer的main函数。


四,SystemServer类
类的代码在frameworks/base/services/java/com/android/server/SystemServer.java中,主函数:
public static void main(String[] args) {
              ...
        System.loadLibrary("android_servers");
        init1(args);
    }
先显式加载libandroid_servers,这个库由frameworks/base/services/jni中的代码生成,加载时会把onload.cpp里的JNI_OnLoad()跑一遍把jni函数注册上去:
    register_android_server_PowerManagerService(env);
    register_android_server_InputManager(env);
    register_android_server_LightsService(env);
    register_android_server_AlarmManagerService(env);
    register_android_server_BatteryService(env);
    register_android_server_UsbService(env);
    register_android_server_VibratorService(env);
    register_android_server_SystemServer(env);
    register_android_server_location_GpsLocationProvider(env);
库加载完后,SystemServer的main函数再调用init1(args)进行下一步的工作,这个函数在SystemServer.java中是这样定义的native public static void init1(String[] args);所以是通过jni的方式进行调用,init1的实现在libandroid_servers库的代码中:
static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
{
    system_init();
}
system_init()的实现在frameworks/base/cmds/system_server/library/system_init.cpp中(生成的是libsystem_server):
extern "C" status_t system_init()
{
        ... // 先启动SurfaceFinger和SensorService等关键服务
    property_get("system_init.startsurfaceflinger", propBuf, "1");
    if (strcmp(propBuf, "1") == 0) {
        // Start the SurfaceFlinger
        SurfaceFlinger::instantiate();
    }

    // Start the sensor service
    SensorService::instantiate();

    // 如果是emulator的话直接在这里把下面的service也拉起来
    if (!proc->supportsProcesses()) {

        // Start the AudioFlinger
        AudioFlinger::instantiate();

        // Start the media playback service
        MediaPlayerService::instantiate();

        // Start the camera service
        CameraService::instantiate();

        // Start the audio policy service
        AudioPolicyService::instantiate();
    }
        ...
    LOGI("System server: starting Android services.\n");
    runtime->callStatic("com/android/server/SystemServer", "init2");
        ...
    return NO_ERROR;
}
通过callStatic调用,又绕回了java层去,SystemServer.java中得init2如下:
public static final void init2() {
        Slog.i(TAG, "Entered the Android system server!");
        Thread thr = new ServerThread();
        thr.setName("android.server.ServerThread");
        thr.start();
}
ServerThread的start()调用run()来启动所有的JAVA Service:

    @Override
    public void run() {
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,
            SystemClock.uptimeMillis());

        Looper.prepare();

        android.os.Process.setThreadPriority(
                android.os.Process.THREAD_PRIORITY_FOREGROUND);

        BinderInternal.disableBackgroundScheduling(true);
        android.os.Process.setCanSelfBackground(false);

        // Check whether we failed to shut down last time we tried.
        {
            final String shutdownAction = SystemProperties.get(
                    ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
            if (shutdownAction != null && shutdownAction.length() > 0) {
                boolean reboot = (shutdownAction.charAt(0) == '1');

                final String reason;
                if (shutdownAction.length() > 1) {
                    reason = shutdownAction.substring(1, shutdownAction.length());
                } else {
                    reason = null;
                }

                ShutdownThread.rebootOrShutdown(reboot, reason);
            }
        }

        String factoryTestStr = SystemProperties.get("ro.factorytest");
        int factoryTest = "".equals(factoryTestStr) ? SystemServer.FACTORY_TEST_OFF
                : Integer.parseInt(factoryTestStr);

        LightsService lights = null;
        PowerManagerService power = null;
        BatteryService battery = null;
        ConnectivityService connectivity = null;
        IPackageManager pm = null;
        Context context = null;
        WindowManagerService wm = null;
        BluetoothService bluetooth = null;
        BluetoothA2dpService bluetoothA2dp = null;
        HeadsetObserver headset = null;
        DockObserver dock = null;
        UsbService usb = null;
        UiModeManagerService uiMode = null;
        RecognitionManagerService recognition = null;
        ThrottleService throttle = null;

        // Critical services...
        try {
                     ...
            // 类似下面这段代码,先创建JAVA Service类(new或者getInstance)
            // 再调用ServiceManager的addService API将系统的各种JAVA Service加进来
            try {
                Slog.i(TAG, "Connectivity Service");
                connectivity = ConnectivityService.getInstance(context);
                ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);   
               // WIFI相关的service由connectivity service管理
               // getInstance()会调用ConnectivityService()构造函数,其中会通过
               // WifiStateTracker wst = new WifiStateTracker(context, mHandler);
               // WifiService wifiService = new WifiService(context, wst);
               // ServiceManager.addService(Context.WIFI_SERVICE, wifiService);
               // wifiService.startWifi(); 来启动wifi service
               // wifi相关的另文分析
            } catch (Throwable e) {
                Slog.e(TAG, "Failure starting Connectivity Service", e);
            }
                    ...

        // It is now time to start up the app processes...
        // Service加完后,可以通过systemReady()回调来通知各个Service现在可以开始自己的服务了
        if (devicePolicy != null) {
            devicePolicy.systemReady();
        }

        if (notification != null) {
            notification.systemReady();
        }

        if (statusBar != null) {
            statusBar.systemReady();
        }
        wm.systemReady();
        power.systemReady();
        try {
            pm.systemReady();
        } catch (RemoteException e) {
        }

        // These are needed to propagate to the runnable below.
        final StatusBarManagerService statusBarF = statusBar;
        final BatteryService batteryF = battery;
        final ConnectivityService connectivityF = connectivity;
        final DockObserver dockF = dock;
        final UsbService usbF = usb;
        final ThrottleService throttleF = throttle;
        final UiModeManagerService uiModeF = uiMode;
        final AppWidgetService appWidgetF = appWidget;
        final WallpaperManagerService wallpaperF = wallpaper;
        final InputMethodManagerService immF = imm;
        final RecognitionManagerService recognitionF = recognition;
        final LocationManagerService locationF = location;

        // We now tell the activity manager it is okay to run third party
        // code.  It will call back into us once it has gotten to the state
        // where third party code can really run (but before it has actually
        // started launching the initial applications), for us to complete our
        // initialization.
        ((ActivityManagerService)ActivityManagerNative.getDefault())
                .systemReady(new Runnable() {  // 这个回调将会通过发送intent.CATEGORY_HOME启动第一个activity,具体代码待分析
            public void run() {
                Slog.i(TAG, "Making services ready");

                if (statusBarF != null) statusBarF.systemReady2();
                if (batteryF != null) batteryF.systemReady();
                if (connectivityF != null) connectivityF.systemReady();
                if (dockF != null) dockF.systemReady();
                if (usbF != null) usbF.systemReady();
                if (uiModeF != null) uiModeF.systemReady();
                if (recognitionF != null) recognitionF.systemReady();
                Watchdog.getInstance().start();

                // It is now okay to let the various system services start their
                // third party code...

                if (appWidgetF != null) appWidgetF.systemReady(safeMode);
                if (wallpaperF != null) wallpaperF.systemReady();
                if (immF != null) immF.systemReady();
                if (locationF != null) locationF.systemReady();
                if (throttleF != null) throttleF.systemReady();
            }
        });

        // For debug builds, log event loop stalls to dropbox for analysis.
        if (StrictMode.conditionallyEnableDebugLogging()) {
            Slog.i(TAG, "Enabled StrictMode for system server main thread.");
        }

        Looper.loop();
        Slog.d(TAG, "System ServerThread is exiting!");
        }
    }

五,后续
至此,提供给app运行的环境已经搭建起来,但是某些步骤还是不太完善需要以后补充。其中关system_init()这个函数也可以通过/system/bin/system_server来显式调用。找到一段说明如下:
There is another way to start system server, which is through a program named system_server whose source is frameworks/base/cmds/system_server/system_main.cpp. It also calls system_init to start system services. So there is a question: why does Android have two methods to start system services? My guess is that directly start system_server may have synchronous problem with zygote because system_server will call JNI to start SystemServer::init2, while at that time zygote may not start JAVA VM yet. So Android uses another method. After zynote is initialized, fork a new process to start system services.

大致意思是,可以通过system_server这个命令调用system_init来启动system services,但是为什么Android要使用上述的方式来启动呢。据猜测是如果直接用命令来启动的话会跟zygote有同步的问题存在,因为system_init会通过JNI来调用SystemServer::init2,如果这时候zygote尚未启动JAVA VM就会出问题了。