天天看點

android OTA更新

版權聲明:您好,轉載請留下本人部落格的位址,謝謝 https://blog.csdn.net/hongbochen1223/article/details/49834125

Android OTA更新

​ ​ ​ ​  Android裝置可以接受和安裝系統和應用軟體的空中下載下傳更新.裝置有一個特殊的帶有軟體的recovery分區,該分區可以解壓下載下傳的更新包并且将他們應用到系統中.

​ ​ ​ ​ 

這一小節描述了這些包的結構和為了建構他們所提供的工具.主要是為了那些想要在新的Android裝置上制作OTA更新系統工作和那些為發行的的裝置建構更新包的開發者設計的.OTA更新被設計用于設計底層的作業系統和安裝在系統分區的隻讀app;這些更新不會影響來自應用市場的使用者安裝的應用程式.

這一小節描述的是Android5.x發行版的OTA系統更新.最後我會将其他版本的OTA相關的代碼附上.

Android裝置更新

Android裝置上的flash空間包含下面的幾個分區:

boot
包含Linux核心和一個小型的根檔案系統(被加載到RAM中).他挂載系統和其他分區,并且啟動位于系統分區上的運作時.
system
​包含系統應用和在android開源項目(AOSP)中存在源代碼的庫檔案.在正常操作期間,這個分區是以隻讀方式被挂載的;他的内容僅僅在OTA更新期間被改變.
vendor
​包含系統應用和在AOSP中不存在源代碼的庫檔案.在正常操作期間,該分區是以隻讀的方式挂載的;他的内容僅僅在OTA更新期間被改變.
userdata
儲存由使用者安裝的應用的資料.這個分區通常是不能被OTA更新改變的.
cache
​​暫時持有被一些應用所使用的區域(通路這個分區需要特殊的app權限),并且用于存儲下載下傳的OTA更新包.其他應用程式使用這個空間,會知道檔案會在任何時候消息.一些OTA包安裝程式可能會導緻這個分區被完全擦除.   ​
recovery
​包含一個完整的Linux系統,包括一個核心和特殊的recovery二進制檔案,這些檔案讀取一個包并且使用他的内容來更新其他分區.
misc
被recovery使用的小型分區來儲存一些資訊,以防止當OTA包正在被應用的時候裝置重新開機.
           

一個OTA更新的聲明周期

一個典型的OTA更新包含下面的步驟:

  1. 裝置使用OTA服務運作正常的檢查,并且被可用更新通知,包括更新包的URL和展示給使用者的一個描述字元串.
  2. 更新下載下傳到一個cache或者是data分區,并且他的加密簽名和位于/system/etc/security/otacerts.zip的證書進行驗證.使用者被推送來安裝更新
  3. 裝置重新開機進入recovery模式,在這個模式中,位于recovery分區的核心和系統被啟動,而不是位于boot分區核心啟動
  4. Recovery二進制檔案被init啟動.他尋找位于/cache/recovery/command中的指令行參數,該參數執行下載下傳的包.
  5. Recovery通過位于/res/keys(位于recovery分區的一部分RAM)下的公共鑰匙來驗證包的加密簽名.
  6. 資料從包中提取出來并且用于去更新需要的boot,system和vendor分區.位于system分區的其他新檔案之一包含新的recovery分區的内容
  7. 裝置正常重新開機.

    a.  新更新的boot分區被加載,他挂載和開始執行位于新的更新的system分區中的二進制檔案

    b. ​作為正常啟動的一部分,系統檢查recovery分區的内容和需要的内容做對比(之前以檔案的形式儲存在/system中). 他們是不同的,是以recovery分區被需要的内容寫入.(在随後的啟動中,recovery分區已經包含新的内容,是以不需要重新寫入了.)

系統更新完成了.

遷移從先前的版本

當從Android2.3/3.0/4.0發行版遷移的時候,主要的改變就是所有的裝置特定的函數從一套C函數到預定義名稱的C++對象的轉換.下列的表列舉除了實作同樣目的的舊函數和新方法.

C function C++ method
device_recovery_start() Device::RecoveryStart()

device_toggle_display()

device_reboot_now()

RecoveryUI::CheckKey()

(also RecoveryUI::IsKeyPressed())

device_handle_key() Device::HandleMenuKey()
device_perform_action() Device::InvokeMenuItem()
device_wipe_data() Device::WipeData()
device_ui_init() ScreenRecoveryUI::Init()

舊函數到新方法的轉換應該是非常合理直接的.不要忘記添加一個新的make_device()函數來建立和傳回一個新的裝置子類的執行個體.

繼續閱讀