Android系統升級那些事兒

摘要

        本文首先介紹了Android系統更新要用到的一些概念:硬件、三種模式及相互之間的通信。然後介紹了Android系統的啓動和升級流程。

概述

        通常,Android系統的升級包名稱爲update.zip。Android系統內部自帶了燒寫升級包的工具,我們可以手動燒寫,也可以通過某些機制自動更新系統。同時,我們可以手動修改和製作升級包。本文主要闡述在Android系統升級中用到的一些概念,本文只是作爲索引,並不涉及到具體的燒寫工作。本文基於Android系統的版本:4.0.4。

硬件

        Android系統的燒寫,是非常貼近硬件的。一是,燒寫是在實實在在的硬件上操作的。二則,有時在翻閱源碼的時候,需要知道硬件的類型,以便找到和硬件相對應的源碼。
        燒寫相關的硬件主要有三部分:CPU、內存和nand flash。當然,只是相對本文而言。CPU用來執行程序中的指令。內存只是在運行中,將需要運行的程序加載其中並運行,關機後即消失。nand flash用來存儲程序的數據,它會一直存在。系統啓動時,會將nand flash上的操作系統加載到內存,然後運行在CPU中,對於非系統程序,按需加載到內存中運行。瞭解這些,有助於瞭解整個燒寫的過程。
        在板子上,可以通過下面的命令,查看CPU的信息:
cat /proc/cpuinfo

        通過如下命令查看內存的信息:
cat /proc/meminfo

        nand flash是需要分區的,每個分區中對應了Android系統燒寫包中不同的image,比如:boot、system分區等。可以通過如下命令來查看nand flash的分區情況:
cat /proc/mtd # 查看分區狀況

        通常,nand flash包含了以下分區:
  1. 開機動畫:用於在開機或者升級過程中顯示在屏幕上的內容。
  2. boot:用於Android系統的正常啓動
  3. recovery:用於Android系統進入recovery模式下,參見本文後續介紹。
  4. misc:用於保存BCB的內容,參見本文後續介紹。
  5. system:對應於Android系統的正常模式下的/system目錄。
  6. cache:用於不同模式之間的通信,參見本文後續介紹。
  7. user-data:用於Android應用數據的存放。
        nand flash上的分區可以按需要增減,這取決於不同的Android系統配置。不過它有可能在Android不同的模塊中都有定義。同時,這些分區的可能在Android不同的模塊中都有配置,比如:內核、bootloader。
        通過下面的命令查看nand flash的總大小:
dmesg | grep NAND

三種模式

        燒寫的過程中,需要在三種模式下互相切換。確切的說,應該是三個操作環境:bootloader、recovery和main system。
        bootloader主要用來屏蔽硬件的差異,類似於PC中的BIOS,它的功能相對比較簡單,內部提供了一些命令,比如:可以將nand flash分區加載到內存、運行內存中的程序、操作SD卡等。Android中的booloader是uboot,位於源碼的uboot目錄下。
        main system就是正常運行的Android操作系統,而recovery則是一個mini的Android系統,顧名思義,就是用來進行系統恢複相關的操作的,它的運行規則和main system一樣,只是,它在啓動時只加載recovery服務,此服務用於燒寫Android系統。
        三者之間的關係如下圖所示:

        系統先啓動到bootloader模式下,然後根據情況,啓動到recovery或者main system模式下。

bootloader

        板子啓動時,在Putty控制檯中按回車,可以進入uboot,輸入help可以查看其可用的命令。uboot的命令是可以自定義的,需要在uboot源碼中進行設置。uboot下可以使用fastboot命令,進入fastboot模式下,可以使用PC與之連接(此時,使用fastboot協議通信),進行Android系統的燒寫工作。
        在uboot中,你可以更新uboot在內的所有系統模塊。

recovery

        recovery系統包含了內核和類似於根文件系統兩部分,啓動時仍採用init進程和init.rc配置腳本,不同的是init.rc腳本比較簡單,system目錄中只存放了一些必備的工具。
        recovery系統下,你能更新除uboot之外的所有Android系統模塊。
        recovery模式下,只有一個recovery服務,該服務對應於recovery進程,源碼位置:bootable\recovery。

main system

        main system是正常運行的Android系統。

