Android 的Recovery機制
文件夾
3.1 主系統和Recovery通過/cache下的文件通信 3
3.2 Bootloader與Recovery通過BCB(Bootloader Control Block)通信 4
1. 系統的啟動模式
1.1 Android系統的啟動模式
一般的Android系統具有下面幾種啟動模式(適用於Android系統的手機),它們的進入方式和描寫敘述例如以下所述:
1.一般啟動模式(normal mode)
進入方法:按電源鍵啟動
描寫敘述:這是正常啟動手機的方法
2.安全模式(safe mode)
進入方法:按住menu鍵,按電源鍵啟動手機。直至手機啟動完畢松開menu鍵
描寫敘述:和正常啟動一樣,但沒有登記Google,所以不能訪問Market或使用你的Google賬號
3.引導模式(bootloader mode)
進入方法:按住照相鍵,按電源鍵啟動手機
描寫敘述:能夠從SD卡上安裝新的系統映像(DREAIMG.NBH),僅僅需再按一次電源鍵。為獲取root權限,對手機進行降級,就是使用這個模式。
4.恢復模式(recovery mode)
進入方法:按住HOME鍵,按電源鍵啟動手機
描寫敘述:能夠打開命令解釋程序(shell),刷新映像文件(flash image),運行備份等。當然這一切取決於你手機上的recovery image版本號。
5.診斷模式(diagnostic mode)
進入方法:按住軌跡球,按電源鍵啟動手機
描寫敘述:用於測試(按音量鍵選擇項目)
6.fastboot模式
進入方法:按住返回鍵。按電源鍵啟動手機,直至屏幕出現FASTBOOT字樣后松開返回鍵
Android系統不同的啟動模式的進入是在不同的情形下觸發的,我們從SD卡中升級我們的update.zip時會進入Recovery模式是當中一種,其它的比方:系統崩潰,或則在命令行輸入啟動命令式也會進入Recovery或其它的啟動模式。
1.2 系統的啟動模式
由下圖可知Android系統啟動后可能進入的模式有下面幾種:
1. MAGIC KEY(組合鍵):組合鍵:若用戶在啟動剛開始按了指定的recovery組合鍵,系統會直接進入Recovery模式。
2. Recovery模式:進入系統“設置”->“系統”,有
a) 網絡升級
b) 本地升級
c) 系統還原
三種方式進入Recovery模式,完畢對應的工作。
3. 正常模式:
若啟動過程中用戶沒有按下不論什么組合鍵。bootloader會讀取位於MISC分區的啟動控制信息塊BCB(Bootloader Control Block)。它是一個結構體。存放着啟動命令command。
依據不同的命令。系統又能夠進入三種不同的啟動模式:MainSystem、Recovery、Bootloader。
2. Recovery模式中的三個部分
Recovery的工作須要整個軟件平台的配合,從通信架構上來看。主要有三個部分。
l MainSystem:即上面提到的正常啟動模式(BCB中無命令),是用boot.img啟動的系統,Android的正常工作模式。更新時。在這樣的模式中我們的上層操作就是使用OTA或則從SD卡中升級update.zip包。
在重新啟動進入Recovery模式之前,會向BCB中寫入命令,以便在重新啟動后告訴bootloader進入Recovery模式。
l Recovery:系統進入Recovery模式后會裝載Recovery分區。該分區包括recovery.img(同boot.img同樣。包括了標准的內核和根文件系統)。進入該模式后主要是執行Recovery服務(/sbin/recovery)來做對應的操作(重新啟動、升級update.zip、擦除cache分區等)。
l Bootloader:除了正常的載入啟動系統之外。還會通過讀取MISC分區(BCB)獲得來至Main system和Recovery的消息。
3. Recovery模式中的兩個通信接口
在Recovery服務中上述的三個實體之間的通信是不可缺少的,它們有下面兩個通信接口。
3.1 主系統和Recovery通過/cache下的文件通信
Recovery通過/cache/recovery/文件夾下的三個文件與main system通信。詳細例如以下
l /cache/recovery/command:這個文件保存着Main system傳給Recovery的命令行,每一行就是一條命令,支持一下幾種的組合。
--send_intent=anystring //write the text out to recovery/intent
在Recovery結束時在finish_recovery函數中將定義的intent字符串作為參數傳進來,並寫入到/cache/recovery/intent中。
-update_package=root:path //verify install an OTA(On The Air) package file
Main system將這條命令寫入時,代表系統須要升級,在進入Recovery模式后,將該文件里的命令讀取並寫入BCB中,然后進行對應的更新update.zip包的操作。
--wipe_data //erase user data(and cache),then reboot。
擦除用戶數據。擦除data分區時必需要擦除cache分區。
--wipe_cache //wipe cache(but not user data),then reboot。
擦除cache分區。
--set_encrypted_filesystem=on|off - enables / diasables encrypted fs
啟用/禁用加密的文件系統
--just_exit - do nothing; exit and reboot
退出並重新啟動
l /cache/recovery/log:Recovery模式在工作中的log打印。
在recovery服務執行過程中,stdout以及stderr會重定位到/tmp/recovery.log在recovery退出之前會將其轉存到/cache/recovery/log中,供查看。
l /cache/recovery/intent:Recovery傳遞給Main system的信息。作用不詳。
上層應用能夠通過調用Android標准的RecoverySystem類(位於frameworks/base/core/java/android/os/RecoverySystem.java中)的接口來完畢與Recovery模式的通信,例如以下圖所看到的:
這個類里基本的接口例如以下:
installPackage() 重新啟動設備安裝指定升級包,在/cache/recovery/command里寫入”--update_package=/path/xxx.zip”
rebootWipeUserData() 重新啟動設備並清除user data分區,這個操作也成為“工廠復位”,
在/cache/recovery/command里寫入”--wipe_data”
rebootWipeCache() 重新啟動進入Recovery模式。清除cache分區,在/cache/recovery/command里寫入”--wipe_data”
verifyPackage() 這個接口主要是用於校驗下載回來的的升級包是否符合Android的簽名認證。
接口調用后,系統會重新啟動,轉入Recovery mode,然后recovery進程會去讀取/cache/recovery/command里的指令去運行對應的操作,是安裝升級包還是恢復出廠設置等。
3.2 Bootloader與Recovery通過BCB(Bootloader Control Block)通信
BCB是Bootloader與Recovery的通信接口,也是Bootloader與Main system之間的通信接口。存儲在flash中的MISC分區。占用三個page,其本身就是一個結構體,詳細成員以及各成員含義例如以下,位於/bootloader/revocery/bootloader.h文件里:
struct bootloader_message{
char command[32];
char status[32];
char recovery[1024];
};
l command字段:當要重新啟動進入Recovery模式或更新radio、bootloader固件時。linux會更新這個值。當固件更新完畢后Bootloader也會更新這個值。另外在成功更新后結束Recovery時。會清除這個成員的值,防止重新啟動時再次進入Recovery模式。
l status字段:在完畢對應的更新后。Bootloader會將運行結果寫入到這個字段。
l recovery字段:可被Main System寫入,也可被Recovery服務程序寫入。該文件的內容格式為:
“recovery\n
<recovery command>\n
<recovery command>”
該文件存儲的就是一個字符串,必須以recovery\n開頭,否則這個字段的全部內容域會被忽略。“recovery\n”之后的部分,是/cache/recovery/command支持的命令。
能夠將其理解為Recovery操作過程中對命令操作的備份。Recovery對其操作的過程為:先讀取BCB然后讀取/cache/recovery/command,然后將二者又一次寫回BCB。這樣在進入Main system之前。確保操作被運行。在操作之后進入Main system之前。Recovery又會清空BCB的command域和recovery域,這樣確保重新啟動后不再進入Recovery模式。
4 Recovery模式的基本流程
Recovery模式的基本流程例如以下:
1. 選擇“設置”->“系統”->”系統還原”。
2. Main system向/cache/recovery/command寫入"--wipe_data";
3. Main system 重新啟動進入Recovery模式;
4. get_args() 函數向 BCB寫入"boot-recovery"和"--wipe_data",然后開始擦除。
-- after this, rebooting will restart the erase --
5. erase_volume() 又一次格式化/data分區
6. erase_volume() 又一次格式化/cache分區
7. finish_recovery() 清除BCB。然后call reboot()進入Main system。
流程圖例如以下所看到的: