1、調用main函數
在gingerbread/bootable/recovery/recovery.c最下面有個main(),這是recovery應用的主入口,當編譯recovery的時候,會產生一個名為recovery的可執行檔,我這邊是放在out/目錄下recovery/檔案系統的/sbin目錄下,調用recovery可執行檔時會傳入參數,這些參數就是main函數的參數,如下
intmain(int argc, char **argv){ char tmp[4]; time_t start = time(NULL);#if RECOVERY_DBGlog_init();#endifINFO(">>>>> Enter recovery <<<<<\n");
argc是參數個數,argv是每個參數指標
從這裡開始了recovery...
2、擷取commond
static voidget_args(int *argc, char ***argv) {//INFO("Enter get_args\n"); struct bootloader_message boot; 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
if (update_image != NULL) { status = install_update(update_image); if (status != 0) { ui_set_background(BACKGROUND_ICON_ERROR); if(status==-1) g_enable_item_move = false; } }else if(recover_image != NULL){status = recover_backup(recover_image); if (status != 0) { ui_set_background(BACKGROUND_ICON_ERROR); if(status==-1) g_enable_item_move = false; } }
這部分代碼是update\recover的需求,update走install_update分支,recovery走recover_backup分支,g_enable_item_move是在recovery升級介面條目是否可移動的一個變數,false表示不能移動
if (wipe_flags) { if( wipe_data(wipe_flags) != 0 ) { status = INSTALL_ERROR; ui_print("Data wipe failed.\n"); // 不擦除misc中的命令,重啟後再次格式化 g_reset_blmsg = false; g_enable_item_move = false; } }
這部分是擦除資料,就是格式化需求,根據擦除flags記錄,分別去擦除需要格式化的分區或者磁碟,如果擦除失敗,g_reset_blmsg 這個變數在擦除boot時候作為判別依據,false表示不擦出,這樣,misc分區的內容還是recovey,下次重啟後,boot引導進入recovery模式
prompt_and_wait()函數裡面,關鍵區段
for (;;) { int key = 0;INFO("wait an key\n");key = ui_wait_key();INFO("end wait\n");
這個函數作用就是一直在等待使用者輸入是一個不斷的迴圈,可以選擇五個條目,包括恢復出廠預設值和重啟等;maybe_install_firmware_update(send_intent);是給使用者一個機會,寫入你的intent,做一些Google沒有做的事這個就是完成升級的最後一個函數,
// Reset the bootloader message to revert to a normal main system boot. if(g_reset_blmsg) {INFO("ready to clear cmd in misc \n"); struct bootloader_message boot; memset(&boot, 0, sizeof(boot)); set_bootloader_message(&boot); }
在這之前是針對intent的一個處理,這裡g_reset_blmsg是根據上文提到的清除boot的一個判據,如果需要清除boot,表明下次重啟後正常啟動,不進入recovery模式
6、reboot處理完boot和misc分區,重啟