Merge "device: qcom: releasetools.py: Extend Incremental FOTA"
This commit is contained in:
commit
f2d054deb6
235
releasetools.py
235
releasetools.py
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue