android系統啓動過程

Android的啓動過程可以分爲兩個階段,第一階段是Linux的啓動,第二階段纔是Android的啓動,下面我們分別來了解一下具體的過程。
首先是Linux啓動,這一部分我想就可以略過了,無非是Linux的Bootloader,Kernel,Driver之類的,在這裏唯一要提到的就是ServiceManager,即服務管理器,這個是做爲一個進程在Android加載之前就被啓動了,我們可以從init.rc中看到這個配置項:
service servicemanager /system/bin/servicemanager
ServiceManager是Binder的服務管理守護進程,是Binder的核心,由其使用Binder驅動進行IPC管理,關於IPC通訊的機制,此處不再詳述。在APP和Framework中,應用程序使用的ServiceManager.java就是通過Proxy與這個守護進程進行的通訊。

然後是Android的啓動,接下來要詳細描述的部分。我們還是先看一下init.rc中的配置
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
即linux啓動以後,啓動zygote服務進程,這個進程恰如其名:孵化器,是所有Android應用程序的孵化器。

我們來看一下app_process的代碼,位置是在:
frameworks/base/cmds/app_process/app_main.cpp
在main()函數中有如下代碼:
       if (0 == strcmp("--zygote", arg)) {
           bool startSystemServer = (i < argc) ?
                   strcmp(argv, "--start-system-server") == 0 : false;
           setArgv0(argv0, "zygote");
           set_process_name("zygote");
           runtime.start("com.android.internal.os.ZygoteInit",
               startSystemServer);
       }
從中可以追蹤到AndroidRuntime,代碼位於:
frameworks/base/core/jni/AndroidRuntime.cpp
在start()函數中有如下代碼:
   /* start the virtual machine */
   if (startVm(&mJavaVM, &env) != 0)
       goto bail;
        ……
                env->CallStaticVoidMethod(startClass, startMeth, strArray);
即先啓動了虛擬機,然後利用JNI調用了zygoteInit函數。

繼續追蹤到frameworks/base/core/java/com/android/internal/os/ZygoteInit.java的main()函數,代碼如下:
           if (argv[1].equals("true")) {
               startSystemServer();
           } else if (!argv[1].equals("false")) {
               throw new RuntimeException(argv[0] + USAGE_STRING);
           }

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

           if (ZYGOTE_FORK_MODE) {
               runForkMode();
           } else {
               runSelectLoopMode();
           }
前一部分是在啓動系統服務,後一部分是雖然是一個條件判斷,但ZYGOTE_FORK_MODE被賦了false,所以進行else分支的runSelectLoopMode()函數,在該函數中,實際上是在一死循環中利用zygoteConnection類通過socket的方式進行消息處理,用於fork出新的zygote,從而以最輕量級的方式實現每個進程一個虛擬機的機制。

繼續來看startSystemServer(),代碼位於:
frameworks/base/services/java/com/android/server/systemserver.java
在其main()函數中調用了init1(args)這個native函數,利用JNI機制,跟蹤至
frameworks/base/services/jni/com_android_server_systemService.cpp,然後到
frameworks/base/cmds/system_server/library/system_init.cpp
在system_init()函數中有如下代碼:
   if (strcmp(propBuf, "1") == 0) {
       // Start the SurfaceFlinger
       SurfaceFlinger::instantiate();
   }
   AndroidRuntime* runtime = AndroidRuntime::getRuntime();

   LOGI("System server: starting Android services./n");
   runtime->callStatic("com/android/server/SystemServer", "init2");
即完成了SurfaceFlinger的實例化,然後利用運行時的callStatic()函數調用了SystemServer的init2()函數,這個函數位於:
frameworks/base/services/java/com/android/server/SystemServer.java
代碼是:
   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線程中,可以看到我們熟悉的Android服務了,比如WallpaperService服務的啓動:
           try {
               Slog.i(TAG, "Wallpaper Service");
               wallpaper = new WallpaperManagerService(context);
               ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);
           } catch (Throwable e) {
               Slog.e(TAG, "Failure starting Wallpaper Service", e);
           }
最後,調用各服務的systemReady()函數通知系統就緒。

至此,系統的啓動過程結束,借用兩張圖來說明問題:

172538uhbox5f2thpoqj23.gif
從這裏可以看出,linux的init在啓動若干守護進程之後,就啓動了Android的runtime和zygote,zygote再啓動虛擬機,系統服務,系統服務再啓動完本地服務後,又啓動了若干Android服務,並完成向ServiceManager的註冊工作,最後系統啓動完成。系統的進程空間如下圖所示:


可見,由zygote孵化器爲各進程以寫時複製的方式用最小的代價實現了虛擬機。
172539y8yl2w4ww87jrw07.gif
好了,相信經過這一系列的源碼跟蹤,我們都能對Android的啓動過程有更清晰的認識
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章