Android啓動源碼分析

1.首先進入的是init

init是Linux系統中用戶空間的第一個進程(pid=1), Kernel啓動後會調用 Init.c的main()方法.

路徑:/system/core/init/Init.c

int main(int argc, char **argv)
{
    。。。

    //掛載一些基本的文件系統
    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);

    //初始化Kernal log
    klog_init();
    //初始化屬性
    property_init();

	//讀取硬件版本
    get_hardware_name(hardware, &revision);

	//處理kernel命令行
    process_kernel_cmdline();

    //SELinux初始化
    selinux_initialize();

	//加載default.prop文件
    property_load_boot_defaults();

    //初始化讀取init.rc
    init_parse_config_file("/init.rc");

	//執行 early-init語句的觸發器
    action_for_each_trigger("early-init", action_add_queue_tail);

    //執行init語句
    action_for_each_trigger("init", action_add_queue_tail);
    //如果是充電狀態,處理charger;否則處理late-init
    if (is_charger) {
        action_for_each_trigger("charger", action_add_queue_tail);
    } else {
        action_for_each_trigger("late-init", action_add_queue_tail);
    }

	for(;;) {

		//循環等待事件 1,中斷事件  2 按鍵事件等等
		nr = poll(ufds, fd_count, timeout);

	}

init進程主要的功能:

  • 分析和運行所有的init.rc
  • 生成設備驅動節點
  • 處理子線程的終止(signal方式)
  • 提供屬性服務property service

基本流程
在這裏插入圖片描述

1.1解析init.rc文件

路徑:device/friendly-arm/nanopi2/init.rc

首先看下開頭

import /init.environ.rc
import /init.usb.rc
import /init.${ro.hardware}.rc
import /init.${ro.zygote}.rc
import /init.trace.rc

分爲五個rc文件的解析。
我們主要看init.rc,init.nanopi2.rc,init.zygote32.rc三個文件。

Init.rc

前期的執行主要是建立文件系統文件夾,配置sys值,修改系統文件權限等等。
後期開啓許多系統後臺服務

## Daemon processes to be run by init.
##
//ueventd主要是負責設備節點的創建、權限設定等一些列工作

service ueventd /sbin/ueventd
    class core
    critical
    seclabel u:r:ueventd:s0

//log後臺服務
service logd /system/bin/logd
    class core
    socket logd stream 0666 logd logd
    socket logdr seqpacket 0666 logd logd
    socket logdw dgram 0222 logd logd
    seclabel u:r:logd:s0

// healthd後臺服務
service healthd /sbin/healthd
    class core
    critical
    seclabel u:r:healthd:s0

//控制檯
service console /system/bin/sh
    class core
    console
    disabled
    user shell
    group shell log
    seclabel u:r:shell:s0
//adb後臺服務

# adbd is controlled via property triggers in init.<platform>.usb.rc
service adbd /sbin/adbd --root_seclabel=u:r:su:s0
    class core
    socket adbd stream 660 system system
    disabled
    seclabel u:r:adbd:s0

# adbd on at boot in emulator
on property:ro.kernel.qemu=1
    start adbd

//低內存管理服務
service lmkd /system/bin/lmkd
    class core
    critical
    socket lmkd seqpacket 0660 system system

//serviceManager服務
service servicemanager /system/bin/servicemanager
    class core
    user system
    group system
    critical
    onrestart restart healthd
    onrestart restart zygote
    onrestart restart media
    onrestart restart surfaceflinger
    onrestart restart drm
//外置存儲器管理服務
service vold /system/bin/vold
    class core
    socket vold stream 0660 root mount
    ioprio be 2

//網絡後臺管理
service netd /system/bin/netd
    class main
    socket netd stream 0660 root system
    socket dnsproxyd stream 0660 root inet
    socket mdns stream 0660 root system
    socket fwmarkd stream 0660 root inet

//調試
service debuggerd /system/bin/debuggerd
    class main

service debuggerd64 /system/bin/debuggerd64
    class main

