Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android開機啟動過程

android開機啟動過程

編輯:關於Android編程

Linux內核啟動之後就到Android Init進程,進而啟動Android相關的服務和應用。

啟動的過程如下圖所示:

   image


  

  下面將從Android4.0源碼中,和網絡達人對此的總結中,對此過程加以學習了解和總結,

以下學習過程中代碼片段中均有省略不完整,請參照源碼。

 

一 Init進程的啟動

  init進程,它是一個由內核啟動的用戶級進程。內核自行啟動(已經被載入內存,開始運行,

並已初始化所有的設備驅動程序和數據結構等)之後,就通過啟動一個用戶級程序init的方式,完成引導進程。init始終是第一個進程。

  啟動過程就是代碼init.c中main函數執行過程:system\core\init\init.c

在函數中執行了:文件夾建立,掛載,rc文件解析,屬性設置,啟動服務,執行動作,socket監聽……

下面看兩個重要的過程:rc文件解析和服務啟動。

1 rc文件解析

  .rc文件是Android使用的初始化腳本文件 (System/Core/Init/readme.txt中有描述:

four broad classes of statements which are Actions, Commands, Services, and Options.)

  其中Command 就是系統支持的一系列命令,如:export,hostname,mkdir,mount,等等,其中一部分是 linux 命令,

還有一些是 android 添加的,如:class_start: 啟動服務,class_stop:關閉服務,等等。

  其中Options是針對 Service 的選項的。

系統初始化要觸發的動作和要啟動的服務及其各自屬性都在rc腳本文件中定義。 具體看一下啟動腳本:\system\core\rootdir\init.rc

在解析rc腳本文件時,將相應的類型放入各自的List中:

  \system\core\init\Init_parser.c :init_parse_config_file( )存入到

  action_queue、 action_list、 service_list中,解析過程可以看一下parse_config函數,類似狀態機形式挺有意思。

  這其中包含了服務:adbd、servicemanager、vold、ril-daemon、debuggerd、surfaceflinger、zygote、media……

2 服務啟動

文件解析完成之後將service放入到service_list中。

 

文件解析完成之後將service放入到service_list中。

  \system\core\init\builtins.c

Service的啟動是在do_class_start函數中完成:

int do_class_start(int nargs, char **args)
{
    service_for_each_class(args[1], service_start_if_not_disabled);
    return 0;
}

 

遍歷所有名稱為classname,狀態不為SVC_DISABLED的Service啟動

 

void service_for_each_class(const char *classname,
                            void (*func)(struct service *svc))
{
       ……
}

static void service_start_if_not_disabled(struct service *svc)
{
    if (!(svc->flags & SVC_DISABLED)) {
        service_start(svc, NULL);
    }
}
do_class_start對應的命令:

 

  KEYWORD(class_start, COMMAND, 1, do_class_start)

 

init.rc文件中搜索class_start:class_start main 、class_start core、……

 

  main、core即為do_class_start參數classname

 

init.rc文件中Service class名稱都是main:

 

service drm /system/bin/drmserver

 

    class main

 

  service surfaceflinger /system/bin/surfaceflinger

 

   class main

 

於是就能夠通過main名稱遍歷到所有的Service,將其啟動。

do_class_start調用:

init.rc中

    on boot  //action

      class_start core    //執行command 對應 do_class_start

     class_start main

 

Init進程main函數中:system/core/init/init.c中:復制代碼

