forked from openkylin/platform_build
Support to build image of root file system with /system and ramdisk combined.
Added support to build system.img that combines contents of /system and
the ramdisk, and can be mounted at the root of the file system.
To enable this feature, define BoardConfig.mk variable:
BOARD_BUILD_SYSTEM_ROOT_IMAGE := true
Ideally we would just change TARGET_OUT (the path of the staging system
directory) to under TARGET_ROOT_OUT. But at this point many places in
the build system assume TARGET_OUT is independent of TARGET_ROOT_OUT and
we can't make it easily configurable.
Instead this implementation takes the least intrusive approach:
We don't change TARGET_OUT or TARGET_ROOT_OUT. We just assemble a
temporary staging directory that contains contents of both TARGET_OUT
and TARGET_ROOT_OUT, in build_image.BuildImage() of
tools/releasetools/build_image.py.
When build_image.py is directly called from the makefile, we pass in the
parameters from the global dictionary; when build_image.BuildImage() is
called from add_img_to_target_files.py, we need to override values to
point to files extracted from the target_files zip file.
We need to combine the fs_config files of both /system and ramdisk,
when fs_config is enabled.
Also this change refactored build_image.BuildImage() by moving the extra
parameters to the image property dictionary.
(cherry-picked from commit 0eabd4f2c5
)
Bug:19868522
Change-Id: Iafc467a0e3427b0d6ad3b575abcc98ddcc9ea0f1
This commit is contained in:
parent
e7173cee10
commit
a2292c94d1
|
@ -717,6 +717,9 @@ $(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),$(hide) echo "verit
|
|||
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),$(hide) echo "verity_signer_cmd=$(VERITY_SIGNER)" >> $(1))
|
||||
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_VERITY_PARTITION),$(hide) echo "system_verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_VERITY_PARTITION)" >> $(1))
|
||||
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_VERITY_PARTITION),$(hide) echo "vendor_verity_block_device=$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VENDOR_VERITY_PARTITION)" >> $(1))
|
||||
$(if $(filter true,$(BOARD_BUILD_SYSTEM_ROOT_IMAGE)),\
|
||||
$(hide) echo "system_root_image=true" >> $(1);\
|
||||
echo "ramdisk_dir=$(TARGET_ROOT_OUT)" >> $(1))
|
||||
$(if $(2),$(hide) $(foreach kv,$(2),echo "$(kv)" >> $(1);))
|
||||
endef
|
||||
|
||||
|
|
|
@ -135,11 +135,20 @@ def CreateImage(input_dir, info_dict, what, block_list=None):
|
|||
fc_config = os.path.join(input_dir, "BOOT/RAMDISK/file_contexts")
|
||||
if not os.path.exists(fc_config): fc_config = None
|
||||
|
||||
# Override values loaded from info_dict.
|
||||
if fs_config:
|
||||
image_props["fs_config"] = fs_config
|
||||
if fc_config:
|
||||
image_props["selinux_fc"] = fc_config
|
||||
if block_list:
|
||||
image_props["block_list"] = block_list
|
||||
if image_props.get("system_root_image") == "true":
|
||||
image_props["ramdisk_dir"] = os.path.join(input_dir, "BOOT/RAMDISK")
|
||||
image_props["ramdisk_fs_config"] = os.path.join(
|
||||
input_dir, "META/boot_filesystem_config.txt")
|
||||
|
||||
succ = build_image.BuildImage(os.path.join(input_dir, what),
|
||||
image_props, img,
|
||||
fs_config=fs_config,
|
||||
fc_config=fc_config,
|
||||
block_list=block_list)
|
||||
image_props, img)
|
||||
assert succ, "build " + what + ".img image failed"
|
||||
|
||||
return img
|
||||
|
|
|
@ -198,25 +198,39 @@ def MakeVerityEnabledImage(out_file, prop_dict):
|
|||
shutil.rmtree(tempdir_name, ignore_errors=True)
|
||||
return True
|
||||
|
||||
def BuildImage(in_dir, prop_dict, out_file,
|
||||
fs_config=None,
|
||||
fc_config=None,
|
||||
block_list=None):
|
||||
def BuildImage(in_dir, prop_dict, out_file):
|
||||
"""Build an image to out_file from in_dir with property prop_dict.
|
||||
|
||||
Args:
|
||||
in_dir: path of input directory.
|
||||
prop_dict: property dictionary.
|
||||
out_file: path of the output image file.
|
||||
fs_config: path to the fs_config file (typically
|
||||
META/filesystem_config.txt). If None then the configuration in
|
||||
the local client will be used.
|
||||
fc_config: path to the SELinux file_contexts file. If None then
|
||||
the value from prop_dict['selinux_fc'] will be used.
|
||||
|
||||
Returns:
|
||||
True iff the image is built successfully.
|
||||
"""
|
||||
# system_root_image=true: build a system.img that combines the contents of /system
|
||||
# and the ramdisk, and can be mounted at the root of the file system.
|
||||
origin_in = in_dir
|
||||
fs_config = prop_dict.get("fs_config")
|
||||
if (prop_dict.get("system_root_image") == "true"
|
||||
and prop_dict["mount_point"] == "system"):
|
||||
in_dir = tempfile.mkdtemp()
|
||||
# Change the mount point to "/"
|
||||
prop_dict["mount_point"] = "/"
|
||||
if fs_config:
|
||||
# We need to merge the fs_config files of system and ramdisk.
|
||||
fd, merged_fs_config = tempfile.mkstemp(prefix="root_fs_config",
|
||||
suffix=".txt")
|
||||
os.close(fd)
|
||||
with open(merged_fs_config, "w") as fw:
|
||||
if "ramdisk_fs_config" in prop_dict:
|
||||
with open(prop_dict["ramdisk_fs_config"]) as fr:
|
||||
fw.writelines(fr.readlines())
|
||||
with open(fs_config) as fr:
|
||||
fw.writelines(fr.readlines())
|
||||
fs_config = merged_fs_config
|
||||
|
||||
build_command = []
|
||||
fs_type = prop_dict.get("fs_type", "")
|
||||
run_fsck = False
|
||||
|
@ -244,22 +258,18 @@ def BuildImage(in_dir, prop_dict, out_file,
|
|||
build_command.extend(["-j", prop_dict["journal_size"]])
|
||||
if "timestamp" in prop_dict:
|
||||
build_command.extend(["-T", str(prop_dict["timestamp"])])
|
||||
if fs_config is not None:
|
||||
if fs_config:
|
||||
build_command.extend(["-C", fs_config])
|
||||
if block_list is not None:
|
||||
build_command.extend(["-B", block_list])
|
||||
if "block_list" in prop_dict:
|
||||
build_command.extend(["-B", prop_dict["block_list"]])
|
||||
build_command.extend(["-L", prop_dict["mount_point"]])
|
||||
if fc_config is not None:
|
||||
build_command.append(fc_config)
|
||||
elif "selinux_fc" in prop_dict:
|
||||
if "selinux_fc" in prop_dict:
|
||||
build_command.append(prop_dict["selinux_fc"])
|
||||
elif fs_type.startswith("squash"):
|
||||
build_command = ["mksquashfsimage.sh"]
|
||||
build_command.extend([in_dir, out_file])
|
||||
build_command.extend(["-m", prop_dict["mount_point"]])
|
||||
if fc_config is not None:
|
||||
build_command.extend(["-c", fc_config])
|
||||
elif "selinux_fc" in prop_dict:
|
||||
if "selinux_fc" in prop_dict:
|
||||
build_command.extend(["-c", prop_dict["selinux_fc"]])
|
||||
elif fs_type.startswith("f2fs"):
|
||||
build_command = ["mkf2fsuserimg.sh"]
|
||||
|
@ -274,7 +284,23 @@ def BuildImage(in_dir, prop_dict, out_file,
|
|||
build_command.append(prop_dict["selinux_fc"])
|
||||
build_command.append(prop_dict["mount_point"])
|
||||
|
||||
if in_dir != origin_in:
|
||||
# Construct a staging directory of the root file system.
|
||||
ramdisk_dir = prop_dict.get("ramdisk_dir")
|
||||
if ramdisk_dir:
|
||||
shutil.rmtree(in_dir)
|
||||
shutil.copytree(ramdisk_dir, in_dir, symlinks=True)
|
||||
staging_system = os.path.join(in_dir, "system")
|
||||
shutil.rmtree(staging_system, ignore_errors=True)
|
||||
shutil.copytree(origin_in, staging_system, symlinks=True)
|
||||
try:
|
||||
exit_code = RunCommand(build_command)
|
||||
finally:
|
||||
if in_dir != origin_in:
|
||||
# Clean up temporary directories and files.
|
||||
shutil.rmtree(in_dir, ignore_errors=True)
|
||||
if fs_config:
|
||||
os.remove(fs_config)
|
||||
if exit_code != 0:
|
||||
return False
|
||||
|
||||
|
@ -334,6 +360,8 @@ def ImagePropFromGlobalDict(glob_dict, mount_point):
|
|||
copy_prop("system_size", "partition_size")
|
||||
copy_prop("system_journal_size", "journal_size")
|
||||
copy_prop("system_verity_block_device", "verity_block_device")
|
||||
copy_prop("system_root_image","system_root_image")
|
||||
copy_prop("ramdisk_dir","ramdisk_dir")
|
||||
elif mount_point == "data":
|
||||
# Copy the generic fs type first, override with specific one if available.
|
||||
copy_prop("fs_type", "fs_type")
|
||||
|
|
Loading…
Reference in New Issue