//ril後臺服務
service ril-daemon /system/bin/rild
    class main
    socket rild stream 660 root radio
    socket rild-debug stream 660 radio system
    user root
    group radio cache inet misc audio log

//surfaceflinger服務
service surfaceflinger /system/bin/surfaceflinger
    class core
    user system
    group graphics drmrpc
    onrestart restart zygote

service drm /system/bin/drmserver
    class main
    user drm
    group drm system inet drmrpc

//媒體服務
service media /system/bin/mediaserver
    class main
    user media
    group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm
    ioprio rt 4

//加密服務
# One shot invocation to deal with encrypted volume.
service defaultcrypto /system/bin/vdc --wait cryptfs mountdefaultencrypted
    disabled
    oneshot
    # vold will set vold.decrypt to trigger_restart_framework (default
    # encryption) or trigger_restart_min_framework (other encryption)

//動畫服務
service bootanim /system/bin/bootanimation
    class core
    user graphics
    group graphics audio
    disabled
    oneshot

//安裝app服務
service installd /system/bin/installd
    class main
    socket installd stream 600 system system

service flash_recovery /system/bin/install-recovery.sh
    class main
    seclabel u:r:install_recovery:s0
    oneshot

service racoon /system/bin/racoon
    class main
    socket racoon stream 600 system system
    # IKE uses UDP port 500. Racoon will setuid to vpn after binding the port.
    group vpn net_admin inet
    disabled
    oneshot
//設備媒體
service mtpd /system/bin/mtpd
    class main
    socket mtpd stream 600 system system
    user vpn
    group vpn net_admin inet net_raw
    disabled
    oneshot

//keystore管理服務
service keystore /system/bin/keystore /data/misc/keystore
    class main
    user keystore
    group keystore drmrpc

//dump狀態服務
service dumpstate /system/bin/dumpstate -s
    class main
    socket dumpstate stream 0660 shell log
    disabled
    oneshot

//dns守護
service mdnsd /system/bin/mdnsd
    class main
    user mdnsr
    group inet net_raw
    socket mdnsd stream 0660 mdnsr inet
    disabled
    oneshot
service pre-recovery /system/bin/uncrypt
    class main
    disabled
    oneshot

init.nanopi2.rc

前面也是添加建立一些文件,設備節點權限等等;
後面添加一些硬件設備相關的服務,大部分是網絡相關的服務。

# wifi
 無線網絡進行管理和控制服務

service wpa_supplicant /system/bin/wpa_supplicant \
    -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \
    -I/system/etc/wifi/wpa_supplicant_overlay.conf \
    -O/data/misc/wifi/sockets \
    -e/data/misc/wifi/entropy.bin -g@android:wpa_wlan0
    #   we will start as root and wpa_supplicant will switch to user wifi
    #   after setting up the capabilities required for WEXT
    #   user wifi
    #   group wifi inet keystore
    class main
    socket wpa_wlan0 dgram 660 wifi wifi
    disabled
    oneshot

service dhcpcd_wlan0 /system/bin/dhcpcd -aABDKL
    class main
    disabled
    oneshot

service iprenew_wlan0 /system/bin/dhcpcd -n
    class main
    disabled
    oneshot

# wifi-p2p

service p2p_supplicant /system/bin/wpa_supplicant \
    -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \
    -I/system/etc/wifi/wpa_supplicant_overlay.conf \
    -O/data/misc/wifi/sockets -N \
    -ip2p0 -Dnl80211 -c/data/misc/wifi/p2p_supplicant.conf \
    -I/system/etc/wifi/p2p_supplicant_overlay.conf \
    -puse_p2p_group_interface=1 -e/data/misc/wifi/entropy.bin \
    -g@android:wpa_wlan0
    #   we will start as root and wpa_supplicant will switch to user wifi
    #   after setting up the capabilities required for WEXT
    #   user wifi
    #   group wifi inet keystore
    class main
    socket wpa_wlan0 dgram 660 wifi wifi
    disabled
    oneshot

