Android A/B System OTA 升級以及報錯處理

介紹

    A/B System OTA是Android 7.0引入的新的OTA方式,跟以前的OTA在升級流程上來說已經完全不一樣了,我們都知道之前的OTA走的是recovery模式。A/B System 不同之處在於系統中有兩個system分區,當然boot分區也是兩個,A和B,當我們進行OTA升級的時候實際上只是對b分區進行升級,而我們正在運行的a分區是不受影響的。

 

OTA包製作

    製作流程跟以前是一樣的,我簡單提一下,首先就是make命令:

make otapackage

生成的target_files文件在out目錄下:

out/target/product/xxx/obj/PACKAGING/target_files_intermediates/xxx.zip

OTA完整包在out下面,與system.img同一級目錄,這裏就不多說了。差分包的製作:

./build/tools/releasetools/ota_from_target_files -v --block -p out/host/linux-x86 -k build/target/product/security/testkey -i target_files_01.zip target_files_02.zip update.zip

生成的update.zip就是我們所需要的差分包。

 

OTA升級流程

    根據官方文檔的說明,主要分爲以下幾步:

1、將上面生成的OTA包push到機器中,

adb push update.zip /data/ota_package/update.zip

2、解析OTA包,生成升級所需參數

ota.py update.zip

附上Python腳本

import sys
import zipfile
def main():
    if len(sys.argv) != 2:
        sys.stderr.write('Use: %s <ota_file.zip>\n' % sys.arv[0])
        return 1
    otazip = 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_size
    payload_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 0
if __name__ == '__main__':
    sys.exit(main())

3、執行上面Python腳本解析之後的命令,shell環境中執行:

update_engine_client --update --follow
--payload=/data/ota_package/update.zip --offset=PAYLOAD_OFFSET
--size=PAYLOAD_SIZE --headers="HEADERS"

4、重啓機器

 

升級過程中的報錯及解決方案

    先貼上log


I update_engine: [0530/162336:INFO:delta_performer.cc(359)] Applying 21701 operations to partition "system"
E update_engine: [0530/162336:ERROR:delta_performer.cc(1060)] The hash of the source data on disk for this operation doesn't match the expected value. This could mean that the delta update payload was targeted for another version, or that the source partition was modified after it was installed, for example, by mounting a filesystem.
E update_engine: [0530/162336:ERROR:delta_performer.cc(1065)] Expected:   sha256|hex = 839ACF5296B9AB820DC822B6C09EBA896905531EB2C581093A357411F1A444A0
E update_engine: [0530/162336:ERROR:delta_performer.cc(1068)] Calculated: sha256|hex = 18AF8D6842A71554893F1DE65B87F2A9639FB390357C71D5383C6ED7A6051AFA
E update_engine: [0530/162336:ERROR:delta_performer.cc(1077)] Operation source (offset:size) in blocks: 0:2,193:1,218:456,23471:8,32769:1,32961:1,37333:4,37351:3,37554:3,37570:2,37951:1,37959:1,38111:1,38125:1,38129:1,38139:1,38147:1,38149:1,38151:2,38155:1,38157:1,38360:5,38372:1,38377:5,38384:1,38437:1,38442:1,38447:1,38452:1,38457:1,38462:1,38467:1
E update_engine: [0530/162336:ERROR:delta_performer.cc(1260)] ValidateSourceHash(source_hasher.raw_hash(), operation, error) failed.
E update_engine: [0530/162336:ERROR:delta_performer.cc(283)] Failed to perform SOURCE_BSDIFF operation 8, which is the operation 0 in partition "system"
E update_engine: [0530/162336:ERROR:download_action.cc(273)] Error 20 in DeltaPerformer's Write method when processing the received payload -- Terminating processing
I update_engine: [0530/162336:INFO:delta_performer.cc(299)] Discarding 113721 unused downloaded bytes
I update_engine: [0530/162336:INFO:multi_range_http_fetcher.cc(171)] Received transfer terminated.
I update_engine: [0530/162336:INFO:multi_range_http_fetcher.cc(123)] TransferEnded w/ code 200
I update_engine: [0530/162336:INFO:multi_range_http_fetcher.cc(125)] Terminating.
I update_engine: [0530/162336:INFO:action_processor.cc(116)] ActionProcessor: finished DownloadAction with code ErrorCode::kDownloadStateInitializationError
I update_engine: [0530/162336:INFO:action_processor.cc(121)] ActionProcessor: Aborting processing due to failure.
I update_engine: [0530/162336:INFO:update_attempter_android.cc(286)] Processing Done.
I update_engine: [0530/162336:INFO:update_attempter_android.cc(306)] Resetting update progress.

從log可以看出,是校驗system的時候兩次hash值不匹配導致的,造成這個錯誤的原因是我直接刷的out下面的system.img,而這個system.img與target_files中的system.img時間戳不同,導致校驗失敗。

解決方案就是用target_files中的system.img代替out下面的。

 

中間還有一個小插曲,adb remount也會導致同樣的錯誤,可能是重新掛載分區會影響到校驗結果,這個還在研究中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章