升级失败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.
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.
这个操作的磁盘上的源数据的散列与预期值不匹配。这可能意味着增量更新有效负载是针对另一个版本的,或者是在安装之后修改了源分区,例如,通过安装文件系统。
原因: make otapackage 会对system.img重新打包 导致重新打包的system.img和out目录下的system.img Hash值不一致. 也就是线刷版本的system.img和OTA包的system.img不一致;整包升级会替换system.img,而差分包升级则需要保证系统内部的system.img和整包中system.img一致才能升级成功(差分包中保存了通过sha256 Hash算法计算出整包system.img的值,通过这个值来确定两个system.img一致).
验证是否如上原因导致:
将整包中system.img通过fastboot烧录到当前系统,再验证差分包升级
adb reboot bootloader
fastboot devices
//切换到system.img所在的目录
fastboot flash system system.img
fastboot reboot
解决:保证差分包或整包的system.img和线刷(也就是out目录下)的system.img保持一致.将make otapackage源包中的system.img替换out目录下system.img
out/target/product/xxx_qn6005_64/obj/PACKAGING/systemimage_intermediates/system.img
out/target/product/xxx_qn6005_64/system.img
脚本实现:
1.在/build/core/Makefile中添加:
$(hide) ./build/tools/releasetools/replace_img_from_target_files.py $@ $(PRODUCT_OUT)
2.在/build/tools/releasetools/中定义replace_img_from_target_files.py脚本
#!/usr/bin/env python
#
# Copyright (C) 2014 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Given a target-files zipfile that does contain images (ie, does
have an IMAGES/ top-level subdirectory), replace the images to
the output dir.
Usage: replace_img_from_target_files target_files output
"""
import sys
if sys.hexversion < 0x02070000:
print >> sys.stderr, "Python 2.7 or newer is required."
sys.exit(1)
import errno
import os
import re
import shutil
import subprocess
import tempfile
import zipfile
image_replace_list = ["boot.img","system.img"]
# missing in Python 2.4 and before
if not hasattr(os, "SEEK_SET"):
os.SEEK_SET = 0
def main(argv):
if len(argv) != 2:
sys.exit(1)
if not os.path.exists(argv[0]):
print "Target file:%s is invalid" % argv[0]
sys.exit(1)
if not os.path.exists(argv[1]):
print "Output dir:%s is invalid" % argv[1]
sys.exit(1)
zf = zipfile.ZipFile(argv[0], 'r')
for img in zf.namelist():
if img.find("IMAGES/") != -1:
if img.find(".img") != -1:
data = zf.read(img)
name = img.replace("IMAGES/", '')
if name in image_replace_list:
print "Replace %s" % name
name = '/'.join((argv[1], name))
file = open(name, "w")
file.write(data)
file.close()
if __name__ == '__main__':
main(sys.argv[1:])
文章参考:
Android OTA差分包升级失败