Android系統啓動研究1

Android系統較爲龐大,要搞清楚系統運行原理需要長期努力。系統啓動部分看了幾遍但沒有總結,今天簡單總結一下。

Android首先重點是啓動zygote進程,這個進程來源於init.rc的讀取,zygote進程主要用於孵化新的app程序,還包括啓動android大量的服務SystemService

本人研究的源碼是4.1的,其它版本的可能略有差異。


init.rc 文件作爲啓動配置重要的入口出,init.c將會讀取這個文件,核心的相關進程也將開啓。

/Android41/system/core/init/init.c

重點是解析了init.rc文件,並且開始處理相關指令。找到main入口,貼出部分代碼

    mkdir("/dev", 0755);
    mkdir("/proc", 0755);
    mkdir("/sys", 0755);

    mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
    mkdir("/dev/pts", 0755);
    mkdir("/dev/socket", 0755);
    mount("devpts", "/dev/pts", "devpts", 0, NULL);
    mount("proc", "/proc", "proc", 0, NULL);
    mount("sysfs", "/sys", "sysfs", 0, NULL);

        /* indicate that booting is in progress to background fw loaders, etc */
    close(open("/dev/.booting", O_WRONLY | O_CREAT, 0000));

        /* We must have some place other than / to create the
         * device nodes for kmsg and null, otherwise we won't
         * be able to remount / read-only later on.
         * Now that tmpfs is mounted on /dev, we can actually
         * talk to the outside world.
         */
    open_devnull_stdio();
    klog_init();
    property_init();

    get_hardware_name(hardware, &revision);

    process_kernel_cmdline();

#ifdef HAVE_SELINUX
    INFO("loading selinux policy\n");
    selinux_load_policy();
#endif

    is_charger = !strcmp(bootmode, "charger");

    INFO("property init\n");
    if (!is_charger)
        property_load_boot_defaults();

    INFO("reading config file\n");
    init_parse_config_file("/init.rc"); //讀取rc文件

前面的都是初始化關鍵目錄和掛載文件系統,系統硬件設備,系統屬性等。

找到Android41/system/core/rootdir/init.rc

這個文件裏面還包括,ServiceManager IPC服務管理者啓動,surfaceflinger圖像服務,bootanim啓動動畫,media媒體服務等。

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

app_process包括2個東西zygote和system server的啓動

app_process啓動代碼在  frameworks/base/cmds/app_process/app_main.cpp
main中的主要代碼。

    while (i < argc) {
        const char* arg = argv[i++];
        if (!parentDir) {
            parentDir = arg;
        } else if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            niceName = "zygote";
        } else if (strcmp(arg, "--start-system-server") == 0) {
            startSystemServer = true;
        } else if (strcmp(arg, "--application") == 0) {
            application = true;
        } 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) {
        <strong>runtime.start("com.android.internal.os.ZygoteInit",
                startSystemServer ? "start-system-server" : "");</strong>
    } else if (className) {
        // Remainder of args get passed to startup class main()
        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和RuntimeInit,AppRuntime是Android dvm 啓動對象,

虛擬機的啓動在/Android41/frameworks/base/core/jni/AndroidRuntime.cpp 裏面包含了大量的初始化比如heap大小內存分配等,這裏暫時不說。

先看ZygoteInit代碼

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

    public static void main(String argv[]) {
        try {
            // Start profiling the zygote initialization.
            SamplingProfilerIntegration.start();

            registerZygoteSocket();
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                SystemClock.uptimeMillis());
            preload();
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                SystemClock.uptimeMillis());

            // Finish profiling the zygote initialization.
            SamplingProfilerIntegration.writeZygoteSnapshot();

            // Do an initial gc to clean up after startup
            gc();

            // If requested, start system server directly from Zygote
            if (argv.length != 2) {
                throw new RuntimeException(argv[0] + USAGE_STRING);
            }

            if (argv[1].equals("start-system-server")) {
                startSystemServer();
            } else if (!argv[1].equals("")) {
                throw new RuntimeException(argv[0] + USAGE_STRING);
            }

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

            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;
        }
    }

zygote主要是孵化app的,通過啓動一個socketServer來接受app啓動的請求,app啓動是靠ActivityManagerService來發送Socket通信的。

下面看看啓動SystemService

    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,3006,3007",
            "--capabilities=130104352,130104352",
            "--runtime-init",
            "--nice-name=system_server",
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

            /* Request to fork the system server process */
            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(parsedArgs);
        }

        return true;
    }

這地方需要調用Zygote的靜態方法

/Android41/libcore/dalvik/src/main/java/dalvik/system/Zygote.java 其實是需要調用對應的native方法.

forkSystemServer fork一個獨立進程用於SystemServer

native方法在 /Android41/dalvik/vm/native/dalvik_system_zygote.cpp

fork成功後,就調用傳入的參數com.android.server.SystemServer.java


SystemServer開啓了Android應用層的大部分服務,包括電源管理,電池,網絡 AMS  WMS等。

frameworks/base/services/java/com/android/server/SystemServer  目錄下面也包含了大量的相應的服務代碼。


    public static final void init2() {
        Slog.i(TAG, "Entered the Android system server!");
        Thread thr = new ServerThread();
        thr.setName("android.server.ServerThread");
        thr.start();
    }

init2函數是native方法

有 native public static void init1(String[] args);調用。

找到對應的底層代碼。

/AndroidSource/Android41/frameworks/base/services/jni/com_android_server_SystemServer.cpp

namespace android {

extern "C" int system_init();

static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
{
    system_init();
}

/*
 * JNI registration.
 */
static JNINativeMethod gMethods[] = {
    /* name, signature, funcPtr */
    { "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 },//註冊了init1方法
};

int register_android_server_SystemServer(JNIEnv* env)
{
    return jniRegisterNativeMethods(env, "com/android/server/SystemServer",
            gMethods, NELEM(gMethods));
}

}; // namespace android


system_init()是個外部函數,到那找到函數體?

/AndroidSource/Android41/frameworks/base/services/jni/Android.mk文件中有添加靜態Library

LOCAL_SHARED_LIBRARIES := \
    libandroid_runtime \
    libandroidfw \
    libcutils \
    libhardware \
    libhardware_legacy \
    libnativehelper \
    libsystem_server \
    libutils \
    libui \
    libinput \
    libskia \
    libgui \
    libusbhost \
    libsuspend

system_server和android_runtime是個關鍵.

system_server 在 /AndroidSource/Android41/frameworks/base/cmds/system_server 可以找到,可以看Android.mk文件知道模塊都編譯了那些文件

看System_init.cpp代碼方法

extern "C" status_t system_init()
{
    ALOGI("Entered 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;
    }
    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");

    return NO_ERROR;
}

上面是jni相關操作,並不難理解。找到com.android.server.SystemServer類,執行init2方法

init2方法啓動了線程開始了Android服務的加載和啓動。


基本流程就是啓動Zygote進程,虛擬機的創建,然後是SystemServer加載服務,當然還同時啓動了其它服務包括ServiceManager,SurfaceFlinger程序。

下一部分詳細分析SystemServer啓動和ActivityManagerService啓動應用程序。


畫個圖容易記住。




本文粗淺的介紹了一下Android啓動流程,若有問題,請指出 謝謝。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章