service dhcpcd_p2p /system/bin/dhcpcd -aABKL
    class main
    disabled
    oneshot

service iprenew_p2p /system/bin/dhcpcd -n
    class main
    disabled
    oneshot
# eth0
service dhcpcd_eth0 /system/bin/dhcpcd -ABDKL
    class main
    disabled
    oneshot

service iprenew_eth0 /system/bin/dhcpcd -n
    class main
    disabled
    oneshot

# bt-pan
service dhcpcd_bt-pan /system/bin/dhcpcd -aABDKL
    class main
    disabled
    oneshot
service iprenew_bt-pan /system/bin/dhcpcd -n
    class main
    disabled
    oneshot

init.zygote32.rc

啓動zygote孵化器服務,見下章

那麼init.rc解析開啓服務的流程如下

在這裏插入圖片描述

2.啓動Zygote

通過init進程解析init.rc文件後,Zygote進程啓動

路徑 system/core/rootdir/init.zygote32.rc

service zygote /system/bin/app_process32 -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

service zygote 啓動zygote服務

zygote路徑 frameworks/base/cmds/app_process/app_main.cpp

app_main.cpp

int main(int argc, char* const argv[])
{
    if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
        // Older kernels don't understand PR_SET_NO_NEW_PRIVS and return
        // EINVAL. Don't die on such kernels.
        if (errno != EINVAL) {
            LOG_ALWAYS_FATAL("PR_SET_NO_NEW_PRIVS failed: %s", strerror(errno));
            return 12;
        }
    }

    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    // 處理命令參數
    argc--;
    argv++;
 	int i;
    for (i = 0; i < argc; i++) {
        if (argv[i][0] != '-') {
            break;
        }
        if (argv[i][1] == '-' && argv[i][2] == 0) {
            ++i; // Skip --.
            break;
        }
        runtime.addOption(strdup(argv[i]));
    }

    // 解析Runtime的參數
    bool zygote = false;
    bool startSystemServer = false;
    bool application = false;
    String8 niceName;
    String8 className;

    ++i;  // Skip unused "parent dir" argument.
    while (i < argc) {
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            niceName = ZYGOTE_NICE_NAME;
        } 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.setTo(arg + 12);
        } else if (strncmp(arg, "--", 2) != 0) {
            className.setTo(arg);
            break;
        } else {
            --i;
 		  break;
        }
    }

    Vector<String8> args;
    if (!className.isEmpty()) {
        // We're not in zygote mode, the only argument we need to pass
        // to RuntimeInit is the application argument.
        //
        // The Remainder of args get passed to startup class main(). Make
        // copies of them before we overwrite them with the process name.
        args.add(application ? String8("application") : String8("tool"));
        runtime.setClassNameAndArgs(className, argc - i, argv + i);
    } else {
        // We're in zygote mode.
        maybeCreateDalvikCache();

        if (startSystemServer) {
            args.add(String8("start-system-server"));
        }

        char prop[PROP_VALUE_MAX];
        if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
            LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
                ABI_LIST_PROPERTY);
            return 11;
        }
        String8 abiFlag("--abi-list=");
        abiFlag.append(prop);
        args.add(abiFlag);

        // In zygote mode, pass all remaining arguments to the zygote
        // main() method.
        for (; i < argc; ++i) {
            args.add(String8(argv[i]));
        }
    }

    //給Runtime設置參數
    if (!niceName.isEmpty()) {
        runtime.setArgv0(niceName.string());
        set_process_name(niceName.string());
    }
//啓動Runtime
    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args);
    } 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;
    }
}

從代碼中我們看到,app_main.cpp主要處理的是開啓AndroidRuntime。
下面看看Runtime啓動後究竟做了哪些事情。
首先我們看看AppRuntime 類的定義。

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) {
        mClassName = className;
        for (int i = 0; i < argc; ++i) {
             mArgs.add(String8(argv[i]));
        }
    }
