Loading tools/releasetools/add_img_to_target_files.py +8 −0 Original line number Diff line number Diff line Loading @@ -371,6 +371,14 @@ def AddImagesToTargetFiles(filename): if recovery_image: recovery_image.AddToZip(output_zip) banner("recovery (two-step image)") # The special recovery.img for two-step package use. recovery_two_step_image = common.GetBootableImage( "IMAGES/recovery-two-step.img", "recovery-two-step.img", OPTIONS.input_tmp, "RECOVERY", two_step_image=True) if recovery_two_step_image: recovery_two_step_image.AddToZip(output_zip) banner("system") system_imgname = AddSystem(output_zip, recovery_img=recovery_image, boot_img=boot_image) Loading tools/releasetools/common.py +16 −7 Original line number Diff line number Diff line Loading @@ -401,13 +401,17 @@ def DumpInfoDict(d): def _BuildBootableImage(sourcedir, fs_config_file, info_dict=None, has_ramdisk=False): has_ramdisk=False, two_step_image=False): """Build a bootable image from the specified sourcedir. Take a kernel, cmdline, and optionally a ramdisk directory from the input (in 'sourcedir'), and turn them into a boot image. Return the image data, or None if sourcedir does not appear to contains files for building the requested image.""" 'sourcedir'), and turn them into a boot image. 'two_step_image' indicates if we are building a two-step special image (i.e. building a recovery image to be loaded into /boot in two-step OTAs). Return the image data, or None if sourcedir does not appear to contains files for building the requested image. """ def make_ramdisk(): ramdisk_img = tempfile.NamedTemporaryFile() Loading Loading @@ -491,6 +495,11 @@ def _BuildBootableImage(sourcedir, fs_config_file, info_dict=None, if (info_dict.get("boot_signer", None) == "true" and info_dict.get("verity_key", None)): # Hard-code the path as "/boot" for two-step special recovery image (which # will be loaded into /boot during the two-step OTA). if two_step_image: path = "/boot" else: path = "/" + os.path.basename(sourcedir).lower() cmd = [OPTIONS.boot_signer_path] cmd.extend(OPTIONS.boot_signer_args) Loading Loading @@ -530,7 +539,7 @@ def _BuildBootableImage(sourcedir, fs_config_file, info_dict=None, def GetBootableImage(name, prebuilt_name, unpack_dir, tree_subdir, info_dict=None): info_dict=None, two_step_image=False): """Return a File object with the desired bootable image. Look for it in 'unpack_dir'/BOOTABLE_IMAGES under the name 'prebuilt_name', Loading Loading @@ -562,7 +571,7 @@ def GetBootableImage(name, prebuilt_name, unpack_dir, tree_subdir, fs_config = "META/" + tree_subdir.lower() + "_filesystem_config.txt" data = _BuildBootableImage(os.path.join(unpack_dir, tree_subdir), os.path.join(unpack_dir, fs_config), info_dict, has_ramdisk) info_dict, has_ramdisk, two_step_image) if data: return File(name, data) return None Loading tools/releasetools/img_from_target_files.py +2 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,8 @@ def main(argv): continue if not image.endswith(".img"): continue if image == "recovery-two-step.img": continue common.ZipWrite( output_zip, os.path.join(images_path, image), image) done = True Loading tools/releasetools/ota_from_target_files.py +68 −3 Original line number Diff line number Diff line Loading @@ -467,6 +467,39 @@ def AppendAssertions(script, info_dict, oem_dict=None): script.AssertOemProperty(prop, oem_dict.get(prop)) def _WriteRecoveryImageToBoot(script, output_zip): """Find and write recovery image to /boot in two-step OTA. In two-step OTAs, we write recovery image to /boot as the first step so that we can reboot to there and install a new recovery image to /recovery. A special "recovery-two-step.img" will be preferred, which encodes the correct path of "/boot". Otherwise the device may show "device is corrupt" message when booting into /boot. Fall back to using the regular recovery.img if the two-step recovery image doesn't exist. Note that rebuilding the special image at this point may be infeasible, because we don't have the desired boot signer and keys when calling ota_from_target_files.py. """ recovery_two_step_img_name = "recovery-two-step.img" recovery_two_step_img_path = os.path.join( OPTIONS.input_tmp, "IMAGES", recovery_two_step_img_name) if os.path.exists(recovery_two_step_img_path): recovery_two_step_img = common.GetBootableImage( recovery_two_step_img_name, recovery_two_step_img_name, OPTIONS.input_tmp, "RECOVERY") common.ZipWriteStr( output_zip, recovery_two_step_img_name, recovery_two_step_img.data) print "two-step package: using %s in stage 1/3" % ( recovery_two_step_img_name,) script.WriteRawImage("/boot", recovery_two_step_img_name) else: print "two-step package: using recovery.img in stage 1/3" # The "recovery.img" entry has been written into package earlier. script.WriteRawImage("/boot", "recovery.img") def HasRecoveryPatch(target_files_zip): namelist = [name for name in target_files_zip.namelist()] return ("SYSTEM/recovery-from-boot.p" in namelist or Loading Loading @@ -616,6 +649,9 @@ def WriteFullOTAPackage(input_zip, output_zip): script.AppendExtra(""" if get_stage("%(bcb_dev)s") == "2/3" then """ % bcb_dev) # Stage 2/3: Write recovery image to /recovery (currently running /boot). script.Comment("Stage 2/3") script.WriteRawImage("/recovery", "recovery.img") script.AppendExtra(""" set_stage("%(bcb_dev)s", "3/3"); Loading @@ -623,6 +659,9 @@ reboot_now("%(bcb_dev)s", "recovery"); else if get_stage("%(bcb_dev)s") == "3/3" then """ % bcb_dev) # Stage 3/3: Make changes. script.Comment("Stage 3/3") # Dump fingerprints script.Print("Target: %s" % CalculateFingerprint( oem_props, oem_dict, OPTIONS.info_dict)) Loading Loading @@ -722,7 +761,11 @@ else if get_stage("%(bcb_dev)s") == "3/3" then set_stage("%(bcb_dev)s", ""); """ % bcb_dev) script.AppendExtra("else\n") script.WriteRawImage("/boot", "recovery.img") # Stage 1/3: Nothing to verify for full OTA. Write recovery image to /boot. script.Comment("Stage 1/3") _WriteRecoveryImageToBoot(script, output_zip) script.AppendExtra(""" set_stage("%(bcb_dev)s", "2/3"); reboot_now("%(bcb_dev)s", ""); Loading Loading @@ -945,6 +988,9 @@ def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_zip): script.AppendExtra(""" if get_stage("%(bcb_dev)s") == "2/3" then """ % bcb_dev) # Stage 2/3: Write recovery image to /recovery (currently running /boot). script.Comment("Stage 2/3") script.AppendExtra("sleep(20);\n") script.WriteRawImage("/recovery", "recovery.img") script.AppendExtra(""" Loading @@ -953,6 +999,9 @@ reboot_now("%(bcb_dev)s", "recovery"); else if get_stage("%(bcb_dev)s") != "3/3" then """ % bcb_dev) # Stage 1/3: (a) Verify the current system. script.Comment("Stage 1/3") # Dump fingerprints script.Print("Source: %s" % CalculateFingerprint( oem_props, oem_dict, OPTIONS.source_info_dict)) Loading Loading @@ -1016,13 +1065,18 @@ else if get_stage("%(bcb_dev)s") != "3/3" then device_specific.IncrementalOTA_VerifyEnd() if OPTIONS.two_step: script.WriteRawImage("/boot", "recovery.img") # Stage 1/3: (b) Write recovery image to /boot. _WriteRecoveryImageToBoot(script, output_zip) script.AppendExtra(""" set_stage("%(bcb_dev)s", "2/3"); reboot_now("%(bcb_dev)s", ""); else """ % bcb_dev) # Stage 3/3: Make changes. script.Comment("Stage 3/3") # Verify the existing partitions. system_diff.WriteVerifyScript(script, touched_blocks_only=True) if vendor_diff: Loading Loading @@ -1616,6 +1670,9 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip): script.AppendExtra(""" if get_stage("%(bcb_dev)s") == "2/3" then """ % bcb_dev) # Stage 2/3: Write recovery image to /recovery (currently running /boot). script.Comment("Stage 2/3") script.AppendExtra("sleep(20);\n") script.WriteRawImage("/recovery", "recovery.img") script.AppendExtra(""" Loading @@ -1624,6 +1681,9 @@ reboot_now("%(bcb_dev)s", "recovery"); else if get_stage("%(bcb_dev)s") != "3/3" then """ % bcb_dev) # Stage 1/3: (a) Verify the current system. script.Comment("Stage 1/3") # Dump fingerprints script.Print("Source: %s" % (source_fp,)) script.Print("Target: %s" % (target_fp,)) Loading Loading @@ -1668,13 +1728,18 @@ else if get_stage("%(bcb_dev)s") != "3/3" then device_specific.IncrementalOTA_VerifyEnd() if OPTIONS.two_step: script.WriteRawImage("/boot", "recovery.img") # Stage 1/3: (b) Write recovery image to /boot. _WriteRecoveryImageToBoot(script, output_zip) script.AppendExtra(""" set_stage("%(bcb_dev)s", "2/3"); reboot_now("%(bcb_dev)s", ""); else """ % bcb_dev) # Stage 3/3: Make changes. script.Comment("Stage 3/3") script.Comment("---- start making changes here ----") device_specific.IncrementalOTA_InstallBegin() Loading Loading
tools/releasetools/add_img_to_target_files.py +8 −0 Original line number Diff line number Diff line Loading @@ -371,6 +371,14 @@ def AddImagesToTargetFiles(filename): if recovery_image: recovery_image.AddToZip(output_zip) banner("recovery (two-step image)") # The special recovery.img for two-step package use. recovery_two_step_image = common.GetBootableImage( "IMAGES/recovery-two-step.img", "recovery-two-step.img", OPTIONS.input_tmp, "RECOVERY", two_step_image=True) if recovery_two_step_image: recovery_two_step_image.AddToZip(output_zip) banner("system") system_imgname = AddSystem(output_zip, recovery_img=recovery_image, boot_img=boot_image) Loading
tools/releasetools/common.py +16 −7 Original line number Diff line number Diff line Loading @@ -401,13 +401,17 @@ def DumpInfoDict(d): def _BuildBootableImage(sourcedir, fs_config_file, info_dict=None, has_ramdisk=False): has_ramdisk=False, two_step_image=False): """Build a bootable image from the specified sourcedir. Take a kernel, cmdline, and optionally a ramdisk directory from the input (in 'sourcedir'), and turn them into a boot image. Return the image data, or None if sourcedir does not appear to contains files for building the requested image.""" 'sourcedir'), and turn them into a boot image. 'two_step_image' indicates if we are building a two-step special image (i.e. building a recovery image to be loaded into /boot in two-step OTAs). Return the image data, or None if sourcedir does not appear to contains files for building the requested image. """ def make_ramdisk(): ramdisk_img = tempfile.NamedTemporaryFile() Loading Loading @@ -491,6 +495,11 @@ def _BuildBootableImage(sourcedir, fs_config_file, info_dict=None, if (info_dict.get("boot_signer", None) == "true" and info_dict.get("verity_key", None)): # Hard-code the path as "/boot" for two-step special recovery image (which # will be loaded into /boot during the two-step OTA). if two_step_image: path = "/boot" else: path = "/" + os.path.basename(sourcedir).lower() cmd = [OPTIONS.boot_signer_path] cmd.extend(OPTIONS.boot_signer_args) Loading Loading @@ -530,7 +539,7 @@ def _BuildBootableImage(sourcedir, fs_config_file, info_dict=None, def GetBootableImage(name, prebuilt_name, unpack_dir, tree_subdir, info_dict=None): info_dict=None, two_step_image=False): """Return a File object with the desired bootable image. Look for it in 'unpack_dir'/BOOTABLE_IMAGES under the name 'prebuilt_name', Loading Loading @@ -562,7 +571,7 @@ def GetBootableImage(name, prebuilt_name, unpack_dir, tree_subdir, fs_config = "META/" + tree_subdir.lower() + "_filesystem_config.txt" data = _BuildBootableImage(os.path.join(unpack_dir, tree_subdir), os.path.join(unpack_dir, fs_config), info_dict, has_ramdisk) info_dict, has_ramdisk, two_step_image) if data: return File(name, data) return None Loading
tools/releasetools/img_from_target_files.py +2 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,8 @@ def main(argv): continue if not image.endswith(".img"): continue if image == "recovery-two-step.img": continue common.ZipWrite( output_zip, os.path.join(images_path, image), image) done = True Loading
tools/releasetools/ota_from_target_files.py +68 −3 Original line number Diff line number Diff line Loading @@ -467,6 +467,39 @@ def AppendAssertions(script, info_dict, oem_dict=None): script.AssertOemProperty(prop, oem_dict.get(prop)) def _WriteRecoveryImageToBoot(script, output_zip): """Find and write recovery image to /boot in two-step OTA. In two-step OTAs, we write recovery image to /boot as the first step so that we can reboot to there and install a new recovery image to /recovery. A special "recovery-two-step.img" will be preferred, which encodes the correct path of "/boot". Otherwise the device may show "device is corrupt" message when booting into /boot. Fall back to using the regular recovery.img if the two-step recovery image doesn't exist. Note that rebuilding the special image at this point may be infeasible, because we don't have the desired boot signer and keys when calling ota_from_target_files.py. """ recovery_two_step_img_name = "recovery-two-step.img" recovery_two_step_img_path = os.path.join( OPTIONS.input_tmp, "IMAGES", recovery_two_step_img_name) if os.path.exists(recovery_two_step_img_path): recovery_two_step_img = common.GetBootableImage( recovery_two_step_img_name, recovery_two_step_img_name, OPTIONS.input_tmp, "RECOVERY") common.ZipWriteStr( output_zip, recovery_two_step_img_name, recovery_two_step_img.data) print "two-step package: using %s in stage 1/3" % ( recovery_two_step_img_name,) script.WriteRawImage("/boot", recovery_two_step_img_name) else: print "two-step package: using recovery.img in stage 1/3" # The "recovery.img" entry has been written into package earlier. script.WriteRawImage("/boot", "recovery.img") def HasRecoveryPatch(target_files_zip): namelist = [name for name in target_files_zip.namelist()] return ("SYSTEM/recovery-from-boot.p" in namelist or Loading Loading @@ -616,6 +649,9 @@ def WriteFullOTAPackage(input_zip, output_zip): script.AppendExtra(""" if get_stage("%(bcb_dev)s") == "2/3" then """ % bcb_dev) # Stage 2/3: Write recovery image to /recovery (currently running /boot). script.Comment("Stage 2/3") script.WriteRawImage("/recovery", "recovery.img") script.AppendExtra(""" set_stage("%(bcb_dev)s", "3/3"); Loading @@ -623,6 +659,9 @@ reboot_now("%(bcb_dev)s", "recovery"); else if get_stage("%(bcb_dev)s") == "3/3" then """ % bcb_dev) # Stage 3/3: Make changes. script.Comment("Stage 3/3") # Dump fingerprints script.Print("Target: %s" % CalculateFingerprint( oem_props, oem_dict, OPTIONS.info_dict)) Loading Loading @@ -722,7 +761,11 @@ else if get_stage("%(bcb_dev)s") == "3/3" then set_stage("%(bcb_dev)s", ""); """ % bcb_dev) script.AppendExtra("else\n") script.WriteRawImage("/boot", "recovery.img") # Stage 1/3: Nothing to verify for full OTA. Write recovery image to /boot. script.Comment("Stage 1/3") _WriteRecoveryImageToBoot(script, output_zip) script.AppendExtra(""" set_stage("%(bcb_dev)s", "2/3"); reboot_now("%(bcb_dev)s", ""); Loading Loading @@ -945,6 +988,9 @@ def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_zip): script.AppendExtra(""" if get_stage("%(bcb_dev)s") == "2/3" then """ % bcb_dev) # Stage 2/3: Write recovery image to /recovery (currently running /boot). script.Comment("Stage 2/3") script.AppendExtra("sleep(20);\n") script.WriteRawImage("/recovery", "recovery.img") script.AppendExtra(""" Loading @@ -953,6 +999,9 @@ reboot_now("%(bcb_dev)s", "recovery"); else if get_stage("%(bcb_dev)s") != "3/3" then """ % bcb_dev) # Stage 1/3: (a) Verify the current system. script.Comment("Stage 1/3") # Dump fingerprints script.Print("Source: %s" % CalculateFingerprint( oem_props, oem_dict, OPTIONS.source_info_dict)) Loading Loading @@ -1016,13 +1065,18 @@ else if get_stage("%(bcb_dev)s") != "3/3" then device_specific.IncrementalOTA_VerifyEnd() if OPTIONS.two_step: script.WriteRawImage("/boot", "recovery.img") # Stage 1/3: (b) Write recovery image to /boot. _WriteRecoveryImageToBoot(script, output_zip) script.AppendExtra(""" set_stage("%(bcb_dev)s", "2/3"); reboot_now("%(bcb_dev)s", ""); else """ % bcb_dev) # Stage 3/3: Make changes. script.Comment("Stage 3/3") # Verify the existing partitions. system_diff.WriteVerifyScript(script, touched_blocks_only=True) if vendor_diff: Loading Loading @@ -1616,6 +1670,9 @@ def WriteIncrementalOTAPackage(target_zip, source_zip, output_zip): script.AppendExtra(""" if get_stage("%(bcb_dev)s") == "2/3" then """ % bcb_dev) # Stage 2/3: Write recovery image to /recovery (currently running /boot). script.Comment("Stage 2/3") script.AppendExtra("sleep(20);\n") script.WriteRawImage("/recovery", "recovery.img") script.AppendExtra(""" Loading @@ -1624,6 +1681,9 @@ reboot_now("%(bcb_dev)s", "recovery"); else if get_stage("%(bcb_dev)s") != "3/3" then """ % bcb_dev) # Stage 1/3: (a) Verify the current system. script.Comment("Stage 1/3") # Dump fingerprints script.Print("Source: %s" % (source_fp,)) script.Print("Target: %s" % (target_fp,)) Loading Loading @@ -1668,13 +1728,18 @@ else if get_stage("%(bcb_dev)s") != "3/3" then device_specific.IncrementalOTA_VerifyEnd() if OPTIONS.two_step: script.WriteRawImage("/boot", "recovery.img") # Stage 1/3: (b) Write recovery image to /boot. _WriteRecoveryImageToBoot(script, output_zip) script.AppendExtra(""" set_stage("%(bcb_dev)s", "2/3"); reboot_now("%(bcb_dev)s", ""); else """ % bcb_dev) # Stage 3/3: Make changes. script.Comment("Stage 3/3") script.Comment("---- start making changes here ----") device_specific.IncrementalOTA_InstallBegin() Loading