介紹Android系統架構的介紹——《Android系統啓動過程剖析》。android
1. 系統啓動流程簡介數據結構
在Linux內核啓動後,init 1(1號進程)將做爲第一個用戶空間(Linux虛擬內存的大小爲232(在32位的x86機器上),內核將這4G字節的空間分爲兩部分。最高的1G字節供內核使用,稱爲「內核空間」。而較低的3G字節供各個進程使用,稱爲「用戶空間」。)的進程來啓動Android系統,該啓動流程能夠分爲以下5個階段,以下圖:架構
Android啓動流程能夠分爲以下5個階段socket
(1) 啓動準備:該階段包括建立文件系統的基本目錄、打開基本輸入、輸出設備,初始化日誌功能等;函數
(2) 解析init.rc文件:該階段對init.rc腳本文件進行解析,主要對Service(服務)和Action(動做)進行解析。其中,Service由命令(Command)和一系列服務的附加內容(Option,選項)組成,如:「service vold /system/bin/vold」爲一個Service,而「socket vold stream 0660 root mount「則爲配合該服務使用的Option;Action則由一系列的命令組成,如:「on init mkdir /system」爲系統初始化時創建系統文件夾的Action;oop
(3) 觸發須要執行的action:Action須要在Triggers(觸發條件)中調用,本階段對須要執行的Action進行觸發,並根據觸發條件將須要執行的Action放入Action隊列;源碼分析
(4) 執行在action隊列中的命令:對上一階段觸發的Action以及Service進行執行。並在此過程當中,派生了Zygote和Service Manager兩個很是重要的進程;ui
(5) 循環處理事件:init進程進入無限循環,處理設備插入/拔出,服務屬性狀態變化和signal事件等。spa
2. 源碼分析結果日誌
對android-2.3.3_r1版本中的以下源碼文件進行分析:
(1) init.c:路徑爲system/core/init/init.c
(2) init_parser.c:路徑爲system/core/init/ init_parser.c
(3) builtins.c:路徑爲system/core/init/ builtins.c
(4) property_service.c:路徑爲system/core/init/property_service.c
(5) keycords.c:路徑爲system/core/init/keycords.c
(6) signal_handler.c:路徑爲system/core/init/signal_handler.c
總結得出系統啓動流程對應的源代碼文件及函數以下(注:如下函數間的順序執行關係使用「>」表示;函數間的調用執行關係使用「à」表示)
2.1 第一階段(啓動準備)
具體的函數執行過程以下:
mkdir > mount > open_devnull_stdio > log_init
2.2 第二階段(解析init.rc文件)
具體的函數調用過程以下:
init_parse_config_fileàparse_configà parse_new_sectionàparse_service (或者parse_action)-> parse_line_service(或者parce_line_action)
2.3 第三階段(觸發須要執行的action)
具體的調用過程以下:
action_for_each_trigger("boot", action_add_queue_tail);à action_add_queue_tail ( class_start default) à action_remove_queue_head à do_class_start
2.4 第四階段(執行在action隊列中的命令)
具體的調用過程以下:
execute_one_commandà action_remove_queue_head àdo_class_start àservice_for_each_classà service_start_if_not_disabledà service_start
2.5 第五階段(循環處理)
具體的循環處理過程以下:
for (; ;) {
poll > handle_property_set_fd > handle_keychord > handle_signal
}
2.6 主要函數介紹
函數名 所在文件 功能概述
main system/core/init/init.c 1號進程init的入口函數。主要分析init.rc配置文件,執行基本的action和啓動必備的native service,而後進入一個infinite loop 處理來自property, signal的event
mkdir system/core/init/init.c 創建文件系統的基本目錄
mount system/core/init/init.c 裝載文件系統
open_devnull_stdio system/core/init/init.c 打開基本輸入、輸出設備
log_init system/core/init/init.c 初始化日誌功能
init_parse_config_file system/core/init/ init_parser.c 讀取init.rc文件內容到內存數據區
parse_config system/core/init/ init_parser.c 識別init.rc文件中的 Section(service and action series )和Text
parse_new_section system/core/init/ init_parser.c 識別section類別
parse_service system/core/init/ init_parser.c 對service section第一行進行分析
parse_line_service system/core/init/ init_parser.c 對service section的option選項進行分析
parse_action system/core/init/ init_parser.c 對action section第一行進行分析
parse_line_action system/core/init/ init_parser.c 對action section的每一行獨立的命令進行分析
action_for_each_trigger system/core/init/ init_parser.c 觸發某個action的執行
action_add_queue_tail system/core/init/ init_parser.c 將某個action的從action_list加到action_queue
execute_one_command system/core/init/init.c 執行當前action的一個command
action_remove_queue_head system/core/init/ init_parser.c 從action_queue鏈表上移除頭結點(action)
do_class_start system/core/init/ builtins.c class_start default對應的入口函數,主要用於啓動native service
service_for_each_class system/core/init/ init_parser.c 遍歷service_list鏈表上的全部結點
service_start_if_not_disabled system/core/init/ builtins.c 判斷service的flag是否disabled,若是不是,則調用相關函數,準備啓動service
service_start system/core/init/init.c 啓動service的主要入口函數,設置service數據結構的相關數據結構後,調用fork建立一個新的進行,而後調用execve執行新的service
fork Lib function(ulibc) 進程建立函數
execve Lib function(ulibc) 調用執行新的service
poll Lib function(ulibc) 查詢property_set_fd,signal_fd和keychord_fd文件句柄是否有服務請求
handle_property_set_fd system/core/init/property_service.c 處理系統屬性服務請求,如:service, wlan和dhcp等等
handle_keychord system/core/init/keycords.c 處理註冊在service structure上的keychord,一般是啓動service
handle_signalsystem/core/init/signal_handler.c處理SIGCHLD signal