1、調用main函數
在gingerbread/bootable/recovery/recovery.c最下面有個main(),這是recovery應用的主入 口,當編譯recovery的時候,會產生一個名為recovery的可執行檔,我這邊是放在out/目錄下recovery/檔案系統的/sbin目 錄下,調用recovery可執行檔時會傳入參數,這些參數就是main函數的參數,如下
02 |
main(int
argc, char **argv) |
05 |
time_t
start = time(NULL); |
10 |
INFO(">>>>> Enter recovery <<<<<\n"); |
argc是參數個數,argv是每個參數指標
從這裡開始了recovery...
2、擷取commond
2 |
get_args(int
*argc, char ***argv) { |
3 |
// INFO("Enter get_args\n"); |
4 |
struct
bootloader_message boot; |
5 |
memset(&boot, 0,
sizeof(boot)); |
如果命令列有recovery命令,優先執行命令列的recovery命令; 否則,往下尋找misc分區中的命令、/cache/recovery/command檔案中的命
3、擷取預設升級韌體路徑和名稱
int property_get(const char *key, char *value, const char *default_value);
包括隨身碟、SD卡和Flash升級
4、解析命令
int getopt_long(int, char * const *, const char *, const struct option *, int *);
如 case 's': send_intent = optarg; break;
optarg是取命令中等號後面字串
註冊一些命令,register_update_commands函數是註冊在update-script和recovery-script使用的升級命令
初始化一個變數,int status = INSTALL_SUCCESS;這個變數是用來標識升級是否成功,在清除misc分區命令時候作為一個判斷依據
5、升級、格式化、還原
接下來,有三種需求,一是factorytest;二是update、recover;三是wipe data
01 |
if (update_image != NULL) { |
02 |
status = install_update(update_image); |
04 |
ui_set_background(BACKGROUND_ICON_ERROR); |
05 |
if(status==-1) g_enable_item_move =
false; |
07 |
}else
if(recover_image != NULL){ |
08 |
status = recover_backup(recover_image); |
10 |
ui_set_background(BACKGROUND_ICON_ERROR); |
11 |
if(status==-1) g_enable_item_move =
false; |
這部分代碼是update\recover的需求,update走install_update分支,recovery走recover_backup分 支,g_enable_item_move是在recovery升級介面條目是否可移動的一個變數,false表示不能移動
02 |
if( wipe_data(wipe_flags) != 0 ) |
04 |
status = INSTALL_ERROR; |
05 |
ui_print("Data wipe failed.\n"); |
06 |
// 不擦除misc中的命令,重啟後再次格式化 |
08 |
g_enable_item_move =
false; |
這部分是擦除資料,就是格式化需求,根據擦除flags記錄,分別去擦除需要格式化的分區或者磁碟,如果擦除失敗,g_reset_blmsg 這個變數在擦除boot時候作為判別依據,false表示不擦出,這樣,misc分區的內容還是recovey,下次重啟後,boot引導進入 recovery模式 prompt_and_wait()函數裡面,關鍵區段
這個函數作用就是一直在等待使用者輸入是一個不斷的迴圈,可以選擇五個條目,包括恢復出廠預設值和重啟 等;maybe_install_firmware_update(send_intent);是給使用者一個機會,寫入你的intent,做一些Google沒有 做的事這個就是完成升級的最後一個函數,
1 |
// Reset the bootloader message to revert to a normal main system boot. |
4 |
INFO("ready to clear cmd in misc \n"); |
5 |
struct
bootloader_message boot; |
6 |
memset(&boot, 0,
sizeof(boot)); |
7 |
set_bootloader_message(&boot); |
在這之前是針對intent的一個處理,這裡g_reset_blmsg是根據上文提到的清除boot的一個判據,如果需要清除boot,表明下次重啟後正常啟動,不進入recovery模式
6、reboot處理完boot和misc分區,重啟