最近在作recovery模式下的升級,簡單的總結一下。編程
先說說recovery模式,他是個升級小系統,有單獨的kernel,經過特定的系統命令就能夠進入到此係統中,選擇進入正常系統的kernel仍是recovery系統的kernel,函數
決定在於bootloader中,recovery中的boot與正常系統的boot燒寫的是相同的kernel,不一樣點在於,recovery模式有一個單獨的rootfs,這個是一個很是小的系統,工具
系統的不少功能也是不啓動的, 主要目的就是留給升級流出足夠的內存,主系統與recovery系統通訊的橋樑就是/cache分區,此分區在正常系統啓動與recoveryui
模式都是要被掛載mount。在主系統寫命令到cache中,在recovery中讀取,升級後,升級結果及日誌也是在cache中。3d
recovery系統中大體流程,有些以爲不重要就省略了日誌
一、執行find_recovery_partition.sh腳本它的工做就是生成/res/recovery_volume_detected文件,很重要的,掛載分區,attach類型爲ubi的分區,如system modem。blog
二、rc啓動腳本主要是啓動了調用recovery進程的腳本,此腳本中運行recovery進程,升級的全部功能就在recovery進程中完成,recovery進程中涉及到的load_volume_table()進程
函數,讀取的文件就是由find_recovery_partition.sh腳本生成的。ip
三、讀取升級命令,升級命令位於/cache/recovery/command中,格式能夠看函數註釋。在此過程當中會寫misc分區一個msg,主要是防止升級過程當中掉電,在lk中會內存
讀取misc中的msg,若是升級中異常掉電,系統加載起來以後就繼續進入recovery模式進程升級。
四、接下來就是從升級包重獲取可執行程序,讀取到/tmp中,升級包簽名校驗,本項目沒涉及到很少說,而後就是建立管道,建立子進程,子進程中執行updater進
程。將進度,結果等通知到主進程,直到升級結束。
五、updater進程的執行過程,有太多的文件講了及就不講了。
六、升級結束後,finish_recovery作收尾工做,拷貝日誌,寫升級結果,而後系統reboot。
七、重啓後,主系統正常啓動後,就能夠從cache中獲取到當前升級的結果,日誌,升級包等。
遇到的一些問題:
一、對nand來講,存在flash層的操做與mtd層的操做,lk中是對flash的操做能夠按照頁,頁大小有2048/4096,mtd層對block操做的,通常都是好多個頁組成,如64*2048,
做爲一個block。有個分區比較特殊,不能多寫flash,由於就是recovery中是mtd層的操做,想要精確,只能在lk中去作,比較特殊。
二、使用的打包工具,高人寫了腳本,能夠將modem分區按照ubi的方式打包,非常厲害啊,對比了下文件展開方式,升級包比較小,升級還快,真實佩服啊。
三、整個recovery模式升級功能其實高通已經完成了不少關鍵,主要的功能,咱們也是簡單的使用了下。
10-24 新增流程圖
簡單說明
一、流程圖中省略也不少細節,其實好多細節都是能夠拿出來大寫特寫,好比差分文件是如何計算生成的(涉及imgdiff 與bsddiff),對於有文件系統的文件權限的處理
(full package時更關心一點) updater-script腳本用於執行的腳本解析器的運行,等等
二、標註紅色的部分是我認爲比較關鍵和重要的部分,包括爲說明的updater-script每條命令對應的回調函數。
三、可能不一樣的應用場景不同,當前沒有將ui部分的邏輯,還有升級前的條件檢查處理,升級異常等等。
四、recovery進程執行結束以後會執行收尾工做,保存日誌,寫升級結果等等,而後就是syse_reboot,圖中帶recovery 的塊其實就是在recovery進程中執行的, 按照函數
調用順序寫的。
長按二維碼關注【嵌入式C部落】,獲取更多編程資料及精華文章