Android 系统OTA升级
一、升級包制作流程
整包:是可以直接用于OTA升級使用,相當于整個替換機器image。優點是操作簡單,不容易出問題。缺點是內存很大。
基礎包:是用于制作差分包。里面包含所有支持升級的image文件。將新舊兩個基礎包,使用系統自帶腳本進行對比差分操作后,就會按照新舊的差異點生成一個差分包。
差分包:是只有包含差點點信息和差異patch的。所以使用差分包升級,一定要保證機器里面當前的image和制作差分的基礎包里面的image完全一致。否則肯定升級失敗。
1.1、編譯一個完整刷機包
1.2、制作OTA包
在android目錄下執行 make otapackage –j8 編譯OTA包。以450平臺為例,編譯后會在
out\target\product\**\ 目錄下生成一個整包:?msm8953_64-ota-*.zip
out\target\product\**\obj\PACKAGING\target_files_intermediates目錄下生成一個基礎包:?msm8953_64-*.zip
差分包制作執行源碼腳本:Android R 需要增加 -p 參數指向依賴的二進制文件
./build/tools/releasetools/ota_from_target_files (-p out/host/linux-x86) -v -i old.zip new.zip update.zip
二、Recovery 升級模式
Recovery升級是原生默認的升級方式,后面某些高端平臺可能會默認廢棄這種方式。升級基于recovery分區進行,對image進行升級操作。這種升級方式,優點是節省ROM,缺點是如果發生意外導致系統image損壞,機器就可能變磚了。
debug模式下調試OTA方法
執行如下 adb 指令進行升級操作
adb rootadb remountadb push update.zip /data/update.zipadb shelluncrypt /data/update.zip /cache/recovery/block.mapecho "--update_package=@/cache/recovery/block.map" > /cache/recovery/commandadb reboot recovery注:7.0之前系統沒有uncrypt,將升級包push到/cache/update.zip,再執行如下指令
adb rootadb remountadb push update.zip / cache /update.zipadb shellecho " --update_package=/cache/update.zip " > /cache/recovery/commandadb reboot recoveryuser版本需要可以使用系統API接口
方法一:使用系統自帶API相關接口文件叫 android.os.RecoverySystem,調用其 installPackage 等方法即可。注意權限需要是系統APP才可以。
方法二:adb reboot recovery 進入到 recovery 界面,有如下兩項
Apply update from ADB
Apply update from SD Card
這兩種都可以升級,選擇后根據界面提示操作即可。
備注:可能有些平臺沒有這個界面功能。
三、A/B分區模式升級
AB升級模式應該是后續主要升級模式。原理就是在ROM中分了兩個區域,各自有一套image。優點是更安全,即使是一套分區出問題了,仍然有一套可以使用,機器不會變磚。缺點就是多一套分區導致ROM占用更多。
debug模式下調試
adb rootadb remountadb push update.zip data/ota_package/update.zipadb shellupdate_engine_client --update --follow --payload=file:///data/ota_package/update.zip --offset=7919 --size=724346 --headers="FILE_HASH=1RilNlJjIRfwwd8t86YucEhJV67msLzETHprS+HcWyg=FILE_SIZE=724346METADATA_HASH=vQsISDOuPUCkczn6FizKVHV8mkF8YqNYnNi21l6Du9o=METADATA_SIZE=440778"update_engine_client后面的參數根據OTA包生成。表示OTA包的參數。新建ota.py,將下面代碼復制過去,再執行python腳本 python ota.py update.zip 即會生成。
#!/usr/bin/env pythonimport sys import zipfiledef main():if len(sys.argv) != 2:sys.stderr.write('Use: %s <ota_file.zip>\n' % sys.arv[0])return 1otazip = zipfile.ZipFile(sys.argv[1], 'r')payload_info = otazip.getinfo('payload.bin')payload_offset = payload_info.header_offset + len(payload_info.FileHeader())payload_size = payload_info.file_sizepayload_location = '/data/ota_package/update.zip'headers = otazip.read('payload_properties.txt')print ('update_engine_client --update --follow --payload=file://{payload_location}'' --offset={payload_offset} --size={payload_size}'' --headers="{headers}"').format(**locals())return 0if __name__ == '__main__':sys.exit(main())執行update_engine_client指令后,等待升級完成,窗口有如下相關提示,表示升級成功。
[INFO:update_engine_client_android.cc(90)] onStatusUpdate(UPDATE_STATUS_UPDATED_NEED_REBOOT (6), 0)[INFO:update_engine_client_android.cc(98)] onPayloadApplicationComplete(ErrorCode::kSuccess (0))user版本調試
需要使用系統相關接口,android.os.UpdateEngine android.os.UpdateEngineCallback。
UpdateEngine.applyPayload? 升級接口
UpdateEngineCallback是升級監聽,如下:
??? class MyUpdateEngineCallback extends UpdateEngineCallback {@Overridepublic void onStatusUpdate(int status, float percent) {Log.i(TAG, "percent:" + percent);if (percent > 0)mInfoTextView.setText("升級進度:" + percent);}@Overridepublic void onPayloadApplicationComplete(int errorCode) {Log.i(TAG, "errorCode:" + errorCode);if (errorCode == 0) {handler.sendEmptyMessage(UPDATE_SUCCESS);} else {Message msg = new Message();msg.what = UPDATE_ERROR;Bundle bundle = new Bundle();bundle.putInt("errorCode", errorCode);msg.setData(bundle);handler.sendMessage(msg);}if (mUpdateEngine != null) {mUpdateEngine.unbind();}}}常見調試問題
a、如何確認AB升級當前分區
通過查看 ro.boot.slot_suffix 屬性值的方式,這個屬性值顯示當前使用分區名
b、如何手動切換分區
通過進入bootloader 模式,指定啟動槽值來選擇下次啟動的分區,按照如下指令即可
adb reboot bootloader
fastboot --set-active=a
fastboot reboot
c、如何判斷失敗原因
升級結束時,可以看到有個錯誤碼,常見錯誤碼如下,按照錯誤碼去查找可能原因
ErrorCode::kSuccess (0) 升級成功
ErrorCode::kSuccess (1) 升級失敗
ErrorCode::kFilesystemCopierError (4) 未知,暫時未使用的錯誤碼
ErrorCode::kPostinstallRunnerError (5) 升級安裝結束,設置啟動分區失敗
ErrorCode::kPayloadMismatchedType (6) 升級包的升級類型不匹配或升級包minor version不兼容
ErrorCode::kInstallDeviceOpenError (7) 無法啟動升級。可能是原因:分區錯誤,設備支持升級的分區和升級包內的不匹配;設備處于disable-verity狀態;
ErrorCode::kKernelDeviceOpenError (8) 未知,暫時未使用的錯誤碼
ErrorCode::kDownloadTransferError (9) w,找不到升級包
ErrorCode::kPayloadHashMismatchError (10) FILE_HASH值不匹配
ErrorCode::kPayloadSizeMismatchError (11) 數據size不匹配
ErrorCode::kDownloadPayloadVerificationError (12) 簽名驗證失敗
ErrorCode::kDownloadStateInitializationError (20) 升級包寫入時失敗? 一般都是發生在差分包升級時,檢測boot、system、vendor的hash值不匹配。
ErrorCode::kDownloadInvalidMetadataMagicString (21)? 未找到正確bin文件,一般是offset不對導致
ErrorCode::kDownloadInvalidMetadataSize (32) METADATA_SIZE值不匹配
ErrorCode::kPayloadTimestampError (51) 升級包的date比機器當前版本早
system/update_engine/update_engine_client_android.cc
總結
以上是生活随笔為你收集整理的Android 系统OTA升级的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 人脸识别SDK调用与分析
- 下一篇: python读xlsb