//創建VM
    virtual void onVmCreated(JNIEnv* env)
    {
        if (mClassName.isEmpty()) {
            return; // Zygote. Nothing to do here.
        }

        /*
         * This is a little awkward because the JNI FindClass call uses the
         * class loader associated with the native method we're executing in.
         * If called in onStarted (from RuntimeInit.finishInit because we're
         * launching "am", for example), FindClass would see that we're calling
         * from a boot class' native method, and so wouldn't look for the class
         * we're trying to look up in CLASSPATH. Unfortunately it needs to,
         * because the "am" classes are not boot classes.
         *
         * The easiest fix is to call FindClass here, early on before we start
         * executing boot class Java code and thereby deny ourselves access to
         * non-boot classes.
         */
        char* slashClassName = toSlashClassName(mClassName.string());
        mClass = env->FindClass(slashClassName);
        if (mClass == NULL) {
            ALOGE("ERROR: could not find class '%s'\n", mClassName.string());
        }
        free(slashClassName);

        mClass = reinterpret_cast<jclass>(env->NewGlobalRef(mClass));
    }
//啓動VM
    virtual void onStarted()
    {
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool();

        AndroidRuntime* ar = AndroidRuntime::getRuntime();
        ar->callMain(mClassName, mClass, mArgs);

        IPCThreadState::self()->stopProcess();
    }
    virtual void onZygoteInit()
    {
        // Re-enable tracing now that we're no longer in Zygote.
        atrace_set_tracing_enabled(true);

        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool();
}
//退出VM
 	virtual void onExit(int code)
    {
        if (mClassName.isEmpty()) {
            // if zygote
            IPCThreadState::self()->stopProcess();
        }

        AndroidRuntime::onExit(code);
    }


    String8 mClassName;
    Vector<String8> mArgs;
    jclass mClass;
};

可以看出AppRuntime 類裏面美歐start方法,那麼它一定調用的是父類AndroidRuntime裏面的方法。
然後我們繼續尋找。下面就是截取的AndroidRuntime類的start方法

AndroidRuntime.java

void AndroidRuntime::start(const char* className, const Vector<String8>& options)
{  
。。。
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
JNIEnv* env;

//開啓虛擬機
    if (startVm(&mJavaVM, &env) != 0) {
        return;
    }
    onVmCreated(env);

    //註冊JNI函數
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }
 	//傳入的參數,通過反射機制調用相應的類的方法
    char* slashClassName = toSlashClassName(className);
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        //打印異常log
    } else {
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
 			//打印異常log
        } else {
            //最終會調用ZygoteInit.main()方法
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
           }
        }
       。。。
}

根據start方法傳入的參數runtime.start(“com.android.internal.os.ZygoteInit”, args)。開始方法中,首先是開啓虛擬機,然後註冊虛擬機裏面的JNI方法,最後JNI方法執行傳入參數的類的main方法。
所以在虛擬機啓動完成後,會調用com.android.internal.os.ZygoteInit類裏面的main方法。

ZygoteInit.java

路徑 frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static void main(String argv[]) {
        try {
            ...
            boolean startSystemServer = false;
            String socketName = "zygote";
            String abiList = null;
   		  //解析參數
            for (int i = 1; i < argv.length; i++) {
                if ("start-system-server".equals(argv[i])) {
                    startSystemServer = true;
                } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                    abiList = argv[i].substring(ABI_LIST_ARG.length());
                } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                    socketName = argv[i].substring(SOCKET_NAME_ARG.length());
                } else {
                    throw new RuntimeException("Unknown command line argument: " + argv[i]);
                }
            }

            if (abiList == null) {
                throw new RuntimeException("No ABI list supplied.");
            }
       //註冊ZygoteSocket
            registerZygoteSocket(socketName);

            //預載入類和資源
            preload();


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

            // 初始化GC
            gc();

            // Disable tracing so that forked processes do not inherit stale tracing tags from
            // Zygote.
            Trace.setTracingEnabled(false);

            //開啓SystemServer服務
            if (startSystemServer) {
                startSystemServer(abiList, socketName);
            }

            //進入循環模式,變成守護進程,接收socket信息進行處理
            runSelectLoop(abiList);

            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
            caller.run();
        } catch (RuntimeException ex) {
            Log.e(TAG, "Zygote died with exception", ex);
            closeServerSocket();
            throw ex;
        }
    }