通信

        Android板子每個時刻只可以處於bootloader、recovery、main system其中的一個模式中,燒寫過程中,三個模式之間需要通信,比如:main system通知recovery燒寫那個升級包。大致有三種方式可以用來通信:BCB、寄存器和cache分區。

BCB

        BCB (bootloader control block)可以用於main system傳遞數據給bootloader和recovery模式。BCB的內容存在於nand flash的一個獨立的分區,可以在nand flash分區表中看到,分區的名稱爲misc。
        通過BCB,main system可以通知bootloader啓動到recovery模式下,同時也可以傳遞命令給recovery,比如燒寫哪個文件。
        recovery在燒寫的過程中,會設置BCB,以確保燒寫成功前,一直會開機啓動到recovery模式下,這樣可以防止燒寫過程中斷電的情況。

寄存器

        main system模式下,運行如下命令會重啓,並進入recovery模式:(也可調用android_reboot函數)
reboot recovery

        reboot命令實際上是系統調用,最終會調用到內核的kernel_restart函數,該函數最終會設置某個寄存器的位置,然後執行重啓操作。
重啓後,bootloader會檢測到該寄存器的值,並根據其值,啓動到recovery模式下。

cache分區

        recovery和main system模式下,都會將nand flash的cache分區掛載到cache目錄從而實現這兩種模式下的通信。比如:main system模式下,下載升級包update.zip,並將其路徑設置到文件/cache/recovery/command中,然後重啓到recovery模式下,recovery進程會讀取到文件/cache/recovery/command中的值,並執行系統升級工作。

升級包

        通常升級包的名稱爲update.zip,它包含了要升級的內容和升級腳本,也就是說,整個升級的過程都由升級包本省控制。
        升級腳本解析對應的源碼:META-INF\com\google\android\updater-script。可用的命令列表可以參見bootable\recovery\updater\install.c的函數RegisterInstallFunctions()。
        解析升級腳本採用語言Edify,源碼位置:bootable\recovery\updater和bootable\recovery\edify。
        若想自己製作update.zip包,需要使用的一下三個文件:
  1. out/host/linux-x86/framework/signapk.jar
  2. build/target/product/security/testkey.pk8
  3. build/target/product/security/testkey.x509.pem
        製作的過程:
  1. 解壓從源碼中編譯出來的update.zip。
  2. 修改解壓後的文件。
  3. 重新壓成包update.zip
  4. 使用命令處理update.zip,該命令主要是最zip執行簽名操作:java -Xmx1024m -jar signapk.jar -w testkey.x509.pem testkey.pk8 update.zip update_unsigned.zip
  5. update_unsigned.zip就是最終的升級包。

啓動流程

        啓動流程大致路下:
        1.開機後,啓動到bootloader下,bootloader會作一些初始化的操作,然後會從三個地方確定後面的動作:
        查找SD卡上指定的文件:此種情況,主要用於,通過SD卡,升級系統。只要在SD卡中按照規則放置升級文件和相關的腳本,即可實現系統的升級。
        查找按鍵的狀態:此種情況主要用於開機後進入bootloader或者recovery模式,按鍵也通常是硬件上的幾個鍵按下的狀態。
        獲取BCB的內容:需要根據BCB的內容,來執行具體的操作,通常是進入recovery模式。
        若沒有發現上述的三種信息,則會按照正常的啓動流程,進入main system模式。
        2.若需要通過SD卡升級,則會顯示升級提示界面,並開始系統升級,完成後,重啓進入main system。
        3.若需要進入recovery模式,在bootloader模式下,會加載recovery分區到內存,然後進入recovery模式下。
        recovery會啓動recovery進程,該進程會讀取/cache/recovery分區中的內容,決定具體的操作。若沒有相關的配置,則進入控制檯模式。
        4.若需要進入main system模式,則會加載boot分區中的內容,然後進入正常的啓動流程。

升級流程

        升級的流程大致如下:
        1.main system模式下,下載update.zip到/cache目錄。
        2.設置/cache/recovery/command目錄的內容爲:--update_package=/cache/update.zip。
        3.調用函數android_reboot,並設置進入recovery模式的代碼。
        4.系統重啓,進入recovery模式,並啓動recovery進程,該進程會檢測/cache/recovery/command的內容,然後升級update.zip。

參考資料

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章