Jollen 的 Android Booting 解析
时间:2010-10-19 来源:landuochong
Android 開機流程,是一個很值得詳細討論的主題;近期,也正在進行相關的技術工作,因此簡單整理一些相關資料,和大家分享。了解「整體開機流程」,是最重要的第一 門課。我們將開機劃分為三大階段:
1. OS-Level,由 Bootloader 載入 Linux kernel 後,開始進行 kernel 本身的初始化,並載入 built-in 的驅動程式。Kernel 完成開機後,載入 init process,切換至 user-space 後,結束 kernel 的循序過程(sequence),進入排程模式(process scheduling)。
2. Android-Level,由 init process 開始,讀取 init.rc 並啟動重要的外部程式,例如:servicemanager、Zygote 以及 SystemServer。
3. Zygote-Mode,Zygote 啟動完 SystemServer 後,進入 Zygote Mode,在 Socket 等候命令。隨後,使用者將看到一個桌面環境(Home Screen)。桌面環境由一個名為 [Launcher] 的應用程式負責提供。
整體開機流程如圖一所示。
圖一:Android 整體開機流程圖
初探 Android 開機技術的朋友,建議可以先行閱讀 init.rc 檔案,並了解 Android 的 init.rc 語法。Android init language 可參考 [PDK] 的說明。
延伸閱讀
2010.04.24:
Jollen 的 Android 系統管理雜記, #3: init.rc 與 setprop
針對「開機過程」的評估,可以採取個別擊破的方式;針對三個不同的開機階段,分別進 行開機過程的評估。評估開機過程的典型做法,當然是測量「開機時間」。
確認訴求
費勁進行開機時間的評估,最首要的目的當然是「快速開機」,想辦法讓開機速度加快。策略上,因為手機是一種重視使用者經驗的產品,所以「儘早顯示桌 面環境」就是一個好想法。採用「一大堆」非同步的做法,可以達到很不錯的效果。簡單來說,儘速顯示桌面環境的目的,就是造成開機很快的「假象」。
因此,快速開機在智慧型手機產品端,也可以歸類到 User Experience 主題。
確認方向
OS-Level 的部份,包含 Linux kernel 本身的開機時間測量,在此先行略過。針對 Android-Level 的開機時間測量,可以採用廣受歡迎的工具 [Bootchart] 來製作;對使用者來說,進入 Zygote Mode 時,已經是處於桌面環境下了,因此理論上也能先略過這個階段。
關鍵部位 (Critical Parts)
圖一:由 Android-Level 切入、尋找議題
如圖一。綜合上述,對 Android-Level 的開機過程進行評估,就是我們的首部曲,也是第一個研究方向。傳統的評估方式,是測量其開機時間;接下來,將會以知名的 Bootchart 來進行這項工作。
前一則日記提到的 Bootchart 是典型的開機量測工具,主要能進行開機過程以及開機時間的量測。由於 Bootchart 的原理是取代 init process 或是內建在 init process 裡,所以只能取得 initial script 的開機過程報告。不過,這已經很有幫助了。
關於 Android Bootchart
以下是一份使用 Bootchart 所製作的 Android 開機流程圖。過去有一些以 C 重寫 Bootchart 的專案,而 Android 也有一份 C re-implementation,放置於 [system/core/init/bootchart.c]。由此可知,Android init 已經內建一份 C re-implement 的 Bootchart。
圖一:使用 Bootchart 製作的 Android 開機流程圖
以下說明如何製作 Android Bootchart。
1. 編譯 Android Bootchart
Android 的 init process 雖然已內建 Bootchart,但編譯系統預設並不會將 Bootchart 編譯至 init 裡。因此,需要重新編譯 init.c 才能加入 Bootchart:
jollen@android:~/try/mokoid_elcair-20100511$ touch system/core/init/init.c
jollen@android:~/try/mokoid_elcair-20100511$ . build/envsetup.sh
including vendor/aosp/vendorsetup.sh
jollen@android:~/try/mokoid_elcair-20100511$ m INIT_BOOTCHART=true PRODUCT-dma6410xp-eng -j 8
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=2.1-update1
TARGET_PRODUCT=dma6410xp
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=
TARGET_BUILD_TYPE=release
TARGET_ARCH=arm
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=ECLAIR
============================================
完成後,使用 Android 模擬器開啟製作好的 image file。
2. 設定 Bootchart Timeout 時間
要讓 Bootchart 在「下一次開機」時開始運作,以進行取樣並紀錄開機過程,需要指定 Timeout 時間:
$ adb shell 'echo 120 > /data/bootchart-start'
$ adb shell 'mkdir /data/bootchart'
重新啟動模擬器。對 /data 目錄進行的變動,「可以」寫回 userdata.img 裡。這裡指定 Timeout 時間為 '120' 秒;實際測試時,可以視情況自由調整。
3. 取得 Bootchart 紀錄檔
在 Android 系統裡的 /data/bootchart 取得開機紀錄檔:
linux@android:~/android/mokoid$ adb shell
# ls -l /data/bootchart
-rw-rw-rw- root root 389 2010-07-28 11:06 header
-rw-r--r-- root root 0 2010-07-28 11:06 kernel_pacct
-rwxr-xr-x root root 589824 2010-07-28 11:08 proc_diskstats.log
-rwxr-xr-x root root 2293760 2010-07-28 11:08 proc_ps.log
-rwxr-xr-x root root 196608 2010-07-28 11:07 proc_stat.log
#
接下來,必須取出這幾個檔案,並製作成漂亮的統計圖檔。貼心的 Android 已經幫我們準備好一個 script 檔了,因此,先切換到 system/core/init 目錄下,直接執行 grab-bootchart.sh:
linux@android:~/android/mokoid$ cd system/core/init/
linux@android:~/android/mokoid/system/core/init$ ./grab-bootchart.sh
7 KB/s (389 bytes in 0.048s)
1439 KB/s (405771 bytes in 0.275s)
2014 KB/s (3861856 bytes in 1.872s)
1936 KB/s (979391 bytes in 0.493s)
look at bootchart.tgz
最後的統計報告存放於 /tmp/android-bootchart/bootchart.tgz。
4. 製作精美 Bootchart 報告
Bootchart 包含一個以 Java 寫成的圖表製作工具,因此,還是必須取得原始的 Bootchart 套件。在 Ubuntu 環境下,可以用 apt 直接安裝:
$ sudo apt-get install bootchart
接著,將 bootchart.tgz 製作成圖檔:
$ java -jar /usr/share/bootchart/bootchart.jar /tmp/android-bootchart/bootchart.tgz
Parsing /tmp/android-bootchart/bootchart.tgz
Wrote image: ./bootchart.png
最後,得到如圖一的精美報告。接下來的工作,就是對 Bootchart 的內容進行分析。
延伸閱讀
2010.07.28: Jollen 的 Android Booting 解析, #1: 整體開機流程
2010.07.29: Jollen 的 Android Booting 解析, #2: 關於開機的評估
分享您的 Android Bootchart 筆記:Build Android Bootchart