Android啓動init.c

首先是   init 進程啓動 (一些 native 服務啓動)           

           如:  servicemanager 啓動

                     Zygote 啓動

                        SysytemServer 啓動,在

                            init1

                            init2 函數中啓動 Android 服務

 

init 進程起來 後,解析 init.rc init.xxx.rc 建立基本的服務, 之後進入循環,並沒有退出。

 


分析 init.c@/system/core/init main 函數主要實現過程

        ...

            mkdir("/dev", 0755)    // 創建具有可讀寫的目錄   /dev

       。。。

       log_init();       // 初始化 log 系統

        。。。      

      parse_config_file("/init.rc");     /* 解析 init.rc 文件, parse_config_file 這個 函數是 /system/core/init/parse.c 這個類中實現的,講解析得到的 service 信息儲存到 service_list 這個數據解構中 */

    

      get_hardware_name();

      snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);

      parse_config_file(tmp);     /* 解析 init.xxx.rc ,和硬件相關 */

 

       action_for_each_trigger("early-init", action_add_queue_tail);

      drain_action_queue();       /* 執行解 析得到的” early-init ”的 action*/

   

      INFO("device init/n");

      device_fd = device_init(); /* 設備的初始化。掛載結點倒 /dev 下還有下載 firmwares*/

 

      property_init();          

      。。。                      /*property 初始化 */

 

        /* 讀取 /initlogo.rle (一張位圖),如果成功則在 /dev/graphics/fb0  顯示 Logo, 如果失敗則將 /dev/tty0, 設爲 TEXT 模式並打開 /dev/tty0, 輸出文本 ANDROID 。具體實現可看

     /system/core/init/log.c

     */

     if( load_565rle_image(INIT_IMAGE_FILE) ) {  

     fd = open("/dev/tty0", O_WRONLY);

     if (fd >= 0) {

        。。。

        。。。

         }

      /*  判斷 cmdline  中的參數,並設置屬性系統中的參數 :

     *   1   如果  bootmode

     *      - factory, 設置 ro.factorytest 值爲 1

     *      - factory2, 設置 ro.factorytest 值爲 2

     *      其他的設 ro.factorytest 值為 0

     *   2 、如果有 serialno 參數,則設置 ro.serialno ,否則爲 ""

     *   3 、如果有 bootmod 參數,則設置 ro.bootmod ,否則爲 "unknown"

     *   4 、如果有 baseband 參數,則設置 ro.baseband ,否則爲 "unknown"

     *   5 、如果有 carrier 參數,則設置 ro.carrier ,否則爲 "unknown"

     *   6 、如果有 bootloader 參數,則設置 ro.bootloader ,否則爲 "unknown"

     *   7 、通過全局變量(前面從 /proc/cpuinfo 中提取的)設置 ro.hardware ro.version

     */

     if (qemu[0])

         import_kernel_cmdline(1);

 

     if (!strcmp(bootmode,"factory"))

         property_set("ro.factorytest", "1");

     else if (!strcmp(bootmode,"factory2"))

         property_set("ro.factorytest", "2");

     else

         property_set("ro.factorytest", "0");

 

     property_set("ro.serialno", serialno[0] ? serialno : "");

     property_set("ro.bootmode", bootmode[0] ? bootmode : "unknown");

     property_set("ro.baseband", baseband[0] ? baseband : "unknown");

     property_set("ro.carrier", carrier[0] ? carrier : "unknown");

     property_set("ro.bootloader", bootloader[0] ? bootloader : "unknown");

 

     property_set("ro.hardware", hardware);

     snprintf(tmp, PROP_VALUE_MAX, "%d", revision);

     property_set("ro.revision", tmp);

 

      action_for_each_trigger("init", action_add_queue_tail);

      drain_action_queue();      /* 執行解析 得到的 init action */

 

      property_set_fd = start_property_service();   // 啓動  property service

       。。。

      。。。                   

         /*  sigchld handler 創建信號機制 */

   

    if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0) {

         signal_fd = s[0];

         signal_recv_fd = s[1];

         fcntl(s[0], F_SETFD, FD_CLOEXEC);

         fcntl(s[0], F_SETFL, O_NONBLOCK);

         fcntl(s[1], F_SETFD, FD_CLOEXEC);

         fcntl(s[1], F_SETFL, O_NONBLOCK);

     }

 

     /*  確認所有初始化工作完成

      * device_fd(device init  完成 )

      * property_set_fd(property server start  完成 )

      * signal_recv_fd ( 信號機制建立 )

      */

     if ((device_fd < 0) ||

         (property_set_fd < 0) ||

         (signal_recv_fd < 0)) {

         ERROR("init startup failure/n");

         return 1;

     }

 

     action_for_each_trigger("early-boot", action_add_queue_tail);

     action_for_each_trigger("boot", action_add_queue_tail);

     drain_action_queue();              // 執行解析的 "early-boot" "boot"action

 

     queue_all_property_triggers();

     drain_action_queue();       // 執行解 析的 property action

 

     for(;;){

     。。。              

/*

    進入無限循環

    等待一些 device/property set/process eixt  這些 event

    比如 SD 插入時,會收到 device add event ,然後它可以爲這個設  

    備添加節點。處理一些 process exit event ,執行在 *.rc 中定義的

    命令(在 onrestart )的時候                                     

*/

     。。。

     }

