Android系統啟動過程剖析
1. 系統啟動流程簡介
在Linux核心啟動後,init 1(1號程式)將作為第一個使用者空間(Linux虛擬記憶體的大小為232(在32位的x86機器上),核心將這4G位元組的空間分為兩部分。最高的1G位元組供核心使用,稱為“核心空間”。而較低的3G位元組供各個程式使用,稱為“使用者空間”。)的程式來啟動Android系統,該啟動流程可以分為如下5個階段,如下圖:
(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;
(3) 觸發需要執行的action:Action需要在Triggers(觸發條件)中呼叫,本階段對需要執行的Action進行觸發,並根據觸發條件將需要執行的Action放入Action佇列;
(4) 執行在action佇列中的命令:對上一階段觸發的Action以及Service進行執行。並在此過程中,派生了Zygote和Service Manager兩個非常重要的程式;
(5) 迴圈處理事件:init程式進入無限迴圈,處理裝置插入/拔出,服務屬性狀態變化和signal事件等。
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_signal | system/core/init/signal_handler.c | 處理SIGCHLD signal |
相關文章
- Android 系統啟動過程Android
- Android啟動過程剖析-深入淺出Android
- Android系統啟動流程(四)Launcher啟動過程與系統啟動流程Android
- 剖析Linux系統啟動的後臺全過程 (zt)Linux
- Android系統啟動流程(三)解析SyetemServer程式啟動過程AndroidServer
- Android系統原始碼分析--Activity啟動過程Android原始碼
- Android系統原始碼分析--Process啟動過程Android原始碼
- Linux系統啟動過程Linux
- 圖解 Android 系列(一)揭祕 Android 系統啟動過程圖解Android
- Android系統原始碼分析–Zygote和SystemServer啟動過程Android原始碼GoServer
- Android系統原始碼分析--Zygote和SystemServer啟動過程Android原始碼GoServer
- FreeBSD系統啟動過程(轉)
- 作業系統啟動的過程作業系統
- Android系統程式Zygote啟動過程的原始碼分析(3)AndroidGo原始碼
- Android App啟動過程AndroidAPP
- Android Service的啟動過程Android
- Android Activity的啟動過程Android
- Android啟動過程深入解析Android
- 關於雙系統選單,NT系統啟動過程
- 《10分鐘剖析》系統啟動2——啟動zygoteGo
- Android中Activity啟動過程探究Android
- 乾貨 | 走進Node.js之啟動過程剖析Node.js
- 理解 Android 程式啟動之全過程Android
- 【Android】【init】解析init程式啟動過程Android
- Android應用程式程式啟動過程Android
- 【Android原始碼】Service的啟動過程Android原始碼
- 淺析Android Activity的啟動過程Android
- Android效能優化之啟動過程(冷啟動和熱啟動)Android優化
- Android啟動過程-萬字長文(Android14)Android
- Android 系統啟動流程Android
- 【android 7.1.2】系統啟動Android
- Android輸入系統(二)IMS的啟動過程和輸入事件的處理Android事件
- 【作業系統2】作業系統啟動過程與異常/中斷,系統呼叫作業系統
- Windows 啟動過程Windows
- Android 核心分析 之八------Android 啟動過程詳解Android
- App 啟動過程(含 Activity 啟動過程) | 安卓 offer 收割基APP安卓
- Android系統啟動自動開啟mtklogAndroid
- Android 啟動過程簡析(一)之 init 程式Android