Merge "device: qcom: releasetools.py: Extend Incremental FOTA"

This commit is contained in:
Linux Build Service Account 2013-08-15 21:30:41 -07:00 committed by Gerrit - the friendly Code Review server
commit f2d054deb6
1 changed files with 97 additions and 138 deletions

View File

@ -46,6 +46,21 @@ def GetRadioFiles(z):
out[fn] = info.filename
return out
def GetImageData(fpath, in_zip, base_zip=None):
try:
in_img = in_zip.read(fpath)
except KeyError:
print "Warning: could not read '%s' from '%s'." % (fpath, in_zip)
in_img = ""
base_img = ""
if base_zip is not None:
try:
base_img = base_zip.read(fpath)
except KeyError:
base_img = ""
return in_img, base_img
def FullOTA_Assertions(info):
#TODO: Implement device specific asserstions.
return
@ -54,10 +69,38 @@ def IncrementalOTA_Assertions(info):
#TODO: Implement device specific asserstions.
return
# This function handles only non-HLOS boot images - files list must contain
# only such images (aboot, tz, etc)
def ExtractBootFiles(info, input_zip, files, filesmap):
# This function checks if fw image is to be handled incrementally and if
# this is the case it creates and adds the diff patch to the update zip and
# adds the appropriate applypatch command to the update script
def HandleIncrementally(info, f, fpath, img_dest, in_img, base_img):
in_f = common.File(fpath, in_img)
base_f = common.File(fpath, base_img)
if in_f.sha1 == base_f.sha1:
return False
diff = common.Difference(in_f, base_f)
common.ComputeDifferences([diff])
_, _, d = diff.GetPatch()
if d is None or len(d) > in_f.size * common.OPTIONS.patch_threshold:
# compute difference failed or the difference is bigger than the
# target file * predefined threshold - do full update
return False
patch = "patch/firmware-update/" + f + ".p"
common.ZipWriteStr(info.output_zip, patch, d)
info.script.ApplyPatch("EMMC:%s:%d:%s:%d:%s" %
(img_dest, base_f.size, base_f.sha1, in_f.size, in_f.sha1),
"-", in_f.size, in_f.sha1, base_f.sha1, patch)
return True
# This function handles only non-HLOS whole partition images - files list
# must contain only such images
def InstallRawImages(info, files, filesmap, in_zip, base_zip=None):
for f in files:
in_img, base_img = GetImageData(files[f], in_zip, base_zip)
if in_img == "":
continue
fn = f
# is the file encoded?
enc = f.endswith('.enc')
@ -69,9 +112,13 @@ def ExtractBootFiles(info, input_zip, files, filesmap):
print "warning radio-update: '%s' not found in filesmap" % (fn)
continue
# handle incrementally?
if base_img != "" and not enc:
if HandleIncrementally(info, fn, files[f], filesmap[fn], in_img, base_img):
continue
filepath = "firmware-update/" + f
image_data = input_zip.read(files[f])
common.ZipWriteStr(info.output_zip, filepath, image_data)
common.ZipWriteStr(info.output_zip, filepath, in_img)
if enc:
info.script.AppendExtra('package_extract_file("%s", "/tmp/%s");' % (filepath, f))
@ -82,53 +129,38 @@ def ExtractBootFiles(info, input_zip, files, filesmap):
# This function handles only non-HLOS boot images - files list must contain
# only such images (aboot, tz, etc)
def InstallBootImages(info, input_zip, files, filesmap):
def InstallBootImages(info, files, filesmap, in_zip, base_zip=None):
filesmapBak = {}
for f in filesmap:
if f.endswith('.bak'):
filesmapBak[f[:-4]] = filesmap[f]
#update main partitions
# update main partitions
info.script.AppendExtra('ifelse(msm.boot_update("main"), (')
info.script.AppendExtra('ui_print("Main boot images update start");')
ExtractBootFiles(info, input_zip, files, filesmap)
info.script.AppendExtra('ui_print("Main boot images update end")')
info.script.AppendExtra('), ui_print("Main boot images already updated") );')
#update backup partitions
info.script.AppendExtra('ifelse(msm.boot_update("backup"), (')
info.script.AppendExtra('ui_print("Backup boot images update start");')
InstallRawImages(info, files, filesmap, in_zip, base_zip)
info.script.AppendExtra('ui_print("Main boot images updated") ), "");')
if filesmapBak != {}:
ExtractBootFiles(info, input_zip, files, filesmapBak)
# update backup partitions
info.script.AppendExtra('ifelse(msm.boot_update("backup"), (')
InstallRawImages(info, files, filesmapBak, in_zip, base_zip)
info.script.AppendExtra('ui_print("Backup boot images updated") ), "");')
else:
info.script.AppendExtra('msm.boot_update("backup");')
info.script.AppendExtra('ui_print("Backup boot images update end")')
info.script.AppendExtra('), ui_print("Backup boot images already updated") );')
#finalize partitions update
# finalize partitions update
info.script.AppendExtra('msm.boot_update("finalize");')
return
# This function handles only non-HLOS firmware images different from boot
# images - files list must contain only such images (modem, dsp, etc)
def InstallFwImages(info, input_zip, files, filesmap):
def InstallFwImages(info, files, filesmap, in_zip, base_zip=None):
last_mounted = ""
for f in files:
filetoken = f
# If full file name is not specified in filesmap get only the name part
# and look for this token
if f not in filesmap:
filetoken = f.split(".")[0] + ".*"
if filetoken not in filesmap:
print "warning radio-update: '%s' not found in filesmap" % (filetoken)
continue
filepath = "firmware-update/" + f
image_data = input_zip.read(files[f])
common.ZipWriteStr(info.output_zip, filepath, image_data)
in_img, base_img = GetImageData(files[f], in_zip, base_zip)
if in_img == "":
continue
fn = f
# is the file encoded?
@ -137,10 +169,19 @@ def InstallFwImages(info, input_zip, files, filesmap):
# disregard the .enc extention
fn = f[:-4]
filetoken = fn
# If full file name is not specified in filesmap get only the name part
# and look for this token
if fn not in filesmap:
filetoken = fn.split(".")[0] + ".*"
if filetoken not in filesmap:
print "warning radio-update: '%s' not found in filesmap" % (filetoken)
continue
dest = ""
# Parse filesmap destination paths for "/dev/" pattern at the beginng.
# This would mean that the file must be written to block device -
# mount needed
# fs mount needed
mount = filesmap[filetoken].startswith("/dev/")
if mount:
if last_mounted != filesmap[filetoken]:
@ -151,6 +192,14 @@ def InstallFwImages(info, input_zip, files, filesmap):
else:
dest = filesmap[filetoken] + "/" + fn
# handle incrementally?
if base_img != "" and not enc:
if HandleIncrementally(info, fn, files[f], dest, in_img, base_img):
continue
filepath = "firmware-update/" + f
common.ZipWriteStr(info.output_zip, filepath, in_img)
if enc:
info.script.AppendExtra('package_extract_file("%s", "/tmp/%s");' % (filepath, f))
info.script.AppendExtra('msm.decrypt("/tmp/%s", "%s");' % (f, dest))
@ -161,26 +210,13 @@ def InstallFwImages(info, input_zip, files, filesmap):
info.script.AppendExtra('unmount("/firmware");')
return
def InstallRawImage(image_data, fn, info, filesmap):
if fn not in filesmap:
return
info.script.AppendExtra('package_extract_file("%s", "%s");' % (fn, filesmap[fn]))
common.ZipWriteStr(info.output_zip, fn, image_data)
return
def InstallBinImages(info, input_zip, files, filesmap):
for f in files:
image_data = input_zip.read(files[f])
InstallRawImage(image_data, f, info, filesmap)
return
def FullOTA_InstallEnd_MMC(info):
files = GetRadioFiles(info.input_zip)
def OTA_InstallEnd_MMC(info, in_zip, base_zip=None):
files = GetRadioFiles(in_zip)
if files == {}:
print "warning radio-update: no radio images in input target_files"
return
filesmap = LoadFilesMap(info.input_zip)
filesmap = LoadFilesMap(in_zip)
if filesmap == {}:
print "warning radio-update: no or invalid filesmap file found"
return
@ -206,12 +242,16 @@ def FullOTA_InstallEnd_MMC(info):
else:
fwFiles[f] = files[f]
if binFiles != {}:
InstallBinImages(info, info.input_zip, binFiles, filesmap)
if bootFiles != {}:
InstallBootImages(info, info.input_zip, bootFiles, filesmap)
InstallBootImages(info, bootFiles, filesmap, in_zip, base_zip)
if binFiles != {}:
InstallRawImages(info, binFiles, filesmap, in_zip, base_zip)
if fwFiles != {}:
InstallFwImages(info, info.input_zip, fwFiles, filesmap)
InstallFwImages(info, fwFiles, filesmap, in_zip, base_zip)
return
def FullOTA_InstallEnd_MMC(info):
OTA_InstallEnd_MMC(info, info.input_zip)
return
def FullOTA_InstallEnd_MTD(info):
@ -226,89 +266,10 @@ def FullOTA_InstallEnd(info):
FullOTA_InstallEnd_MMC(info)
elif info.type == 'MTD':
FullOTA_InstallEnd_MTD(info)
info.script.UnmountAll()
return
def WriteRadioFirmware(info, f, files, filesmap, trgt_img, src_img=None):
tf = common.File(files[f], trgt_img)
if src_img is None:
tf.AddToZip(info.output_zip)
InstallRawImage(trgt_img, f, info, filesmap)
else:
sf = common.File(files[f], src_img)
if tf.sha1 == sf.sha1:
print "%s image unchanged; skipping" % (f)
else:
diff = common.Difference(tf, sf)
common.ComputeDifferences([diff])
_, _, d = diff.GetPatch()
if d is None or len(d) > tf.size * common.OPTIONS.patch_threshold:
# compute difference failed or the difference is bigger than
# target file - write the whole target file.
tf.AddToZip(info.output_zip)
InstallRawImage(trgt_img, f, info, filesmap)
else:
patch = "patch/" + f + ".p"
common.ZipWriteStr(info.output_zip, patch, d)
info.script.Print("Patching Radio...")
radio_device = filesmap[f]
info.script.ApplyPatch("EMMC:%s:%d:%s:%d:%s" %
(radio_device, sf.size, sf.sha1, tf.size, tf.sha1),
"-", tf.size, tf.sha1, sf.sha1, patch)
return
def IncrementalOTA_InstallEnd_MMC(info):
files = GetRadioFiles(info.target_zip)
if files == {}:
print "warning radio-update: no radio images in input target_files"
return
filesmap = LoadFilesMap(info.target_zip)
if filesmap == {}:
print "warning radio-update: no or invalid filesmap file found"
return
info.script.Print("Incrementally updating firmware images...")
fwFiles = {}
bootFiles = {}
binFiles = {}
incFiles = {}
# Separate image types as each type needs different handling
for f in files:
dotSeparatedFname = f.split(".")
if dotSeparatedFname[-1] == 'enc':
if dotSeparatedFname[-2] == 'mbn':
bootFiles[f] = files[f]
elif dotSeparatedFname[-2] == 'bin':
binFiles[f] = files[f]
else:
fwFiles[f] = files[f]
else:
incFiles[f] = files[f]
if binFiles != {}:
InstallBinImages(info, info.target_zip, binFiles, filesmap)
if bootFiles != {}:
InstallBootImages(info, info.target_zip, bootFiles, filesmap)
if fwFiles != {}:
InstallFwImages(info, info.target_zip, fwFiles, filesmap)
for f in incFiles:
try:
trgt_img = info.target_zip.read(incFiles[f])
try:
src_img = info.source_zip.read(incFiles[f])
except KeyError:
print "source radio image = None"
src_img = None
WriteRadioFirmware(info, f, files, filesmap, trgt_img, src_img)
except KeyError:
print "no %s in target target_files; skipping install" % (f)
OTA_InstallEnd_MMC(info, info.target_zip, info.source_zip)
return
def IncrementalOTA_InstallEnd_MTD(info):
@ -323,6 +284,4 @@ def IncrementalOTA_InstallEnd(info):
IncrementalOTA_InstallEnd_MMC(info)
elif info.type == 'MTD':
IncrementalOTA_InstallEnd_MTD(info)
info.script.UnmountAll()
return