這裏我們主要看看runSelectLoop方法的實現:

private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
        FileDescriptor[] fdArray = new FileDescriptor[4];
		//添加serverSocket服務 ,Zygote進程
        fds.add(sServerSocket.getFileDescriptor());
        peers.add(null);

        int loopCount = GC_LOOP_COUNT;
        while (true) {
            int index;


            if (loopCount <= 0) {
                gc();
                loopCount = GC_LOOP_COUNT;
            } else {
                loopCount--;
            }


            try {
                fdArray = fds.toArray(fdArray);
                index = selectReadable(fdArray);
            } catch (IOException ex) {
                throw new RuntimeException("Error in select()", ex);
            }

            if (index < 0) {
                throw new RuntimeException("Error in select()");
            } else if (index == 0) {
			//創建socket客戶端連接
                ZygoteConnection newPeer = acceptCommandPeer(abiList);
                peers.add(newPeer);
                fds.add(newPeer.getFileDescriptor());
            } else {
                boolean done;
			//處理客戶端數據事務
                done = peers.get(index).runOnce();

                if (done) {
                    peers.remove(index);
                    fds.remove(index);
                }
            }
        }
}

3.啓動SystemServer

SystemServer的在Android體系中所處的地位,SystemServer由Zygote fork生成的,進程名爲system_server,該進程承載着framework的核心服務。
在這裏插入圖片描述
紫色的流程運行在是Zygote進程,藍色的流程ZygoteInit.handleSystemServerProcess開始是運行在新創建的system_server,這是fork機制實現的(fork會返回2次)。下面從startSystemServer()開始講解詳細啓動流程。

看看startSystemServer的實現

private static boolean startSystemServer(String abiList, String socketName)
            throws MethodAndArgsCaller, RuntimeException {
        。。。
    //參數設置

        ZygoteConnection.Arguments parsedArgs = null;

        int pid;
		//ZygoteConnection參數設置

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

            //fork一個子線程 SystemServer
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        //子線程處理
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
		//處理SystemServer進程
            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }

主要看看handleSystemServerProcess方法

private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {

	   //關閉ServerSocket
        closeServerSocket();


        Os.umask(S_IRWXG | S_IRWXO);
	   //設置進程名
        if (parsedArgs.niceName != null) {
            Process.setArgV0(parsedArgs.niceName);
        }
        //執行一些dex的優化操作
        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
        if (systemServerClasspath != null) {
            performSystemServerDexOpt(systemServerClasspath);
        }
        //創建PathClassLoader加載器
if (systemServerClasspath != null) {
                cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
                Thread.currentThread().setContextClassLoader(cl);
        }

       //初始化
       RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);

}

system_server進程創建PathClassLoader類加載器.

RuntimeInit.java

路徑 frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {

    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
    redirectLogStreams(); //重定向log輸出

    commonInit(); // 通用的一些初始化
    nativeZygoteInit(); // zygote初始化
    applicationInit(targetSdkVersion, argv, classLoader); // [見小節3.4]
}

nativeZygoteInit()方法經過層層調用,會進入app_main.cpp中的onZygoteInit()方法, Binder線程池的創建也是在這個過程,如下:

virtual void onZygoteInit()
{
    sp<ProcessState> proc = ProcessState::self();
    proc->startThreadPool(); //啓動新binder線程
}

applicationInit()方法經過層層調用,會拋出異常ZygoteInit.MethodAndArgsCaller(m, argv), ZygoteInit.main() 會捕捉該異常, 見下文.

ZygoteInit.java

路徑 frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static void main(String argv[]) {
    try {
        startSystemServer(abiList, socketName); //拋出MethodAndArgsCaller異常
        ....
    } catch (MethodAndArgsCaller caller) {
        caller.run(); //此處通過反射,會調用SystemServer.main()方法 [見小節4.4]
    } catch (RuntimeException ex) {
        ...
    }
}

