Add system_other partition, install odex files

For AB devices, support flashing two system partitions for factory use.
The normal system image on one partition, but without dex preopt. And a
system_other image that just contains the odex files. The dex files will
not be stripped out of the system image, in case the second system
partition is wiped.

Setting BOARD_USES_SYSTEM_OTHER_ODEX := true in the BoardConfig.mk
enables this behavior.

One can control which directories are placed in system_other by the
SYSTEM_OTHER_ODEX_FILTER configuration variable. Currently we default
to only copying only app and priv-app odexs.

Bug: 29278988
Change-Id: I7f4e87da919e7dc6a89fd8c668193cd4e98631bc
This commit is contained in:
Alex Light 2016-06-16 14:47:10 -07:00
parent 9cbe37e723
commit 4e358ab2c3
11 changed files with 146 additions and 10 deletions

View file

@ -374,6 +374,10 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/APPS/*)
# $(PRODUCT_OUT)/recovery/root/sdcard goes from symlink to folder.
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/sdcard)
# Add BOARD_USES_SYSTEM_OTHER_ODEX
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/app/*)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/*)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************

View file

@ -1415,6 +1415,59 @@ IGNORE_CACHE_LINK := --exclude=cache
endif # BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE
# -----------------------------------------------------------------
# system_other partition image
ifeq ($(BOARD_USES_SYSTEM_OTHER_ODEX),true)
BOARD_USES_SYSTEM_OTHER := true
# Marker file to identify that odex files are installed
INSTALLED_SYSTEM_OTHER_ODEX_MARKER := $(TARGET_OUT_SYSTEM_OTHER)/system-other-odex-marker
ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_SYSTEM_OTHER_ODEX_MARKER)
$(INSTALLED_SYSTEM_OTHER_ODEX_MARKER):
$(hide) touch $@
endif
ifdef BOARD_USES_SYSTEM_OTHER
INTERNAL_SYSTEMOTHERIMAGE_FILES := \
$(filter $(TARGET_OUT_SYSTEM_OTHER)/%,\
$(ALL_DEFAULT_INSTALLED_MODULES)\
$(ALL_PDK_FUSION_FILES))
INSTALLED_FILES_FILE_SYSTEMOTHER := $(PRODUCT_OUT)/installed-files-system-other.txt
$(INSTALLED_FILES_FILE_SYSTEMOTHER) : $(INTERNAL_SYSTEMOTHERIMAGE_FILES)
@echo Installed file list: $@
@mkdir -p $(dir $@)
@rm -f $@
$(hide) build/tools/fileslist.py $(TARGET_OUT_SYSTEM_OTHER) > $@
systemotherimage_intermediates := \
$(call intermediates-dir-for,PACKAGING,system_other)
BUILT_SYSTEMOTHERIMAGE_TARGET := $(PRODUCT_OUT)/system_other.img
# Note that we assert the size is SYSTEMIMAGE_PARTITION_SIZE since this is the 'b' system image.
define build-systemotherimage-target
$(call pretty,"Target system_other fs image: $(INSTALLED_SYSTEMOTHERIMAGE_TARGET)")
@mkdir -p $(TARGET_OUT_SYSTEM_OTHER)
@mkdir -p $(systemotherimage_intermediates) && rm -rf $(systemotherimage_intermediates)/system_other_image_info.txt
$(call generate-userimage-prop-dictionary, $(systemotherimage_intermediates)/system_other_image_info.txt, skip_fsck=true)
$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
./build/tools/releasetools/build_image.py \
$(TARGET_OUT_SYSTEM_OTHER) $(systemotherimage_intermediates)/system_other_image_info.txt $(INSTALLED_SYSTEMOTHERIMAGE_TARGET) $(TARGET_OUT)
$(hide) $(call assert-max-image-size,$(INSTALLED_SYSTEMOTHERIMAGE_TARGET),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))
endef
# We just build this directly to the install location.
INSTALLED_SYSTEMOTHERIMAGE_TARGET := $(BUILT_SYSTEMOTHERIMAGE_TARGET)
$(INSTALLED_SYSTEMOTHERIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_SYSTEMOTHERIMAGE_FILES) $(INSTALLED_FILES_FILE_SYSTEMOTHER)
$(build-systemotherimage-target)
.PHONY: systemotherimage-nodeps
systemotherimage-nodeps: | $(INTERNAL_USERIMAGES_DEPS)
$(build-systemotherimage-target)
endif # BOARD_USES_SYSTEM_OTHER
# -----------------------------------------------------------------
# vendor partition image
ifdef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE
@ -1646,6 +1699,7 @@ $(BUILT_TARGET_FILES_PACKAGE): \
$(INSTALLED_USERDATAIMAGE_TARGET) \
$(INSTALLED_CACHEIMAGE_TARGET) \
$(INSTALLED_VENDORIMAGE_TARGET) \
$(INSTALLED_SYSTEMOTHERIMAGE_TARGET) \
$(INSTALLED_ANDROID_INFO_TXT_TARGET) \
$(SELINUX_FC) \
$(APKCERTS_FILE) \
@ -1718,6 +1772,11 @@ ifdef BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE
@# Contents of the vendor image
$(hide) $(call package_files-copy-root, \
$(TARGET_OUT_VENDOR),$(zip_root)/VENDOR)
endif
ifdef INSTALLED_SYSTEMOTHERIMAGE_TARGET
@# Contents of the system_other image
$(hide) $(call package_files-copy-root, \
$(TARGET_OUT_SYSTEM_OTHER),$(zip_root)/SYSTEM_OTHER)
endif
@# Extra contents of the OTA package
$(hide) mkdir -p $(zip_root)/OTA
@ -1832,6 +1891,9 @@ endif
$(hide) zipinfo -1 $@ | awk 'BEGIN { FS="BOOT/RAMDISK/" } /^BOOT\/RAMDISK\// {print $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -S $(SELINUX_FC) > $(zip_root)/META/boot_filesystem_config.txt
ifneq ($(INSTALLED_RECOVERYIMAGE_TARGET),)
$(hide) zipinfo -1 $@ | awk 'BEGIN { FS="RECOVERY/RAMDISK/" } /^RECOVERY\/RAMDISK\// {print $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -S $(SELINUX_FC) > $(zip_root)/META/recovery_filesystem_config.txt
endif
ifdef INSTALLED_SYSTEMOTHERIMAGE_TARGET
$(hide) zipinfo -1 $@ | awk 'BEGIN { FS="SYSTEM_OTHER/" } /^SYSTEM_OTHER\// { print "system/" $$2}' | $(HOST_OUT_EXECUTABLES)/fs_config -C -D $(TARGET_OUT) -S $(SELINUX_FC) > $(zip_root)/META/system_other_filesystem_config.txt
endif
$(hide) (cd $(zip_root) && zip -qX ../$(notdir $@) META/*filesystem_config.txt)
$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH MKBOOTIMG=$(MKBOOTIMG) \

View file

@ -242,6 +242,7 @@ installclean_files := \
$(PRODUCT_OUT)/recovery \
$(PRODUCT_OUT)/root \
$(PRODUCT_OUT)/system \
$(PRODUCT_OUT)/system_other \
$(PRODUCT_OUT)/vendor \
$(PRODUCT_OUT)/oem \
$(PRODUCT_OUT)/dex_bootjars \

View file

@ -19,6 +19,10 @@ DEXPREOPT_BOOT_JAR_DIR_FULL_PATH := $(DEXPREOPT_PRODUCT_DIR_FULL_PATH)/$(DEXPREO
# The default value for LOCAL_DEX_PREOPT
DEX_PREOPT_DEFAULT ?= true
# The default filter for which files go into the system_other image (if it is
# being used). To bundle everything one should set this to '%'
SYSTEM_OTHER_ODEX_FILTER ?= app/% priv-app/%
# The default values for pre-opting: always preopt PIC.
# Conditional to building on linux, as dex2oat currently does not work on darwin.
ifeq ($(HOST_OS),linux)

View file

@ -59,6 +59,21 @@ define get-odex-file-path
$(dir $(2))oat/$(1)/$(basename $(notdir $(2))).odex
endef
# Returns the full path to the installed .odex file.
# This handles BOARD_USES_SYSTEM_OTHER_ODEX to install odex files into another
# partition.
# $(1): the arch name.
# $(2): the full install path (including file name) of the corresponding .apk.
ifeq ($(BOARD_USES_SYSTEM_OTHER_ODEX),true)
define get-odex-installed-file-path
$(if $(filter $(foreach f,$(SYSTEM_OTHER_ODEX_FILTER),$(TARGET_OUT)/$(f)),$(2)),
$(call get-odex-file-path,$(1),$(patsubst $(TARGET_OUT)/%,$(TARGET_OUT_SYSTEM_OTHER)/%,$(2))),
$(call get-odex-file-path,$(1),$(2)))
endef
else
get-odex-installed-file-path = $(get-odex-file-path)
endif
# Returns the path to the image file (such as "/system/framework/<arch>/boot.art"
# $(1): the arch name (such as "arm")
# $(2): the image location (such as "/system/framework/boot.art")

View file

@ -39,6 +39,14 @@ ifeq ($(filter $(DEXPREOPT_BOOT_JARS_MODULES),$(LOCAL_MODULE)),)
LOCAL_DEX_PREOPT :=
endif
endif
# if installing into system, and odex are being installed into system_other, don't strip
ifeq ($(BOARD_USES_SYSTEM_OTHER_ODEX),true)
ifeq ($(LOCAL_DEX_PREOPT),true)
ifneq ($(filter $(foreach f,$(SYSTEM_OTHER_ODEX_FILTER),$(TARGET_OUT)/$(f)),$(my_module_path)),)
LOCAL_DEX_PREOPT := nostripping
endif
endif
endif
built_odex :=
installed_odex :=
@ -100,14 +108,6 @@ endif
endif
$(built_odex): PRIVATE_DEX_PREOPT_FLAGS := $(LOCAL_DEX_PREOPT_FLAGS)
# Use pattern rule - we may have multiple installed odex files.
# Ugly syntax - See the definition get-odex-file-path.
$(installed_odex) : $(dir $(LOCAL_INSTALLED_MODULE))%$(notdir $(word 1,$(installed_odex))) \
: $(dir $(LOCAL_BUILT_MODULE))%$(notdir $(word 1,$(built_odex))) \
| $(ACP)
@echo "Install: $@"
$(copy-file-to-target)
endif
# Add the installed_odex to the list of installed files for this module.

View file

@ -109,6 +109,7 @@ HOST_PREBUILT_TAG := $(BUILD_OS)-$(HOST_PREBUILT_ARCH)
# TARGET_COPY_OUT_* are all relative to the staging directory, ie PRODUCT_OUT.
# Define them here so they can be used in product config files.
TARGET_COPY_OUT_SYSTEM := system
TARGET_COPY_OUT_SYSTEM_OTHER := system_other
TARGET_COPY_OUT_DATA := data
TARGET_COPY_OUT_OEM := oem
TARGET_COPY_OUT_ODM := odm
@ -322,6 +323,8 @@ TARGET_OUT_ETC := $(TARGET_OUT)/etc
TARGET_OUT_NOTICE_FILES := $(TARGET_OUT_INTERMEDIATES)/NOTICE_FILES
TARGET_OUT_FAKE := $(PRODUCT_OUT)/fake_packages
TARGET_OUT_SYSTEM_OTHER := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_SYSTEM_OTHER)
# Out for TARGET_2ND_ARCH
TARGET_2ND_ARCH_VAR_PREFIX := $(HOST_2ND_ARCH_VAR_PREFIX)
TARGET_2ND_ARCH_MODULE_SUFFIX := $(HOST_2ND_ARCH_MODULE_SUFFIX)

View file

@ -81,6 +81,7 @@ dont_bother_goals := clean clobber dataclean installclean \
userdataimage-nodeps userdatatarball-nodeps \
cacheimage-nodeps \
vendorimage-nodeps \
systemotherimage-nodeps \
ramdisk-nodeps \
bootimage-nodeps \
recoveryimage-nodeps \
@ -928,6 +929,9 @@ cacheimage: $(INSTALLED_CACHEIMAGE_TARGET)
.PHONY: vendorimage
vendorimage: $(INSTALLED_VENDORIMAGE_TARGET)
.PHONY: systemotherimage
systemotherimage: $(INSTALLED_SYSTEMOTHERIMAGE_TARGET)
.PHONY: bootimage
bootimage: $(INSTALLED_BOOTIMAGE_TARGET)
@ -955,8 +959,10 @@ droidcore: files \
$(INSTALLED_USERDATAIMAGE_TARGET) \
$(INSTALLED_CACHEIMAGE_TARGET) \
$(INSTALLED_VENDORIMAGE_TARGET) \
$(INSTALLED_SYSTEMOTHERIMAGE_TARGET) \
$(INSTALLED_FILES_FILE) \
$(INSTALLED_FILES_FILE_VENDOR)
$(INSTALLED_FILES_FILE_VENDOR) \
$(INSTALLED_FILES_FILE_SYSTEMOTHER)
# dist_files only for putting your library into the dist directory with a full build.
.PHONY: dist_files
@ -1017,6 +1023,7 @@ else # TARGET_BUILD_APPS
$(SYMBOLS_ZIP) \
$(INSTALLED_FILES_FILE) \
$(INSTALLED_FILES_FILE_VENDOR) \
$(INSTALLED_FILES_FILE_SYSTEMOTHER) \
$(INSTALLED_BUILD_PROP_TARGET) \
$(BUILT_TARGET_FILES_PACKAGE) \
$(INSTALLED_ANDROID_INFO_TXT_TARGET) \

View file

@ -32,7 +32,9 @@ $(my_built_odex) : $($(my_2nd_arch_prefix)DEXPREOPT_ONE_FILE_DEPENDENCY_BUILT_BO
$(DEXPREOPT_ONE_FILE_DEPENDENCY_TOOLS) \
$(my_dex_preopt_image_filename)
my_installed_odex := $(call get-odex-file-path,$($(my_2nd_arch_prefix)DEX2OAT_TARGET_ARCH),$(LOCAL_INSTALLED_MODULE))
my_installed_odex := $(call get-odex-installed-file-path,$($(my_2nd_arch_prefix)DEX2OAT_TARGET_ARCH),$(LOCAL_INSTALLED_MODULE))
$(eval $(call copy-one-file,$(my_built_odex),$(my_installed_odex)))
built_odex += $(my_built_odex)
installed_odex += $(my_installed_odex)

View file

@ -78,6 +78,24 @@ def BuildSystem(input_dir, info_dict, block_list=None):
return CreateImage(input_dir, info_dict, "system", block_list=block_list)
def AddSystemOther(output_zip, prefix="IMAGES/"):
"""Turn the contents of SYSTEM_OTHER into a system_other image
and store it in output_zip."""
prebuilt_path = os.path.join(OPTIONS.input_tmp, prefix, "system_other.img")
if os.path.exists(prebuilt_path):
print "system_other.img already exists in %s, no need to rebuild..." % (prefix,)
return
imgname = BuildSystemOther(OPTIONS.input_tmp, OPTIONS.info_dict)
common.ZipWrite(output_zip, imgname, prefix + "system_other.img")
def BuildSystemOther(input_dir, info_dict):
"""Build the (sparse) system_other image and return the name of a temp
file containing it."""
return CreateImage(input_dir, info_dict, "system_other", block_list=None)
def AddVendor(output_zip, prefix="IMAGES/"):
"""Turn the contents of VENDOR into a vendor image and store in it
output_zip."""
@ -268,6 +286,8 @@ def AddImagesToTargetFiles(filename):
except KeyError:
has_vendor = False
has_system_other = "SYSTEM_OTHER/" in input_zip.namelist()
OPTIONS.info_dict = common.LoadInfoDict(input_zip, OPTIONS.input_tmp)
common.ZipClose(input_zip)
@ -314,6 +334,9 @@ def AddImagesToTargetFiles(filename):
if has_vendor:
banner("vendor")
AddVendor(output_zip)
if has_system_other:
banner("system_other")
AddSystemOther(output_zip)
banner("userdata")
AddUserdata(output_zip)
banner("cache")

View file

@ -556,6 +556,19 @@ def ImagePropFromGlobalDict(glob_dict, mount_point):
copy_prop("system_squashfs_block_size", "squashfs_block_size")
copy_prop("system_squashfs_disable_4k_align", "squashfs_disable_4k_align")
copy_prop("system_base_fs_file", "base_fs_file")
elif mount_point == "system_other":
# We inherit the selinux policies of /system since we contain some of its files.
d["mount_point"] = "system"
copy_prop("fs_type", "fs_type")
copy_prop("system_fs_type", "fs_type")
copy_prop("system_size", "partition_size")
copy_prop("system_journal_size", "journal_size")
copy_prop("system_verity_block_device", "verity_block_device")
copy_prop("has_ext4_reserved_blocks", "has_ext4_reserved_blocks")
copy_prop("system_squashfs_compressor", "squashfs_compressor")
copy_prop("system_squashfs_compressor_opt", "squashfs_compressor_opt")
copy_prop("system_squashfs_block_size", "squashfs_block_size")
copy_prop("system_base_fs_file", "base_fs_file")
elif mount_point == "data":
# Copy the generic fs type first, override with specific one if available.
copy_prop("fs_type", "fs_type")
@ -618,6 +631,8 @@ def main(argv):
mount_point = ""
if image_filename == "system.img":
mount_point = "system"
elif image_filename == "system_other.img":
mount_point = "system_other"
elif image_filename == "userdata.img":
mount_point = "data"
elif image_filename == "cache.img":