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")
Example #3
0
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
Example #4
0
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
Example #6
0
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")
Example #7
0
    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)
Example #8
0
    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
Example #9
0
  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
Example #11
0
    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
Example #12
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)
Example #13
0
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")
Example #17
0
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
Example #18
0
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
Example #19
0
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)
Example #21
0
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")
Example #23
0
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")
Example #24
0
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")
Example #27
0
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)
Example #28
0
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)