天天看點

SystemServer的建立 api29

本文章基于 api29的代碼進行的分析

網上搜尋的部分文章 ZygoteInit 都不一樣 原因基本上是因為各個api都有改動 但是基本流程沒有太大變化 大家可以按照

自己的需求食用

  1. 系統的第一個使用者程序Init程序啟動
  2. 解析init.rc檔案
  3. 從init程序中fork出zygote程序,也就是app_main.cpp檔案
  4. zygote程序調用AppRuntime的start方法啟動ZygoteInit,進入java
  5. ZygoteInit調用Zygote的方法fork一個system_server程序
  6. Zygote調用forkSystemServer方法建立SystemServer

1.解析init.rc檔案

init是Android系統中使用者級的第一個程序。通過ps指令可以看到,程序ID是1.

既然整個使用者系統都是從init開始的,那麼SystemService肯定也是從這裡建立了。

init程序的入口是main()方法

/system/core/init/init.cpp:

int main(int argc, char** argv) {
    parser.ParseConfig("/init.rc");
}
           

要解析一個init.rc檔案

import /init.${ro.zygote}.rc
           

以init.zygote64.rc為例

/system/core/rootdir/init.zygote64.rc

service zygote /system/bin/app_process64 -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 audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart netd
    writepid /dev/cpuset/foreground/tasks
           

通過解析這個檔案,會從init程序中fork出zygote程序。

2.從init程序中fork出zygote程序,也就是app_main.cpp檔案

zygote對應的源檔案是app_main.cpp,這個程序把自己的名字重命名為zygote。

/frameworks/base/cmds/app_process/app_main.cpp:

static const char ZYGOTE_NICE_NAME[] = "zygote64";
int main(int argc, char* const argv[]){
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    while (i < argc) {
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            niceName = ZYGOTE_NICE_NAME;
        }
    }
    //重命名程序名字
    if (!niceName.isEmpty()) {
        runtime.setArgv0(niceName.string());
        set_process_name(niceName.string());
    }
    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.");
        return 10;
    }
}
           

看到最後又一句runtime.start(“com.android.internal.os.ZygoteInit”, args, zygote);,

把事情交給runtime去做。runtime是AppRuntime,AppRuntime是繼承AndroidRuntime的:

/frameworks/base/cmds/app_process/app_main.cpp:
           
class AppRuntime : public AndroidRuntime{
    public:AppRuntime(char* argBlockStart, const size_t argBlockLength)
        : AndroidRuntime(argBlockStart, argBlockLength)
        , mClass(NULL){}
        
void setClassNameAndArgs(const String8& className, int argc, char * const *argv) {
    ......
}

virtual void onVmCreated(JNIEnv* env){
    ......
}

virtual void onStarted(){
    ......
}

virtual void onZygoteInit(){
    ......
}

virtual void onExit(int code){
    ......
}
}
           

AppRuntime并沒有start方法,是以start方法是AndroidRuntime的:

/frameworks/base/core/jni/AndroidRuntime.cpp
           
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
    //設定ANDROID_ROOT環境變量
    const char* rootDir = getenv("ANDROID_ROOT");
    if (rootDir == NULL) {
        rootDir = "/system";
        if (!hasDir("/system")) {
            LOG_FATAL("No root directory specified, and /android does not exist.");
            return;
        }
        setenv("ANDROID_ROOT", rootDir, 1);
    }
//啟動虛拟機
if (startVm(&mJavaVM, &env, zygote) != 0) {
    return;
}
onVmCreated(env);

//注冊Android的JNI函數
if (startReg(env) < 0) {
    ALOGE("Unable to register all android natives\n");
    return;
}

//用數組儲存類名和參數
stringClass = env->FindClass("java/lang/String");
strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
classNameStr = env->NewStringUTF(className);
env->SetObjectArrayElement(strArray, 0, classNameStr);
for (size_t i = 0; i < options.size(); ++i) {
    jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
    assert(optionsStr != NULL);
    env->SetObjectArrayElement(strArray, i + 1, optionsStr);
}

//找到這個類,并執行這個類的main方法,前面調用時傳入的是`com.android.internal.os.ZygoteInit`
char* slashClassName = toSlashClassName(className);
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
    ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
    /* keep going */
} else {
    //找到main方法
    jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
        "([Ljava/lang/String;)V");
    if (startMeth == NULL) {
        ALOGE("JavaVM unable to find main() in '%s'\n", className);
        /* keep going */
    } else {
        //通過JNI執行main方法,com.android.internal.os.ZygoteInit是一個java類
        env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
//zygote退出
if (mJavaVM->DetachCurrentThread() != JNI_OK)
    ALOGW("Warning: unable to detach main thread\n");
if (mJavaVM->DestroyJavaVM() != 0)
    ALOGW("Warning: VM did not shut down cleanly\n");
           

這個start方法啟動AndroidRuntime,先啟動虛拟機,然後注冊JNI函數,最後通過傳進來的第一個參數找到相應的類,并執行他的main()方法。

這時,從native進入java層了。

3.zygote程序調用AppRuntime的start方法啟動ZygoteInit,進入java

進入Java代碼 ZygoteInit.java

下面就是ZygoteInit的main方法:

ZygoteInit.java  api29  819行
public static void main(String argv[]) {
        ZygoteServer zygoteServer = null;
        ...
        try {
            ...
            // 895行
            Zygote.initNativeState(isPrimaryZygote);

            ZygoteHooks.stopZygoteNoThreadCreation();

            zygoteServer = new ZygoteServer(isPrimaryZygote);

            if (startSystemServer) {
                //調用forkSystemServer方法 建立出SystemServer
                Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
			...
            }
		...
    }
           

關注 forkSystemServer()方法

  1. ZygoteInit調用Zygote的方法fork一個system_server程序

    ZygoteInit.java  api29  724行	
    	注釋 :為系統伺服器程序準備參數和分叉。
    	/**
         * Prepare the arguments and forks for the system server process.
         *...
         */
        private static Runnable forkSystemServer(String abiList, String socketName,
                ZygoteServer zygoteServer) {
            ...
            try {
              	... 
                /* Request to fork the system server process */
                  直譯:請求分叉系統伺服器程序  780行
                pid = Zygote.forkSystemServer(
                        parsedArgs.mUid, parsedArgs.mGid,
                        parsedArgs.mGids,
                        parsedArgs.mRuntimeFlags,
                        null,
                        parsedArgs.mPermittedCapabilities,
                        parsedArgs.mEffectiveCapabilities);
            } catch (IllegalArgumentException ex) {
                throw new RuntimeException(ex);
            }
    		...
        }
               
  2. Zygote調用forkSystemServer方法建立SystemServer

    Zygote.java  api29  461行	
    /**
     * Special method to start the system server process. In addition to the
     * common actions performed in forkAndSpecialize, the pid of the child
     * process is recorded such that the death of the child process will cause
     * zygote to exit.
     * ...
     */
    static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
        ...
        int pid = nativeForkSystemServer(
                uid, gid, gids, runtimeFlags, rlimits,
                permittedCapabilities, effectiveCapabilities);
        ...
    }
    
    private static native int nativeForkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities);
               

    最終調用到native方法 但是由注釋可以了解到 SystemServer建立了

    感興趣的大佬可以自己追一下代碼

    /frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
               
    native之後的方法

參考:前1-3是從網上參考的 具體部落格我給弄丢了 如果有看到可以貼到評論區

​ 源碼查詢網址:http://androidxref.com/

​ https://www.androidos.net.cn/sourcecode

如果文章有什麼問題 請一定要在評論或者私信告訴我 非常感謝

位址