採用拋出異常的方式,用於棧幀清空,提供利用率, 以至於現在大家看到的每個Java進程的調用棧如下:

...
at com.android.server.SystemServer.main(SystemServer.java:175)
at java.lang.reflect.Method.invoke!(Native method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)

SystemServer.java

路徑 frameworks/base/services/java/com/android/server/SystemServer.java

public final class SystemServer {
    ...
    public static void main(String[] args) {
        //先初始化SystemServer對象,再調用對象的run()方法
        new SystemServer().run();
    }
}

SystemServer.java

private void run() {
    if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
        Slog.w(TAG, "System clock is before 1970; setting to 1970.");
        SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
    }
    ...

    Slog.i(TAG, "Entered the Android system server!");
    EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());

    Looper.prepareMainLooper();// 準備主線程looper

    //加載android_servers.so庫,該庫包含的源碼在frameworks/base/services/目錄下
    System.loadLibrary("android_servers");

    //檢測上次關機過程是否失敗,該方法可能不會返回[見小節3.6.1]
    performPendingShutdown();

    createSystemContext(); //初始化系統上下文

    //創建系統服務管理
    mSystemServiceManager = new SystemServiceManager(mSystemContext);
    LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

    //啓動各種系統服務[見小節3.7]
    try {
        startBootstrapServices(); // 啓動引導服務
        startCoreServices();      // 啓動核心服務
        startOtherServices();     // 啓動其他服務[見小節4.6]
    } catch (Throwable ex) {
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    }

    //一直循環執行
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

SystemServer.java

public final class SystemServer {

    private void startBootstrapServices() {
      ...
      //phase100
      mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
      ...
    }

    private void startOtherServices() {
        ...
        //phase480 和phase500
        mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
        mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
        ...
        //[見小節4.7]
        mActivityManagerService.systemReady(new Runnable() {
           @Override
           public void run() {
               //phase550
               mSystemServiceManager.startBootPhase(
                       SystemService.PHASE_ACTIVITY_MANAGER_READY);
               ...
               //phase600
               mSystemServiceManager.startBootPhase(
                       SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
            }
        }
    }
}
  • start: 創建AMS, PMS, LightsService, DMS.
  • phase100: 進入Phase100, 創建PKMS, WMS, IMS, DBMS, LockSettingsService, JobSchedulerService, MmsService等服務;
  • phase480 && 500: 進入Phase480, 調用WMS, PMS, PKMS, DisplayManagerService這4個服務的systemReady();
  • Phase550: 進入phase550, 執行AMS.systemReady(), 啓動SystemUI, WebViewFactory, Watchdog.
  • Phase600: 進入phase600, 執行AMS.systemReady(), 執行各種服務的systemRunning().
  • Phase1000: 進入1000, 執行finishBooting, 啓動啓動on-hold進程.

AMS.systemReady

路徑 frameworks/base/services/core/java/com/android/server/am/ActivityManagerServer.java

public final class ActivityManagerService extends ActivityManagerNative
    implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

    public void systemReady(final Runnable goingCallback) {
        ... //update相關
        mSystemReady = true;

        //殺掉所有非persistent進程
        removeProcessLocked(proc, true, false, "system update done");
        mProcessesReady = true;

        goingCallback.run();  //[見小節1.6.2]

        addAppLocked(info, false, null); //啓動所有的persistent進程
        mBooting = true;

        //啓動home
        startHomeActivityLocked(mCurrentUserId, "systemReady");
        //恢復棧頂的Activity
        mStackSupervisor.resumeTopActivitiesLocked();
    }
}

System_server主線程的啓動工作,總算完成, 進入Looper.loop()狀態,等待其他線程通過handler發送消息再處理.
從解析rc文件到啓動AndroidRuntime,Zygote,SystemServer流程圖
在這裏插入圖片描述

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