從上可以看出 init 依次執行五種觸發器( Triggers

early-init

init

early-boot

boot

property:*

 

分析 init.rc 文件 @/system/core/rootdir/init.rc

 

  1 . 關於 init.rc

 

Android 中使用啓動腳本 init.rc, 可以在系統的初始化過程中進行一些簡單的初始化操作。這個腳本被直接安裝到目標系統的根文件系統中, 被 init 可執行程序解析。  init.rc 是在 init 啓動後被執行的啓動腳本,其餘發主要包含了以下內容:

 

     * Commands :命令

     * Actions :動作

     * Triggers: 觸發條件

     * Services :服務

     * Options :選項

     * Propertise :屬性

 

Commands 是 一些基本的操作,例如:

 

     mkdir /sdcard 0000 system system

     mkdir /system

     mkdir /data 0771 system system

     mkdir /cache 0770 system cache

     mkdir /config 0500 root root

     mkdir /sqlite_stmt_journals 01777 root root

     mount tmpfs tmpfs /sqlite_stmt_journals size=4m

 

這些命令在 init 可執行程序中被解析,然後調用相關的函數來實現。  Actions( 動作 ) 表示一系列的命令,通常在 Triggers (觸發條件)中調用,動作和觸發條件例如:

 

     on init

     export PATH /sbin:/system/sbin:/system/bin:/system/xbin

 

init  表示一個 觸發條件,這個觸發事件發生後,進行設置環境變量和建立目錄的操作稱爲一個“動作” Services (服務)通常表示啓動一個可執行程序, Options (選項)是服務的附加內容,用於配合服務使用。

 

service vold /system/bin/vold

     socket vold stream 0660 root mount

 

service bootsound /system/bin/playmp3

     user media

     group audio

     oneshot

 

vold  bootsound 分別是兩個服務的名稱, /system/bin/vold /system/bin/playmp3 分別是他們所對應的可執行程序。  socket user group oneshot 就是配合服務使用的選項。  Properties (屬性)是系統中使用的一些值,可以進行設置和讀取。

 

     setprop ro.FOREGROUND_APP_MEM 1536

     setprop ro.VISIBLE_APP_MEM 2048

     start adbd

 

setprop  用 於設置屬性, on property 可以用於判斷屬 性,這裏的屬性在整個 Android 系統運行中都是一致的

 

init.rc 啓動 的服務

1.console             

2.adbd           adb deamon   

                     可以通過 property_set persist.service.adb.enable  來 控制其執行

                          

3.servicemanager       啓動 binder system.IPC 機制   通信相關的吧。。。

4.vold

5.nexus

6.mountd

7.debuggerd

8.ril-daemon

9.zygote

10.media

11.bootsound

12.bootanim

13.dbus

14.bluetoothd

15.hfag

16.hsag

17.opush

18.pbap

19.installd

20.flash_recovery

21.racoon

22.mtpd

23.keystore

24.dumpstate

      

Zygote 服務的 啓動:

        service zygote /system/bin/app_process -Xzygote /system/bin --zygote –start-system-server

        app_main.cpp@/framework/base/cmds/app_process/ main 函數中

 

      

          // Next arg is startup classname or "--zygote"

     if (i < argc) {

         arg = argv[i++];

         if (0 == strcmp("--zygote", arg)) {

             bool startSystemServer = (i < argc) ?

                     strcmp(argv[i], "--start-system-server") == 0 : false;

             setArgv0(argv0, "zygote");

             set_process_name("zygote");

             runtime.start("com.android.internal.os.ZygoteInit", startSystemServer);

         } else {

             set_process_name(argv0);

             runtime.mClassName = arg;

             // Remainder of args get passed to startup class main()

             runtime.mArgC = argc-i;

             runtime.mArgV = argv+i;

 

             LOGV("App process is starting with pid=%d, class=%s./n",

                  getpid(), runtime.getClassName());

             runtime.start();

         }

     } else {

         LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");

         fprintf(stderr, "Error: no class name or --zygote supplied./n");

         app_usage();

         return 10;

     }

 

  創建 AppRuntime 對象  runtime ,執行 runtime.start("com.android.internal.os.ZygoteInit",  

                 startSystemServer) 的方法,實現在 AndroidRuntime.cpp 中。

void AndroidRuntime::start(const char* className, const bool startSystemServe

{

        。。。

     /* start the virtual machine */

     if (startVm(&mJavaVM, &env) != 0)

         goto bail;

 

     /*

      * Register android functions.

      */

     if (startReg(env) < 0) {

         LOGE("Unable to register all android natives/n");

         goto bail;

     }

        。。。

}

創建虛擬機器,註冊 android jni 方法,然後就是定位 className 的類

  slashClassName = strdup(className);

     for (cp = slashClassName; *cp != '/0'; cp++)

         if (*cp == '.')

             *cp = '/';

 

     startClass = env->FindClass(slashClassName);

執行該類的 main 方法

  startMeth = env->GetStaticMethodID(startClass, "main",

             "([Ljava/lang/String;)V");

         if (startMeth == NULL) {

             LOGE("JavaVM unable to find main() in '%s'/n", className);

             /* keep going */

         } else {

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

 

 ZygoteInit main 方法中

               SamplingProfilerIntegration.start();               // Start profiling the zygote                                                                                                      initialization.

               RegisterZygoteSocket();                             // 註冊 Zygote 端口

               //load preload classes  路徑 /frameworks/base/preloaded-classes

         preloadClasses();                                                         

               //load preload resource  系統常用的資源                 

         preloadResources();

/*

               startSystemServer() 中調用  Zygote.forkSystemServer 這個 nitive 方法,具體實現在 dalvik/vm/native/dalvik_system_Zygote.c

*/

               if (argv[1].equals("true")) {

                 startSystemServer();

             }

/*

        之後進入  runSelectLoopMode

*/

          if (ZYGOTE_FORK_MODE) {

                 runForkMode();

             } else {

                 runSelectLoopMode()

 

startSystemServer 後, Zygote forkSystemServer 之後,建立了 SystemServer 進程,執行其 main 函數,

        //load android_servers.so

        System.loadLibrary("android_servers");

      

/* 執行 init1 native  方法。實現在 /frameworks/base/cmds/system_server/library/system_init.cpp

        1. 如果是運行在模擬器上則 instantiate AudioFlinger MediaPlayerService CameraService AudioPolicyService

        2. 調用 runtime->callStatic("com/android/server/SystemServer", "init2") SystemServer 中的 init2 方法,

        3. 如果不是運行在模擬器上,則執行

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

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

      

*/   

systemServer   init2 中會創 建一個線程來啓動所有的 Android 服務

1.Entropy Service

2.Power Manager

3.Activity Manager

4.Telephony Registry

5.Package Manager

6.Account Manager

7.Content Manager

8.System Content Providers

9.Battery Service

10.Hardware Service

11.Alarm Manager

12.Sensor Service

13.Window Manager

14.Bluetooth Service

15.Status Bar

16.Clipboard Service

17.Input Method Service

18.NetStat Service

19.Connectivity Service

20.Accessibility Manager

21.Notification Manager

22.Mount Service

23.Device Storage Monitor

24.Location Manager

25.Search Service

26.Checkin Service

27.Wallpaper Service

28.Audio Service

29.Headset Observer

30.Dock Observer

31.Backup Service

32.AppWidget Service

 

 

最後會調用 ActivityManagerService  systemReady 方法,

依次執行

        resumeTopActivityLocked

    startHomeActivityLocked intent.addCategory(Intent.CATEGORY_HOME)

        startActivityLocked

最終啓動完成進入 Home 畫面

發佈了1 篇原創文章 · 獲贊 0 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章