Android 核心分析 之八------Android 啟動過程詳解

poclist發表於2016-09-17

Android 啟動過程詳解

AndroidLinux系統啟動有4個步驟;

(1) init程式啟動

(2) Native服務啟動

(3) SystemServerAndroid服務啟動

(4) Home啟動

 

總體啟動框架圖如:

image

 

第一步:initial程式(system/core/init)

 

    init程式,它是一個由核心啟動的使用者級程式。核心自行啟動(已經被載入記憶體,開始執行,並已初始化所有的裝置驅動程式和資料結構等)之後,就通過啟動一個使用者級程式init的方式,完成引導程式。init始終是第一個程式.

Init.rc

Init.marvell.rc


Init程式一起來就根據init.rcinit.xxx.rc指令碼檔案建立了幾個基本的服務:

  •  servicemanamger
  •  zygote

。。。

最後Init並不退出,而是擔當起propertyservice的功能。

 

1.1指令碼檔案

init@System/Core/Init

Init.c: parse_config_file(Init.rc)

   @parse_config_file(Init.marvel.rc)

解析指令碼檔案:Init.rcInit.xxxx.rc(硬體平臺相關)

 

Init.rcAndroid自己規定的初始化指令碼(Android Init Language,System/Core/Init/readme.txt)

該指令碼包含四個型別的宣告:

  • Actions
  • Commands
  • Services
  • Options.

1.2服務啟動機制

 

我們來看看Init是這樣解析.rc檔案開啟服務的。

1)開啟.rc檔案,解析檔案內容@system/core/init/init.c

service資訊放置到service_list中。@system/core/init parser.c

2restart_service()@system/core/init/init.c

service_start

execve().建立service程式。

 

第二步 Zygote

Servicemanagerzygote程式就奠定了Android的基礎。Zygote這個程式起來才會建立起真正的Android執行空間,初始化建立的Service都是Navtiveservice..rc指令碼檔案中zygote的描述:

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

所以Zygotemain()@frameworks/base/cmds/app_main.cpp開始。

(1) main()@frameworks/base/cmds/app_main.cpp

  • 建立JavaRuntime
  • runtime.start("com.android.internal.os.ZygoteInit", startSystemServer);

 

(2) runtime.start@AndroidRuntime.cpp

  • 建立虛擬機器
  • 執行:com.android.internal.os.ZygoteInitmain函式。

 

(3)main()@com.android.internal.os.ZygoteInit//正真的Zygote

  • registerZygoteSocket();//登記Listen
  • startSystemServer();
  • 進入Zygote服務框架。

經過這幾個步驟,Zygote就建立好了,利用Socket通訊,接收ActivityManangerService的請求,Fork應用程式。

 

 

第三步 SystemServer

 

startSystemServer@com.android.internal.os.ZygoteInitZygotefork了一個程式: com.android.server.SystemServer.於是SystemServer@(SystemServer.java就建立了。Android的所有服務迴圈框架都是建立SystemServer@(SystemServer.java)上。在SystemServer.java中看不到迴圈結構,只是可以看到建立了init2的實現函式,建立了一大堆服務,並AddService到serviceManager。

main() @ com/android/server/SystemServer

{

init1();

}

Init1()是在Native空間實現的(com_andoird_server_systemServer.cpp)。我們一看這個函式就知道了,init1->system_init()@System_init.cpp

 

system_init()我們看到了迴圈閉合管理框架。

{

Call "com/android/server/SystemServer","init2"

…..

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

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

}


init2()@SystemServer.java中建立了Android中所有要用到的服務。

這個init2()建立了一個執行緒,來NewServiceAddService來建立服務


 

第三步 Home啟動

ServerThread@SystemServer.java後半段,我們可以看到系統在啟動完所有的Android服務後,做了這樣一些動作:

(1) 使用xxx.systemReady()通知各個服務,系統已經就緒。

(2)  特別對於ActivityManagerService.systemReady(回撥)

Widget.wallpaper,imm(輸入法)ready通知。

 

Home就是在ActivityManagerService.systemReady()通知的過程中建立的。下面是ActivityManagerService.systemReady()的虛擬碼:

systemReady()@ActivityManagerService.java

resumeTopActivityLocked()

startHomeActivityLocked();//如果是第一個則啟動HomeActivity

startActivityLocked(。。。)CATEGORY_HOME

 

 

Android的開機流程 
  
1.    系統引導bootloader 
1)        原始碼:bootable/bootloader/* 
2)        說明:加電後,CPU將先執行bootloader程式,此處有三種選擇 
a)        開機按Camera+Power啟動到fastboot,即命令或SD卡燒寫模式,不載入核心及檔案系統,此處可以進行工廠模式的燒寫 
b)        開機按Home+Power啟動到recovery模式,載入recovery.img,recovery.img包含核心,基本的檔案系統,用於工程模式的燒寫 
c)        開機按Power,正常啟動系統,載入boot.img,boot.img包含核心,基本檔案系統,用於正常啟動手機(以下只分析正常啟動的情況) 2.    核心kernel 
1)        原始碼:kernel/* 
2)        說明:kernel由bootloader載入 3.    檔案系統及應用init 
1)        原始碼:system/core/init/* 
2)        配置檔案:system/rootdir/init.rc, 
3)        說明:init是一個由核心啟動的使用者級程式,它按照init.rc中的設定執行:啟動服務(這裡的服務指linux底層服務,如adbd提供adb支援,vold提供SD卡掛載等),執行命令和按其中的配置語句執行相應功能 4.    重要的後臺程式zygote 
1)        原始碼:frameworks/base/cmds/app_main.cpp等 
2)        說明:zygote是一個在init.rc中被指定啟動的服務,該服務對應的命令是/system/bin/app_process 
a)        建立Java Runtime,建立虛擬機器 
b)        建立Socket接收ActivityManangerService的請求,用於Fork應用程式 c)        啟動System Server 
5.    系統服務system server 
1)        原始碼:frameworks/base/services/java/com/android/server/SystemServer.java 
2)        說明:被zygote啟動,通過System Manager管理android的服務(這裡的服務指frameworks/base/services下的服務,如衛星定位服務,剪下板服務等) 6.    桌面launcher 
1)        原始碼:ActivityManagerService.java為入口,packages/apps/launcher*實現 
2)        說明:系統啟動成功後SystemServer使用xxx.systemReady()通知各個服務,系統已經就緒,桌面程式Home就是在ActivityManagerService.systemReady()通知的過程中建立的,最終呼叫 ()啟launcher 7.    解鎖 
1)        原始碼: 
frameworks/policies/base/phone/com/android/internal/policy/impl/*lock* 
2)        說明:系統啟動成功後SystemServer呼叫wm.systemReady()通知WindowManagerService,進而呼叫PhoneWindowManager,最終通過LockPatternKeyguardView顯示解鎖介面,跟蹤程式碼可以看到解鎖介面並不是一個Activity,這是隻是向特定層上繪圖,其程式碼了存放在特殊的位置 8.    開機自啟動的第三方應用程式

相關文章