releasetools: Support packaging for system_root_image.

For system images that contain the root directory, we need to find the
root directory at ROOT/ instead of BOOT/RAMDISK/.

 Conflicts:
	tools/releasetools/common.py

Change-Id: Ica345c8b1b03475f8ac6c44fd576045fcf17c882
This commit is contained in:
Tao Bao 2015-07-21 18:01:20 -07:00 committed by Rom Lemarchand
parent 97b906b004
commit b11d2c5dd6
3 changed files with 74 additions and 46 deletions

View File

@ -182,7 +182,8 @@ def LoadInfoDict(input_file):
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
@ -298,7 +299,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["/"]
@ -310,34 +312,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"
@ -368,14 +382,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()
@ -415,7 +430,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
@ -423,11 +439,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):
@ -440,10 +456,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
@ -1394,6 +1418,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)
@ -1453,13 +1478,15 @@ 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
not init_rc_file.endswith('.rc')):
continue
with open(os.path.join(init_rc_dir, init_rc_file)) as f:
for line in f:
m = re.match(r"^service flash_recovery /system/(\S+)\s*$", line)
@ -1467,10 +1494,8 @@ fi
sh_location = m.group(1)
found = True
break
if found:
break
print "putting script in", sh_location
output_sink(sh_location, sh)

View File

@ -620,8 +620,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):

View File

@ -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)
@ -231,7 +233,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
@ -403,11 +406,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,