int main(){

     //掛在文件

//解析配置文件:init.rc……

//初始化化action queue

     ……
       for(;;){

              execute_one_command();

              restart_processes();

              for (i = 0; i 
 循環調用service_start,將狀態SVC_RESTARTING啟動, 將啟動後的service狀態設置為SVC_RUNNING。

  pid=fork();

  execve();

 在消息循環中:Init進程執行了Android的Command,啟動了Android的NativeService,監聽Service的變化需求,Signal處理。

Init進程是作為屬性服務(Property service),維護這些NativeService。

二 ServiceManager啟動

在.rc腳本文件中zygote的描述:

service servicemanager /system/bin/servicemanager
  class core
  user system
  group system
  critical
  onrestart restart zygote
  onrestart restart media
  onrestart restart surfaceflinger
  onrestart restart drm

ServiceManager用來管理系統中所有的binder service,不管是本地的c++實現的還是java語言實現的都需要

這個進程來統一管理,最主要的管理就是,注冊添加服務,獲取服務。所有的Service使用前都必須先在servicemanager中進行注冊。

  do_find_service( )

  do_add_service( )

  svcmgr_handler( )

  代碼位置:frameworks\base\cmds\servicemanager\Service_manager.c

三 Zygote進程的啟動

  Zygote這個進程是非常重要的一個進程,Zygote進程的建立是真正的Android運行空間,初始化建立的Service都是Navtive service.

(1) 在.rc腳本文件中zygote的描述:

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
  class main
  socket zygote stream 666
  onrestart write /sys/android_power/request_state wake
  onrestart write /sys/power/state on
  onrestart restart media
  onrestart restart netd

參數:--zygote --start-system-server
代碼位置:frameworks/base/cmds/app_process/app_main.cpp

上面的參數在這裡就會用上,決定是否要啟動和啟動那些進程。

int main( ){
       AppRuntime runtime;
       if (zygote) {
              runtime.start("com.android.internal.os.ZygoteInit",
                startSystemServer ? "start-system-server" : "");
       }
}

class AppRuntime : public AndroidRuntime{};

(2) 接著到了AndroidRuntime類中:

frameworks\base\core\jni\AndroidRuntime.cpp

void start(const char* className, const char* options){

       // start the virtual machine Java在虛擬機中運行的
       JNIEnv* env;
       if (startVm(&mJavaVM, &env) != 0) {
              return;
       }

       //向剛剛新建的虛擬機注冊JNI本地接口
       if (startReg(env) GetStaticMethodID(startClass,
         "main","([Ljava/lang/String;)V");

       // jni調用 java方法,調用到ZygoteInit類的main函數

       jclass startClass = env->FindClass(className);

       env->CallStaticVoidMethod(startClass, startMeth, strArray);
}

 到了ZygoteInit.java中的靜態main函數中,從C++ ——》JAVA

(3)ZygoteInit

真正Zygote進程:

frameworks\base\core\java\com\android\internal\os\ZygoteInit.java

public static void main(String argv[]) {
       //Registers a server socket for zygote command connections
       registerZygoteSocket();

       //Loads and initializes commonly used classes and
       //used resources that can be shared across processes
       preload();

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

       if (argv[1].equals("start-system-server")) {
              startSystemServer();
       }

       /**
       * Runs the zygote process's select loop. Accepts new connections as
       * they happen, and reads commands from connections one spawn-request's
       * worth at a time.
       */

       runSelectLoopMode();    //loop中
       /**
       * Close and clean up zygote sockets. Called on shutdown and on the
       * child's exit path.
       */
       closeServerSocket();
}
Zygote就建立好了,利用Socket通訊,接收請求,Fork應用程序進程,進入Zygote進程服務框架中。

四 SystemServer啟動

(1)在Zygote進程進入循環之前,調用了startSystemServer( );

private static boolean startSystemServer(){
       /* Request to fork the system server process 孵化新的進程 */
    ZygoteConnection.Arguments parsedArgs = null;
       pid = Zygote.forkSystemServer(
              parsedArgs.uid, parsedArgs.gid,
              parsedArgs.gids,
              parsedArgs.debugFlags,
              null,
              parsedArgs.permittedCapabilities,
              parsedArgs.effectiveCapabilities);
 
              /* For child process 對新的子進程設置 */
       if (pid == 0) {
              handleSystemServerProcess(parsedArgs);
       }
}

void handleSystemServerProcess(parsedArgs){
       closeServerSocket();
       //"system_server"
       Process.setArgV0(parsedArgs.niceName);

       //Pass the remaining arguments to SystemServer.
    RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
      parsedArgs.remainingArgs);
       /* should never reach here */
}

(2)RuntimeInit中:

frameworks\base\core\java\com\android\internal\os\RuntimeInit.java

//The main function called when started through the zygote process.
void zygoteInit(int targetSdkVersion, String[] argv){
        applicationInit(targetSdkVersion, argv);
}

void applicationInit(int targetSdkVersion, String[] argv){
    // Remaining arguments are passed to the start class's static main
    invokeStaticMain(args.startClass, args.startArgs);
}

void invokeStaticMain(String className, String[] argv){
    Class> cl;
    cl = Class.forName(className);
 
    //獲取SystemServer的main方法,拋出MethodAndArgsCaller異常
    Method m;
    m = cl.getMethod("main", new Class[] { String[].class });
    int modifiers = m.getModifiers();
    throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}

(3)從startSystemServer開始執行並沒有去調用SystemServer的任何方法,

    只是通過反射獲取了main方法,付給了MethodAndArgsCaller,並拋出了MethodAndArgsCaller異常。

    此異常是在哪裡處理的呢?

回到startSystemServer( )函數的調用處:

在ZygoteInit的main函數中:

public static void main(String argv[]) {
       try {
              ……
              if (argv[1].equals("start-system-server")) {
                  startSystemServer();       //這裡如果拋出異常,跳過下面流程
              }
          
        runSelectLoopMode();    //loop中
              ……


       } catch (MethodAndArgsCaller caller) {
              caller.run();        //處理的異常
       }
}

  如果startSystemServer拋出了異常,跳過執行ZygoteInit進程的循環,這是怎麼回事呢?

  在startSystemServer中異常是由handleSystemServerProcess拋出,而

      pid = Zygote.forkSystemServer( )

      /* For child process 僅對新的子進程設置 */

      if (pid == 0) {

        handleSystemServerProcess(parsedArgs);

      }

      // Zygote.forkSystemServer根據參數fork 出一個子進程,若成功調用,則返回兩次:

    一次返回的是 zygote 進程的 pid ,值大於0;一次返回的是子進程 pid,值等於0否則,出錯返回-1;

  caller.run();

    MethodAndArgsCaller run函數:調用前面所提到的

    //SystemServer main方法

    m = cl.getMethod("main", new Class[] { String[].class });

    啟動了進程SystemServer。

(4)SystemServer的執行 init1( )

//frameworks\base\services\java\com\android\server\SystemServer.java

public static void main(String[] args) {

         System.loadLibrary("android_servers");    

         /*

         * This method is called from Zygote to initialize the system.
         * This will cause the native services (SurfaceFlinger, AudioFlinger, etc..)
         * to be started. After that it will call back
         * up into init2() to start the Android services.
         */
         init1(args);    //native 完了回調init2( )
  }

//init1:
  frameworks/base/services/jni/com_android_server_SystemServer.cpp:: android_server_SystemServer_init1( ) 
  中調用:system_init
extern "C" status_t system_init()
{
       sp proc(ProcessState::self());
       sp sm = defaultServiceManager();

       //啟動SurfaceFlinger 和傳感器
       property_get("system_init.startsurfaceflinger", propBuf, "1");
       SurfaceFlinger::instantiate();

       property_get("system_init.startsensorservice", propBuf, "1");
       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.
       AndroidRuntime* runtime = AndroidRuntime::getRuntime();


       //回調 com.android.server.SystemServer init2 方法      

       JNIEnv* env = runtime->getJNIEnv();

       jclass clazz = env->FindClass("com/android/server/SystemServer");

       jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");

       env->CallStaticVoidMethod(clazz, methodId);
    

       //啟動線程池 做為binder 服務
       ProcessState::self()->startThreadPool();
       IPCThreadState::self()->joinThreadPool();
       return NO_ERROR;

}

ProcessState:

  每個進程在使用binder 機制通信時,均需要維護一個ProcessState 實例來描述當前進程在binder 通信時的binder 狀態。

  ProcessState 有如下2 個主要功能:

  1. 創建一個thread, 該線程負責與內核中的binder 模塊進行通信,稱該線程為Pool thread ;

  2. 為指定的handle 創建一個BpBinder 對象,並管理該進程中所有的BpBinder 對象。

Pool thread:

  在Binder IPC 中,所有進程均會啟動一個thread 來負責與BD 來直接通信,也就是不停的讀寫BD ,

  這個線程的實現主體是一個IPCThreadState 對象,下面會介紹這個類型。

  下面是Pool thread 的啟動方式:

  ProcessState::self()->startThreadPool();

IPCThreadState :

  IPCThreadState 也是以單例模式設計的。由於每個進程只維護了一個ProcessState 實例,同時ProcessState 只啟動一個Pool thread ,

也就是說每一個進程只會啟動一個Pool thread ,因此每個進程則只需要一個IPCThreadState 即可。

Pool thread 的實際內容則為:

IPCThreadState::self()->joinThreadPool();

(5)SystemServer的執行 init2( )

public static final void init2() {   
    //建立線程來處理
       Thread thr = new ServerThread();      
       thr.setName("android.server.ServerThread");
       thr.start();
}

//看看線程ServerThread裡面都做了什麼事情?
public void run() {
    addBootEvent(new String("Android:SysServerInit_START"));
    Looper.prepare();
    android.os.Process.setThreadPriority(
    android.os.Process.THREAD_PRIORITY_FOREGROUND);

    //初始化服務,創建各種服務實例,如:電源、網絡、Wifi、藍牙,USB等,
  //初始化完成以後加入到 ServiceManager中,
    //事我們用 Context.getSystemService (String name) 才獲取到相應的服務
    PowerManagerService power = null;
    NetworkManagementService networkManagement = null;
    WifiP2pService wifiP2p = null;
    WindowManagerService wm = null;
    BluetoothService bluetooth = null;
    UsbService usb = null;
    NotificationManagerService notification = null;
    StatusBarManagerService statusBar = null;
    ……

    power = new PowerManagerService();
    ServiceManager.addService(Context.POWER_SERVICE, power);
    ……

    // ActivityManagerService作為ApplicationFramework最重要的服務
    ActivityManagerService.setSystemProcess();
    ActivityManagerService.installSystemProviders();
    ActivityManagerService.self().setWindowManager(wm);   
  // 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.self().systemReady(new Runnable() {

           public void run() {
                  startSystemUi(contextF);
                  batteryF.systemReady();
                  networkManagementF.systemReady();
                  usbF.systemReady();
                  ……

                  // It is now okay to let the various system services start their
                  // third party code...
                  appWidgetF.systemReady(safeMode);
                  wallpaperF.systemReady();
           }
    });

    //
    //BOOTPROF
    addBootEvent(new String("Android:SysServerInit_END"));
    Looper.loop();
}

到這裡系統ApplicationFramework層的XxxServiceManager准備就緒,可以開始跑上層應用了,我們的第一個上層應用HomeLauncher。

  HomeActivity又是如何啟動的呢?

  Activity的啟動必然和ActivityManagerService有關,我們需要去看看

  ActivityManagerService.systemReady( )中都干了些什麼。

五 Home界面啟動

 public void systemReady(final Runnable goingCallback) {
    ……
    //ready callback
       if (goingCallback != null)
              goingCallback.run();

       synchronized (this) {
              // Start up initial activity.
              // ActivityStack mMainStack;
              mMainStack.resumeTopActivityLocked(null);
       }
……

}

final boolean resumeTopActivityLocked(ActivityRecord prev) {
  // Find the first activity that is not finishing.
  ActivityRecord next = topRunningActivityLocked(null);
  if (next == null) {
    // There are no more activities!  Let's just start up the
    // Launcher...
    if (mMainStack) {
      //ActivityManagerService mService;
      return mService.startHomeActivityLocked();
    }
  }
  ……
}

然後就啟動了Home界面,完成了整個Android啟動流程。

整個過程如下:(摘自網絡) 

\

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved