diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py index 03e66a4b1f..2fd6eeda55 100644 --- a/tools/releasetools/common.py +++ b/tools/releasetools/common.py @@ -205,7 +205,8 @@ def LoadInfoDict(input_file, input_dir=None): makeint("boot_size") makeint("fstab_version") - d["fstab"] = LoadRecoveryFSTab(read_helper, d["fstab_version"], d.get("system_root_image", False)) + d["fstab"] = LoadRecoveryFSTab(read_helper, d["fstab_version"], + d.get("system_root_image", False)) d["build.prop"] = LoadBuildProp(read_helper) return d @@ -321,7 +322,8 @@ def LoadRecoveryFSTab(read_helper, fstab_version, system_root_image=False): raise ValueError("Unknown fstab_version: \"%d\"" % (fstab_version,)) # / is used for the system mount point when the root directory is included in - # system. Other areas assume system is always at "/system" so point /system at / + # system. Other areas assume system is always at "/system" so point /system + # at /. if system_root_image: assert not d.has_key("/system") and d.has_key("/") d["/system"] = d["/"] @@ -333,34 +335,46 @@ def DumpInfoDict(d): print "%-25s = (%s) %s" % (k, type(v).__name__, v) -def BuildBootableImage(sourcedir, fs_config_file, info_dict=None): - """Take a kernel, cmdline, and 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.""" +def _BuildBootableImage(sourcedir, fs_config_file, info_dict=None, + has_ramdisk=False): + """Build a bootable image from the specified sourcedir. - if (not os.access(os.path.join(sourcedir, "RAMDISK"), os.F_OK) or - not os.access(os.path.join(sourcedir, "kernel"), os.F_OK)): + 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.""" + + def make_ramdisk(): + ramdisk_img = tempfile.NamedTemporaryFile() + + if os.access(fs_config_file, os.F_OK): + cmd = ["mkbootfs", "-f", fs_config_file, + os.path.join(sourcedir, "RAMDISK")] + else: + cmd = ["mkbootfs", os.path.join(sourcedir, "RAMDISK")] + p1 = Run(cmd, stdout=subprocess.PIPE) + p2 = Run(["minigzip"], stdin=p1.stdout, stdout=ramdisk_img.file.fileno()) + + p2.wait() + p1.wait() + assert p1.returncode == 0, "mkbootfs of %s ramdisk failed" % (sourcedir,) + assert p2.returncode == 0, "minigzip of %s ramdisk failed" % (sourcedir,) + + return ramdisk_img + + if not os.access(os.path.join(sourcedir, "kernel"), os.F_OK): + return None + + if has_ramdisk and not os.access(os.path.join(sourcedir, "RAMDISK"), os.F_OK): return None if info_dict is None: info_dict = OPTIONS.info_dict - ramdisk_img = tempfile.NamedTemporaryFile() img = tempfile.NamedTemporaryFile() - if os.access(fs_config_file, os.F_OK): - cmd = ["mkbootfs", "-f", fs_config_file, os.path.join(sourcedir, "RAMDISK")] - else: - cmd = ["mkbootfs", os.path.join(sourcedir, "RAMDISK")] - p1 = Run(cmd, stdout=subprocess.PIPE) - p2 = Run(["minigzip"], - stdin=p1.stdout, stdout=ramdisk_img.file.fileno()) - - p2.wait() - p1.wait() - assert p1.returncode == 0, "mkbootfs of %s ramdisk failed" % (sourcedir,) - assert p2.returncode == 0, "minigzip of %s ramdisk failed" % (sourcedir,) + if has_ramdisk: + ramdisk_img = make_ramdisk() # use MKBOOTIMG from environ, or "mkbootimg" if empty or not set mkbootimg = os.getenv('MKBOOTIMG') or "mkbootimg" @@ -391,14 +405,15 @@ def BuildBootableImage(sourcedir, fs_config_file, info_dict=None): if args and args.strip(): cmd.extend(shlex.split(args)) + if has_ramdisk: + cmd.extend(["--ramdisk", ramdisk_img.name]) + img_unsigned = None if info_dict.get("vboot", None): img_unsigned = tempfile.NamedTemporaryFile() - cmd.extend(["--ramdisk", ramdisk_img.name, - "--output", img_unsigned.name]) + cmd.extend(["--output", img_unsigned.name]) else: - cmd.extend(["--ramdisk", ramdisk_img.name, - "--output", img.name]) + cmd.extend(["--output", img.name]) p = Run(cmd, stdout=subprocess.PIPE) p.communicate() @@ -436,7 +451,8 @@ def BuildBootableImage(sourcedir, fs_config_file, info_dict=None): img.seek(os.SEEK_SET, 0) data = img.read() - ramdisk_img.close() + if has_ramdisk: + ramdisk_img.close() img.close() return data @@ -444,11 +460,11 @@ def BuildBootableImage(sourcedir, fs_config_file, info_dict=None): def GetBootableImage(name, prebuilt_name, unpack_dir, tree_subdir, info_dict=None): - """Return a File object (with name 'name') with the desired bootable - image. Look for it in 'unpack_dir'/BOOTABLE_IMAGES under the name - 'prebuilt_name', otherwise look for it under 'unpack_dir'/IMAGES, - otherwise construct it from the source files in - 'unpack_dir'/'tree_subdir'.""" + """Return a File object with the desired bootable image. + + Look for it in 'unpack_dir'/BOOTABLE_IMAGES under the name 'prebuilt_name', + otherwise look for it under 'unpack_dir'/IMAGES, otherwise construct it from + the source files in 'unpack_dir'/'tree_subdir'.""" prebuilt_path = os.path.join(unpack_dir, "BOOTABLE_IMAGES", prebuilt_name) if os.path.exists(prebuilt_path): @@ -461,10 +477,18 @@ def GetBootableImage(name, prebuilt_name, unpack_dir, tree_subdir, return File.FromLocalFile(name, prebuilt_path) print "building image from target_files %s..." % (tree_subdir,) + + if info_dict is None: + info_dict = OPTIONS.info_dict + + # With system_root_image == "true", we don't pack ramdisk into the boot image. + has_ramdisk = (info_dict.get("system_root_image", None) != "true" or + prebuilt_name != "boot.img") + 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) + data = _BuildBootableImage(os.path.join(unpack_dir, tree_subdir), + os.path.join(unpack_dir, fs_config), + info_dict, has_ramdisk) if data: return File(name, data) return None @@ -1414,6 +1438,7 @@ def MakeRecoveryPatch(input_dir, output_sink, recovery_img, boot_img, info_dict = OPTIONS.info_dict full_recovery_image = info_dict.get("full_recovery_image", None) == "true" + system_root_image = info_dict.get("system_root_image", None) == "true" if full_recovery_image: output_sink("etc/recovery.img", recovery_img.data) @@ -1471,7 +1496,10 @@ fi # target-files expects it to be, and put it there. sh_location = "etc/install-recovery.sh" found = False - init_rc_dir = os.path.join(input_dir, "BOOT", "RAMDISK") + if system_root_image: + init_rc_dir = os.path.join(input_dir, "ROOT") + else: + init_rc_dir = os.path.join(input_dir, "BOOT", "RAMDISK") init_rc_files = os.listdir(init_rc_dir) for init_rc_file in init_rc_files: if (not init_rc_file.startswith('init.') or diff --git a/tools/releasetools/img_from_target_files.py b/tools/releasetools/img_from_target_files.py index 608aad1039..ce5808f040 100755 --- a/tools/releasetools/img_from_target_files.py +++ b/tools/releasetools/img_from_target_files.py @@ -101,6 +101,7 @@ def main(argv): "boot.img", "boot.img", OPTIONS.input_tmp, "BOOT") if boot_image: boot_image.AddToZip(output_zip) + recovery_image = common.GetBootableImage( "recovery.img", "recovery.img", OPTIONS.input_tmp, "RECOVERY") if recovery_image: diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py index 69987ab479..03b7e05010 100755 --- a/tools/releasetools/ota_from_target_files.py +++ b/tools/releasetools/ota_from_target_files.py @@ -617,8 +617,8 @@ else if get_stage("%(bcb_dev)s") == "3/3" then symlinks = CopyPartitionFiles(system_items, input_zip, output_zip) script.MakeSymlinks(symlinks) - boot_img = common.GetBootableImage("boot.img", "boot.img", - OPTIONS.input_tmp, "BOOT") + boot_img = common.GetBootableImage( + "boot.img", "boot.img", OPTIONS.input_tmp, "BOOT") if not block_based: def output_sink(fn, data): diff --git a/tools/releasetools/sign_target_files_apks.py b/tools/releasetools/sign_target_files_apks.py index 962d3dd578..e98eb8f5e4 100755 --- a/tools/releasetools/sign_target_files_apks.py +++ b/tools/releasetools/sign_target_files_apks.py @@ -180,15 +180,17 @@ def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info, OPTIONS.replace_verity_private_key): ReplaceVerityPrivateKey(input_tf_zip, output_tf_zip, misc_info, OPTIONS.replace_verity_private_key[1]) - elif (info.filename == "BOOT/RAMDISK/verity_key" and + elif (info.filename in ("BOOT/RAMDISK/verity_key", + "BOOT/verity_key") and OPTIONS.replace_verity_public_key): - new_data = ReplaceVerityPublicKey(output_tf_zip, + new_data = ReplaceVerityPublicKey(output_tf_zip, info.filename, OPTIONS.replace_verity_public_key[1]) write_to_temp(info.filename, info.external_attr, new_data) # Copy BOOT/, RECOVERY/, META/, ROOT/ to rebuild recovery patch. elif (info.filename.startswith("BOOT/") or info.filename.startswith("RECOVERY/") or info.filename.startswith("META/") or + info.filename.startswith("ROOT/") or info.filename == "SYSTEM/etc/recovery-resource.dat"): write_to_temp(info.filename, info.external_attr, data) @@ -229,7 +231,8 @@ def ProcessTargetFiles(input_tf_zip, output_tf_zip, misc_info, info.filename == "META/misc_info.txt"): pass elif (OPTIONS.replace_verity_public_key and - info.filename == "BOOT/RAMDISK/verity_key"): + info.filename in ("BOOT/RAMDISK/verity_key", + "BOOT/verity_key")): pass else: # a non-APK file; copy it verbatim @@ -397,11 +400,11 @@ def ReplaceOtaKeys(input_tf_zip, output_tf_zip, misc_info): return new_recovery_keys -def ReplaceVerityPublicKey(targetfile_zip, key_path): +def ReplaceVerityPublicKey(targetfile_zip, filename, key_path): print "Replacing verity public key with %s" % key_path with open(key_path) as f: data = f.read() - common.ZipWriteStr(targetfile_zip, "BOOT/RAMDISK/verity_key", data) + common.ZipWriteStr(targetfile_zip, filename, data) return data def ReplaceVerityPrivateKey(targetfile_input_zip, targetfile_output_zip,