def IncrementalOTA_InstallEnd(info): print "amlogic extensions:IncrementalOTA_InstallEnd" source_bootloader = common.File("bootloader.img", info.source_zip.read("BOOTLOADER/bootloader")); target_bootloader = common.File("bootloader.img", info.target_zip.read("BOOTLOADER/bootloader")); updating_bootloader = (source_bootloader.data != target_bootloader.data); if updating_bootloader: SetBootloaderEnv(info.script, "upgrade_step", "1")
def WriteRadio(info, target_radio_img, source_radio_img=None): tf = common.File("radio.img", target_radio_img) if source_radio_img is None: tf.AddToZip(info.output_zip) info.script.Print("Writing radio...") info.script.WriteRawImage("/radio", tf.name) else: sf = common.File("radio.img", source_radio_img) if tf.sha1 == sf.sha1: print "radio image unchanged; skipping" else: diff = common.Difference(tf, sf, diff_program="bsdiff") common.ComputeDifferences([diff]) _, _, d = diff.GetPatch() if d is None or len(d) > tf.size * common.OPTIONS.patch_threshold: # computing difference failed, or difference is nearly as # big as the target: simply send the target. tf.AddToZip(info.output_zip) info.script.Print("Writing radio...") info.script.WriteRawImage("/radio", tf.name) else: common.ZipWriteStr(info.output_zip, "radio.img.p", d) info.script.Print("Patching radio...") radio_type, radio_device = common.GetTypeAndDevice( "/radio", info.info_dict) info.script.ApplyPatch( "%s:%s:%d:%s:%d:%s" % (radio_type, radio_device, sf.size, sf.sha1, tf.size, tf.sha1), "-", tf.size, tf.sha1, sf.sha1, "radio.img.p")
def ComputeFWUpdatePatches(source_tfp_dir, target_tfp_dir, variant=None, existing_ota_zip=None): patch_list = None verbatim = None output_files = None # In case an already "fixed up" ota package is passed - Do nothing if existing_ota_zip and patch_or_verbatim_exists("fwu_image.bin", existing_ota_zip): return verbatim, patch_list, output_files src_fwupdate_data = readfile_from_provdata(source_tfp_dir, "fwu_image.bin", variant) if not src_fwupdate_data: return verbatim, patch_list, output_files tgt_fwupdate_data = readfile_from_provdata(target_tfp_dir, "fwu_image.bin", variant) if not tgt_fwupdate_data: return verbatim, patch_list, output_files src_fwupdate = common.File("fwu_image.bin", src_fwupdate_data) tgt_fwupdate = common.File("fwu_image.bin", tgt_fwupdate_data) diffs = [common.Difference(tgt_fwupdate, src_fwupdate)] common.ComputeDifferences(diffs) tf, sf, d = diffs[0].GetPatch() verbatim = False # If the patch size is almost as big as the actual file # the fwu_image will be included in the OTA verbatim. if d is None or len(d) > tf.size * 0.95: print("Firmware update image will be included verbatim") verbatim = True else: patch_list = (tf,sf) output_files = d return verbatim, patch_list, output_files
def IncrementalOTA_InstallEnd(info): try: target_bootloader_img = info.target_zip.read("RADIO/bootloader.img") try: source_bootloader_img = info.source_zip.read( "RADIO/bootloader.img") except KeyError: source_bootloader_img = None if source_bootloader_img == target_bootloader_img: print "bootloader unchanged; skipping" else: common.ZipWriteStr(info.output_zip, "bootloader.img", target_bootloader_img) info.script.Print("Writing bootloader...") info.script.WriteRawImage("/bootloader", "bootloader.img") except KeyError: print "no bootloader.img in target target_files; skipping install" tf = FindRadio(info.target_zip) if not tf: # failed to read TARGET radio image: don't include any radio in update. print "no radio.img in target target_files; skipping install" else: tf = common.File("radio.img", tf) sf = FindRadio(info.source_zip) if not sf: # failed to read SOURCE radio image: include the whole target # radio image. tf.AddToZip(info.output_zip) info.script.Print("Writing radio...") info.script.WriteRawImage("/radio", tf.name) else: sf = common.File("radio.img", sf) if tf.sha1 == sf.sha1: print "radio image unchanged; skipping" 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: # computing difference failed, or difference is nearly as # big as the target: simply send the target. tf.AddToZip(info.output_zip) info.script.Print("Writing radio...") info.script.WriteRawImage("radio", tf.name) else: common.ZipWriteStr(info.output_zip, "radio.img.p", d) info.script.Print("Patching radio...") radio_type, radio_device = common.GetTypeAndDevice( "/radio", info.info_dict) info.script.ApplyPatch( "%s:%s:%d:%s:%d:%s" % (radio_type, radio_device, sf.size, sf.sha1, tf.size, tf.sha1), "-", tf.size, tf.sha1, sf.sha1, "radio.img.p")
def LoadBootloaderFiles(tfpdir, extra_files=None, variant=None, base_variant=None): out = {} data = GetBootloaderImageFromTFP(tfpdir, extra_files=extra_files, variant=variant, base_variant=base_variant) image = common.File("bootloader.img", data).WriteToTemp() # Extract the contents of the VFAT bootloader image so we # can compute diffs on a per-file basis esp_root = tempfile.mkdtemp(prefix="bootloader-") common.OPTIONS.tempfiles.append(esp_root) add_dir_to_path("/sbin") subprocess.check_output(["mcopy", "-s", "-i", image.name, "::*", esp_root]) image.close() for dpath, dname, fnames in os.walk(esp_root): for fname in fnames: # Capsule update file -- gets consumed and deleted by the firmware # at first boot, shouldn't try to patch it if (fname == "BIOSUPDATE.fv"): continue abspath = os.path.join(dpath, fname) relpath = os.path.relpath(abspath, esp_root) data = open(abspath).read() out[relpath] = common.File("bootloader/" + relpath, data) return out
def IncrementalOTA_InstallEnd(info): try: target_bootloader_img = info.target_zip.read("RADIO/bootloader.img") try: source_bootloader_img = info.source_zip.read( "RADIO/bootloader.img") except KeyError: source_bootloader_img = None if source_bootloader_img == target_bootloader_img: print "bootloader unchanged; skipping" else: WriteBootloader(info, target_bootloader_img) except KeyError: print "no bootloader.img in target target_files; skipping install" tf = FindRadio(info.target_zip) if not tf: # failed to read TARGET radio image: don't include any radio in update. print "no radio.img in target target_files; skipping install" # we have checked the existence of the radio image in # IncrementalOTA_VerifyEnd(), so it won't reach here. assert common.OPTIONS.full_radio == False else: tf = common.File("radio.img", tf) sf = FindRadio(info.source_zip) if not sf or common.OPTIONS.full_radio: # failed to read SOURCE radio image or one has specified the option to # include the whole target radio image. print( "no radio image in source target_files or full_radio specified; " "installing complete image") WriteRadio(info, tf.data) else: sf = common.File("radio.img", sf) if tf.sha1 == sf.sha1: print "radio image unchanged; skipping" else: diff = common.Difference(tf, sf, diff_program="bsdiff") common.ComputeDifferences([diff]) _, _, d = diff.GetPatch() if d is None or len( d) > tf.size * common.OPTIONS.patch_threshold: # computing difference failed, or difference is nearly as # big as the target: simply send the target. WriteRadio(info, tf.data) else: common.ZipWriteStr(info.output_zip, "radio.img.p", d) info.script.Print("Patching radio...") radio_type, radio_device = common.GetTypeAndDevice( "/radio", info.info_dict) info.script.ApplyPatch( "%s:%s:%d:%s:%d:%s" % (radio_type, radio_device, sf.size, sf.sha1, tf.size, tf.sha1), "-", tf.size, tf.sha1, sf.sha1, "radio.img.p")
def test_full_recovery(self): recovery_image = common.File("recovery.img", self.recovery_data) boot_image = common.File("boot.img", self.boot_data) self._info["full_recovery_image"] = "true" common.MakeRecoveryPatch(self._tempdir, self._out_tmp_sink, recovery_image, boot_image, self._info) validate_target_files.ValidateInstallRecoveryScript( self._tempdir, self._info)
def _unpack(self, data): """ Unpack the data blob as a motoboot image and return the list of contained image objects""" num_imgs_fmt = "<L" num_imgs_size = struct.calcsize(num_imgs_fmt) num_imgs, = struct.unpack(num_imgs_fmt, data[:num_imgs_size]) img_info_format = "<24sLL" img_info_size = struct.calcsize(img_info_format) imgs = [ struct.unpack( img_info_format, data[num_imgs_size + i * img_info_size:num_imgs_size + (i + 1) * img_info_size]) for i in range(num_imgs) ] magic_format = "<8s" magic_size = struct.calcsize(magic_format) magic, = struct.unpack( magic_format, data[num_imgs_size + NUM_MAX_IMAGES * img_info_size:num_imgs_size + NUM_MAX_IMAGES * img_info_size + magic_size]) if magic != MAGIC: raise BadMagicError img_objs = [] for name, start, end in imgs: start_offset = HEADER_SIZE + start * SECTOR_SIZE end_offset = HEADER_SIZE + (end + 1) * SECTOR_SIZE - 1 img = common.File(trunc_to_null(name), data[start_offset:end_offset + 1]) img_objs.append(img) self.unpacked_images = img_objs
def CheckAllFiles(which): logging.info('Checking %s image.', which) image = _GetImage(which, input_tmp) prefix = '/' + which for entry in image.file_map: if not entry.startswith(prefix): continue # Read the blocks that the file resides. Note that it will contain the # bytes past the file length, which is expected to be padded with '\0's. ranges = image.file_map[entry] blocks_sha1 = image.RangeSha1(ranges) # The filename under unpacked directory, such as SYSTEM/bin/sh. unpacked_name = os.path.join( input_tmp, which.upper(), entry[(len(prefix) + 1):]) with open(unpacked_name) as f: file_data = f.read() file_size = len(file_data) file_size_rounded_up = RoundUpTo4K(file_size) file_data += '\0' * (file_size_rounded_up - file_size) file_sha1 = common.File(entry, file_data).sha1 assert blocks_sha1 == file_sha1, \ 'file: %s, range: %s, blocks_sha1: %s, file_sha1: %s' % ( entry, ranges, blocks_sha1, file_sha1)
def _unpack(self, data): """Unpack the data blob as a Huawei boot image and return the list of contained image objects""" num_imgs_fmt = struct.Struct("<IHH64sHH") header = data[0:num_imgs_fmt.size] info = {} (info["magic"], info["major_version"], info["minor_version"], info["img_version"], info["meta_hdr_size"], info["img_hdr_size"]) = num_imgs_fmt.unpack(header) img_info_format = "<72sLL" img_info_size = struct.calcsize(img_info_format) num = info["img_hdr_size"] / img_info_size size = num_imgs_fmt.size imgs = [ struct.unpack( img_info_format, data[size + i * img_info_size:size + (i + 1) * img_info_size]) for i in range(num) ] if info["magic"] != MAGIC: raise BadMagicError img_objs = {} for name, start, end in imgs: if TruncToNull(name): img = common.File(TruncToNull(name), data[start:start + end]) img_objs[img.name] = img self.unpacked_images = img_objs
def __init__(self, partition, file_name, input_dir, bootable=False, subdir=None): self.partition = partition self.file_name = file_name if file_name is None or input_dir is None: if PartitionUpdater.IfNeedImageFile(partition.mount_point): raise common.ExternalError("init PartitionFile error") return self.full_name = os.path.join(input_dir, file_name) if os.path.exists(self.full_name): file_data = open(self.full_name).read() if OPTIONS.secure_boot: if partition.secureboot: file_data = common.DoSprdSign(partition.secureboot, file_name, file_data, partition.mount_point) self.bin = common.File(file_name, file_data) self.size = len(file_data) else: print("[Warning:] no image file %s" % (self.full_name)) self.bin = None self.size = 0
def test_recovery_from_boot(self): recovery_image = common.File("recovery.img", self.recovery_data) self._out_tmp_sink("recovery.img", recovery_image.data, "IMAGES") boot_image = common.File("boot.img", self.boot_data) self._out_tmp_sink("boot.img", boot_image.data, "IMAGES") common.MakeRecoveryPatch(self._tempdir, self._out_tmp_sink, recovery_image, boot_image, self._info) validate_target_files.ValidateInstallRecoveryScript( self._tempdir, self._info) # Validate 'recovery-from-boot' with bonus argument. self._out_tmp_sink("etc/recovery-resource.dat", "bonus", "SYSTEM") common.MakeRecoveryPatch(self._tempdir, self._out_tmp_sink, recovery_image, boot_image, self._info) validate_target_files.ValidateInstallRecoveryScript( self._tempdir, self._info)
def IncrementalOTA_InstallEnd(info): try: target_bootloader_img = info.target_zip.read("RADIO/bootloader.img") try: source_bootloader_img = info.source_zip.read( "RADIO/bootloader.img") except KeyError: source_bootloader_img = None if source_bootloader_img == target_bootloader_img: print "bootloader unchanged; skipping" elif source_bootloader_img == None: print "no bootloader.img in source target_files; installing complete image" WriteBootloader(info, target_bootloader_img) else: tf = common.File("bootloader.img", target_bootloader_img) sf = common.File("bootloader.img", source_bootloader_img) WriteIncrementalBootloader(info, tf, sf) except KeyError: print "no bootloader.img in target target_files; skipping install" tf = FindRadio(info.target_zip) if not tf: # failed to read TARGET radio image: don't include any radio in update. print "no radio.img in target target_files; skipping install" # we have checked the existence of the radio image in # IncrementalOTA_VerifyEnd(), so it won't reach here. assert common.OPTIONS.full_radio == False else: tf = common.File("radio.img", tf) sf = FindRadio(info.source_zip) if not sf or common.OPTIONS.full_radio: # failed to read SOURCE radio image or one has specified the option to # include the whole target radio image. print( "no radio image in source target_files or full_radio specified; " "installing complete image") WriteRadio(info, tf.data) else: sf = common.File("radio.img", sf) if tf.size == sf.size and tf.sha1 == sf.sha1: print "radio image unchanged; skipping" else: WriteIncrementalRadio(info, tf, sf)
def GetRadioFiles(z): out = {} for info in z.infolist(): f = info.filename if f.startswith("RADIO/") and (f.__len__() > len("RADIO/")): fn = f[6:] if fn.startswith("filesmap"): continue data = z.read(f) out[fn] = common.File(f, data) # This is to include vbmeta,dtbo images from IMAGES/ folder. if f.startswith("IMAGES/") and (f.__len__() > len("IMAGES/")): fn = f[7:] if (fn in target_files_IMAGES_list): data = z.read(f) out[fn] = common.File(f, data) return out
def _ReadFile(file_name, unpacked_name, round_up=False): """Constructs and returns a File object. Rounds up its size if needed.""" assert os.path.exists(unpacked_name) with open(unpacked_name, 'rb') as f: file_data = f.read() file_size = len(file_data) if round_up: file_size_rounded_up = common.RoundUpTo4K(file_size) file_data += b'\0' * (file_size_rounded_up - file_size) return common.File(file_name, file_data)
def IncrementalOTA_InstallEnd(info): tf = FindRadio(info.target_zip) if not tf: # failed to read TARGET radio image: don't include any radio in update. print "no radio.img in target target_files; skipping install" else: tf = common.File("uboot.bin", tf) sf = FindRadio(info.source_zip) if not sf: # failed to read SOURCE radio image: include the whole target # radio image. WriteRadio(info, tf.data) else: sf = common.File("uboot.bin", sf) if tf.sha1 == sf.sha1: print "u-boot-with-spl-mbr-gpt.bin unchanged; skipping" else: diff = common.Difference(tf, sf, diff_program="bsdiff") common.ComputeDifferences([diff]) _, _, d = diff.GetPatch() if d is None or len( d) > tf.size * common.OPTIONS.patch_threshold: # computing difference failed, or difference is nearly as # big as the target: simply send the target. WriteRadio(info, tf.data) else: common.ZipWriteStr(info.output_zip, "u-boot-with-spl-mbr-gpt.bin.p", d) info.script.Print("Patching uboot...") uboot_type, uboot_device = common.GetTypeAndDevice( "/uboot", info.info_dict) info.script.PatchCheck("%s:%s:%d:%s:%d:%s" % (uboot_type, uboot_device, sf.size, sf.sha1, tf.size, tf.sha1)) info.script.ApplyPatch( "%s:%s:%d:%s:%d:%s" % (uboot_type, uboot_device, sf.size, sf.sha1, tf.size, tf.sha1), "-", tf.size, tf.sha1, sf.sha1, "u-boot-with-spl-mbr-gpt.bin.p")
def ComputeBinOrImgPatches(source_tfp_dir, target_tfp_dir, filename=None, variant=None, existing_ota_zip=None): patch_list = [] verbatim = None output_files = None if filename is None: print("Error input, no filename ") return [None, None, None] source_loader_filepath = os.path.join(source_tfp_dir, "RADIO", filename) if not os.path.exists(source_loader_filepath): print("Source:Can't find ", source_loader_filepath) return [None, None, None] source_loader_file = open(source_loader_filepath) source_loader_data = source_loader_file.read() source_loader_file.close() target_loader_filepath = os.path.join(target_tfp_dir, "RADIO", filename) if not os.path.exists(target_loader_filepath): print("Target Can't find ", target_loader_filepath) return [None, None, None] target_loader_file = open(target_loader_filepath) target_loader_data = target_loader_file.read() target_loader_file.close() src_bin = common.File(filename, source_loader_data) tgt_bin = common.File(filename, target_loader_data) diffs = [common.Difference(tgt_bin, src_bin)] common.ComputeDifferences(diffs) tf, sf, d = diffs[0].GetPatch() verbatim = False # If the patch size is almost as big as the actual file # the image will be included in the OTA verbatim. if d is None or len(d) > tf.size * 0.95: print(filename, "update will be included verbatim") verbatim = True else: patch_list = (tf,sf) output_files = d return verbatim, patch_list, output_files
def GetRadioFiles(z): out = {} for info in z.infolist(): f = info.filename if f.startswith("RADIO/") and (f.__len__() > len("RADIO/")): fn = f[6:] if fn.startswith("filesmap"): continue data = z.read(f) out[fn] = common.File(f, data) return out
def LoadSystemFiles(z): """Load all the files from SYSTEM/... in a given target-files ZipFile, and return a dict of {filename: File object}.""" out = {} for info in z.infolist(): if info.filename.startswith("SYSTEM/") and not IsSymlink(info): basefilename = info.filename[7:] fn = "system/" + basefilename data = z.read(info.filename) out[fn] = common.File(fn, data) return out
def IncrementalOTA_InstallEnd(info): try: target_bootloader_img = info.target_zip.read("RADIO/bootloader.img") try: source_bootloader_img = info.source_zip.read( "RADIO/bootloader.img") except KeyError: source_bootloader_img = None if source_bootloader_img == target_bootloader_img: print "bootloader unchanged; skipping" elif source_bootloader_img == None: print "no bootloader in source target_files; installing complete image" WriteBootloader(info, target_bootloader_img) else: tf = common.File("bootloader.img", target_bootloader_img) sf = common.File("bootloader.img", source_bootloader_img) WriteIncrementalBootloader(info, tf, sf) except KeyError: print "no bootloader.img in target target_files; skipping install" target_radio_image = FindRadio(info.target_zip) if not target_radio_image: # failed to read TARGET radio image: don't include any radio in update. print "no radio.img in target target_files; skipping install" else: tf = common.File("radio.img", target_radio_image) source_radio_image = FindRadio(info.source_zip) if not source_radio_image: # failed to read SOURCE radio image: include the whole target # radio image. print "no radio image in source target_files; installing complete image" WriteRadio(info, tf.data) else: sf = common.File("radio.img", source_radio_image) if tf.size == sf.size and tf.sha1 == sf.sha1: print "radio image unchanged; skipping" else: WriteIncrementalRadio(info, tf, sf)
def ComputeBootloaderPatch(source_tfp_dir, target_tfp_dir, variant=None, base_variant=None, existing_ota_zip=None): target_data = LoadBootloaderFiles(target_tfp_dir, variant=variant, base_variant=base_variant) source_data = LoadBootloaderFiles(source_tfp_dir, variant=variant, base_variant=base_variant) diffs = [] # List of files that will be included in the OTA verbatim because # they are either new or the patch is > 95% in size of the original # file. If this isn't empty you just need to call edify generator # UnpackPackageDir("bootloader", "/bootloader") verbatim_targets = [] # Returned list of common.File objects that need to be added to # the OTA archive, for each one call AddToZip() output_files = [] # Returned list of patches to be created. # Each element is a tuple of the form (path, target File object, # source File object, target file size) patch_list = [] for fn in sorted(target_data.keys()): filepath = os.path.join('bootloader', fn) if existing_ota_zip and patch_or_verbatim_exists(filepath, existing_ota_zip): continue tf = target_data[fn] sf = source_data.get(fn, None) if sf is None: verbatim_targets.append(fn) output_files.append(tf) elif tf.sha1 != sf.sha1: diffs.append(common.Difference(tf, sf)) common.ComputeDifferences(diffs) for diff in diffs: tf, sf, d = diff.GetPatch() if d is None or len(d) > tf.size * 0.95: output_files.append(tf) verbatim_targets.append(tf.name) else: output_files.append(common.File("patch/" + tf.name + ".p", d)) patch_list.append((tf, sf)) # output list of files that need to be deleted, pass this to # edify generator DeleteFiles in InstallEnd delete_files = ["/bootloader/"+i for i in sorted(source_data) if i not in target_data] return (output_files, delete_files, patch_list, verbatim_targets)
def IncrementalOTA_ImageCheck(info, name): source_image = False target_image = False updating_image = False image_path = name.upper() + "/" + name image_name = name + ".img" if HasTargetImage(info.source_zip, image_path): source_image = common.File(image_name, info.source_zip.read(image_path)) if HasTargetImage(info.target_zip, image_path): target_image = common.File(image_name, info.target_zip.read(image_path)) if target_image: if source_image: updating_image = (source_image.data != target_image.data) else: updating_image = 1 if updating_image: message_process = "install " + name + " image..." info.script.Print(message_process) common.ZipWriteStr(info.output_zip, image_name, target_image.data) if name == "dtb": info.script.WriteDtbImage(image_name) else: if name == "bootloader": info.script.WriteBootloaderImage("/" + name, image_name) else: info.script.WriteRawImage("/" + name, image_name) if name == "bootloader": if updating_image: SetBootloaderEnv(info.script, "upgrade_step", "1") else: SetBootloaderEnv(info.script, "upgrade_step", "2")
def IncrementalOTA_InstallEnd(info): print "amlogic extensions:IncrementalOTA_InstallEnd" source_bootloader = False target_bootloader = False updating_bootloader = False if HasTargetImage(info.source_zip, "BOOTLOADER/bootloader"): source_bootloader = common.File( "bootloader.img", info.source_zip.read("BOOTLOADER/bootloader")) if HasTargetImage(info.target_zip, "BOOTLOADER/bootloader"): target_bootloader = common.File( "bootloader.img", info.target_zip.read("BOOTLOADER/bootloader")) if target_bootloader: if source_bootloader: updating_bootloader = (source_bootloader.data != target_bootloader.data) else: updating_bootloader = 1 if updating_bootloader: SetBootloaderEnv(info.script, "upgrade_step", "1")
def FindImage(zipfile, basename): matches = [] for name in zipfile.namelist(): m = re.match(r"^RADIO/(" + basename + "[.](.+[.])?img)$", name) if m: matches.append((name, m.group(1))) if len(matches) > 1: raise ValueError("multiple radio images in target-files zip!") if matches: matches = matches[0] print "using %s as %s" % matches return common.File(matches[1], zipfile.read(matches[0])) else: return None
def _CalculateFileSha1(file_name, unpacked_name, round_up=False): """Calculate the SHA-1 for a given file. Round up its size to 4K if needed.""" def RoundUpTo4K(value): rounded_up = value + 4095 return rounded_up - (rounded_up % 4096) assert os.path.exists(unpacked_name) with open(unpacked_name, 'r') as f: file_data = f.read() file_size = len(file_data) if round_up: file_size_rounded_up = RoundUpTo4K(file_size) file_data += '\0' * (file_size_rounded_up - file_size) return common.File(file_name, file_data).sha1
def FullOTA_InstallEnd(info): print "amlogic extensions:FullOTA_InstallEnd" bootloader_img_exist = 0 try: bootloader_img_info = info.input_zip.getinfo("BOOTLOADER/bootloader") bootloader_img_exist = 1 bootloader_img = common.File("bootloader.img", info.input_zip.read("BOOTLOADER/bootloader")); except KeyError: print 'WARNING: No BOOTLOADER found' if bootloader_img_exist: common.CheckSize(bootloader_img.data, "bootloader.img", info.info_dict) common.ZipWriteStr(info.output_zip, "bootloader.img", bootloader_img.data) info.script.WriteRawImage("/bootloader", "bootloader.img") SetBootloaderEnv(info.script, "upgrade_step", "1") else: SetBootloaderEnv(info.script, "upgrade_step", "1") SetBootloaderEnv(info.script, "force_auto_update", "false")
def get_file_data(tmpdir, path): provdata_name = os.path.join(tmpdir, "RADIO", "provdata.zip") with zipfile.ZipFile(provdata_name) as provdata_zip: data = provdata_zip.read(path) return common.File(path, data)
def get_image(archive, name): try: ret = common.File(name, archive.read(name)) except KeyError: ret = None return ret
def GetFastbootImage(unpack_dir, info_dict=None): """Return a File object 'fastboot.img' with the Fastboot boot image. It will either be fetched from RADIO/fastboot.img or built using RADIO/ufb_ramdisk.zip, RADIO/ufb_cmdline, and BOOT/kernel""" if info_dict is None: info_dict = common.OPTIONS.info_dict prebuilt_path = os.path.join(unpack_dir, "RADIO", "fastboot.img") if (os.path.exists(prebuilt_path)): print "using prebuilt fastboot.img" return common.File.FromLocalFile("fastboot.img", prebuilt_path) ramdisk_path = os.path.join(unpack_dir, "RADIO", "ufb-ramdisk.zip") if not os.path.exists(ramdisk_path): print "no user fastboot image found, assuming efi fastboot" return None print "building Fastboot image from target_files..." ramdisk_img = tempfile.NamedTemporaryFile() img = tempfile.NamedTemporaryFile() ramdisk_tmp, ramdisk_zip = common.UnzipTemp(ramdisk_path) cmd1 = ["mkbootfs", ramdisk_tmp] try: p1 = common.Run(cmd1, stdout=subprocess.PIPE) except Exception as exc: print "Error: Unable to execute command: {}".format(' '.join(cmd1)) shutil.rmtree(ramdisk_tmp) raise exc cmd2 = ["minigzip"] try: p2 = common.Run(cmd2, stdin=p1.stdout, stdout=ramdisk_img.file.fileno()) except Exception as exc: print "Error: Unable to execute command: {}".format(' '.join(cmd2)) shutil.rmtree(ramdisk_tmp) raise exc p1.stdout.close() p2.communicate() p1.wait() assert p1.returncode == 0, "mkbootfs of fastboot ramdisk failed" assert p2.returncode == 0, "minigzip of fastboot ramdisk failed" # use MKBOOTIMG from environ, or "mkbootimg" if empty or not set mkbootimg = os.getenv('MKBOOTIMG') or "mkbootimg" cmd = [mkbootimg, "--kernel", os.path.join(unpack_dir, "BOOT", "kernel")] fn = os.path.join(unpack_dir, "RADIO", "ufb-cmdline") if os.access(fn, os.F_OK): cmd.append("--cmdline") cmd.append(open(fn).read().rstrip("\n")) # Add 2nd-stage loader, if it exists fn = os.path.join(unpack_dir, "RADIO", "ufb-second") if os.access(fn, os.F_OK): cmd.append("--second") cmd.append(fn) args = info_dict.get("mkbootimg_args", None) if args and args.strip(): cmd.extend(shlex.split(args)) cmd.extend(["--ramdisk", ramdisk_img.name, "--output", img.name]) try: p = common.Run(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE) except Exception as exc: print "Error: Unable to execute command: {}".format(' '.join(cmd)) raise exc p.communicate() assert p.returncode == 0, "mkbootimg of fastboot image failed" # Sign the image using BOOT_SIGNER env variable, or "boot_signer" command signing_key = info_dict.get("verity_key") if info_dict.get("verity") == "true" and signing_key: boot_signer = os.getenv('BOOT_SIGNER') or "boot_signer" cmd = [ boot_signer, "/fastboot", img.name, signing_key + common.OPTIONS.private_key_suffix, signing_key + common.OPTIONS.public_key_suffix, img.name ] try: p = common.Run(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE) except Exception as exc: print "Error: Unable to execute command: {}".format(' '.join(cmd)) raise exc p.communicate() assert p.returncode == 0, "boot signing of fastboot image failed" img.seek(os.SEEK_SET, 0) data = img.read() ramdisk_img.close() img.close() return common.File("fastboot.img", data)
def GetTdosImage(unpack_dir, info_dict=None): if info_dict is None: info_dict = common.OPTIONS.info_dict prebuilt_path = os.path.join(unpack_dir, "RADIO", "tdos.img") if (os.path.exists(prebuilt_path)): print "using prebuilt tdos.img" return common.File.FromLocalFile("tdos.img", prebuilt_path) ramdisk_path = os.path.join(unpack_dir, "RADIO", "ramdisk-tdos.img") if not os.path.exists(ramdisk_path): print "no TDOS ramdisk found" return None print "building TDOS image from target_files..." ramdisk_img = tempfile.NamedTemporaryFile() img = tempfile.NamedTemporaryFile() # use MKBOOTIMG from environ, or "mkbootimg" if empty or not set mkbootimg = os.getenv('MKBOOTIMG') or "mkbootimg" cmd = [mkbootimg, "--kernel", os.path.join(unpack_dir, "BOOT", "kernel")] fn = os.path.join(unpack_dir, "BOOT", "cmdline") if os.access(fn, os.F_OK): cmd.append("--cmdline") cmd.append(open(fn).read().rstrip("\n")) # Add 2nd-stage loader, if it exists fn = os.path.join(unpack_dir, "BOOT", "second") if os.access(fn, os.F_OK): cmd.append("--second") cmd.append(fn) args = info_dict.get("mkbootimg_args", None) if args and args.strip(): cmd.extend(shlex.split(args)) cmd.extend(["--ramdisk", ramdisk_path, "--output", img.name]) try: p = common.Run(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE) except Exception as exc: print "Error: Unable to execute command: {}".format(' '.join(cmd)) raise exc p.communicate() assert p.returncode == 0, "mkbootimg of fastboot image failed" # Sign the image using BOOT_SIGNER env variable, or "boot_signer" command signing_key = info_dict.get("verity_key") if info_dict.get("verity") == "true" and signing_key: boot_signer = os.getenv('BOOT_SIGNER') or "boot_signer" cmd = [ boot_signer, "/tdos", img.name, signing_key + common.OPTIONS.private_key_suffix, signing_key + common.OPTIONS.public_key_suffix, img.name ] try: p = common.Run(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE) except Exception as exc: print "Error: Unable to execute command: {}".format(' '.join(cmd)) raise exc p.communicate() assert p.returncode == 0, "boot signing of tdos image failed" img.seek(os.SEEK_SET, 0) data = img.read() img.close() return common.File("tdos.img", data)