From 4647f12a4ff9dc54247184f17ff3de1cc423f213 Mon Sep 17 00:00:00 2001 From: Doug Zongker Date: Thu, 2 Jul 2009 09:00:54 -0700 Subject: [PATCH] fix image size tests There are currently two errors in the way we test the size of built images against the size of the partition on the hardware: - the limits in BoardConfig.mk are set with the data size only, but images contain an extra 64 bytes per 2048-byte page. This means we think the partition is about 1/32 smaller than it really is. - when we deliver a build via OTA, the system partition ends up with one more file than when it's flashed via fastboot. That file is a copy of the recovery image. In order to be able to OTA a build, we need to make sure the system partition has enough room for all the system files plus the recovery image as well. For the kila system partition, these errors are roughly the same order of magnitude -- about 2MB, one in the "safe" direction, one in the "unsafe" direction. This change fixes both to give us a more accurate notion of how close we are to the limit. Make the build emit a warning (but not fail) when the size is within 32kb of the limit. Also, include the values of the partition size limits in an info file in the target-files package, so post-processing tools can use them without parsing the BoardConfig.mk file. --- core/Makefile | 183 ++++++++++++++++++++++---------------------- core/definitions.mk | 38 +++++---- 2 files changed, 117 insertions(+), 104 deletions(-) diff --git a/core/Makefile b/core/Makefile index 20522942fd..ea556311cb 100644 --- a/core/Makefile +++ b/core/Makefile @@ -497,6 +497,91 @@ else INTERNAL_MKUSERFS := $(MKYAFFS2) endif +# ----------------------------------------------------------------- +# Recovery image +INSTALLED_RECOVERYIMAGE_TARGET := $(PRODUCT_OUT)/recovery.img + +recovery_initrc := $(call include-path-for, recovery)/etc/init.rc +recovery_kernel := $(INSTALLED_KERNEL_TARGET) # same as a non-recovery system +recovery_ramdisk := $(PRODUCT_OUT)/ramdisk-recovery.img +recovery_build_prop := $(INSTALLED_BUILD_PROP_TARGET) +recovery_binary := $(call intermediates-dir-for,EXECUTABLES,recovery)/recovery +recovery_resources_common := $(call include-path-for, recovery)/res +recovery_resources_private := $(strip $(wildcard $(TARGET_DEVICE_DIR)/recovery/res)) +recovery_resource_deps := $(shell find $(recovery_resources_common) \ + $(recovery_resources_private) -type f) + +ifeq ($(recovery_resources_private),) + $(info No private recovery resources for TARGET_DEVICE $(TARGET_DEVICE)) +endif + +INTERNAL_RECOVERYIMAGE_ARGS := \ + $(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET)) \ + --kernel $(recovery_kernel) \ + --ramdisk $(recovery_ramdisk) + +# Assumes this has already been stripped +ifdef BOARD_KERNEL_CMDLINE + INTERNAL_RECOVERYIMAGE_ARGS += --cmdline "$(BOARD_KERNEL_CMDLINE)" +endif +ifdef BOARD_KERNEL_BASE + INTERNAL_RECOVERYIMAGE_ARGS += --base $(BOARD_KERNEL_BASE) +endif + +# Keys authorized to sign OTA packages this build will accept. The +# build always uses test-keys for this; release packaging tools will +# substitute other keys for this one. +OTA_PUBLIC_KEYS := $(SRC_TARGET_DIR)/product/security/testkey.x509.pem + +# Generate a file containing the keys that will be read by the +# recovery binary. +RECOVERY_INSTALL_OTA_KEYS := \ + $(call intermediates-dir-for,PACKAGING,ota_keys)/keys +DUMPKEY_JAR := $(HOST_OUT_JAVA_LIBRARIES)/dumpkey.jar +$(RECOVERY_INSTALL_OTA_KEYS): PRIVATE_OTA_PUBLIC_KEYS := $(OTA_PUBLIC_KEYS) +$(RECOVERY_INSTALL_OTA_KEYS): $(OTA_PUBLIC_KEYS) $(DUMPKEY_JAR) + @echo "DumpPublicKey: $@ <= $(PRIVATE_OTA_PUBLIC_KEYS)" + @rm -rf $@ + @mkdir -p $(dir $@) + java -jar $(DUMPKEY_JAR) $(PRIVATE_OTA_PUBLIC_KEYS) > $@ + +$(INSTALLED_RECOVERYIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) \ + $(INSTALLED_RAMDISK_TARGET) \ + $(INSTALLED_BOOTIMAGE_TARGET) \ + $(recovery_binary) \ + $(recovery_initrc) $(recovery_kernel) \ + $(INSTALLED_2NDBOOTLOADER_TARGET) \ + $(recovery_build_prop) $(recovery_resource_deps) \ + $(RECOVERY_INSTALL_OTA_KEYS) + @echo ----- Making recovery image ------ + rm -rf $(TARGET_RECOVERY_OUT) + mkdir -p $(TARGET_RECOVERY_OUT) + mkdir -p $(TARGET_RECOVERY_ROOT_OUT) + mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/etc + mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/tmp + echo Copying baseline ramdisk... + cp -R $(TARGET_ROOT_OUT) $(TARGET_RECOVERY_OUT) + echo Modifying ramdisk contents... + cp -f $(recovery_initrc) $(TARGET_RECOVERY_ROOT_OUT)/ + cp -f $(recovery_binary) $(TARGET_RECOVERY_ROOT_OUT)/sbin/ + cp -rf $(recovery_resources_common) $(TARGET_RECOVERY_ROOT_OUT)/ + $(foreach item,$(recovery_resources_private), \ + cp -rf $(item) $(TARGET_RECOVERY_ROOT_OUT)/) + cp $(RECOVERY_INSTALL_OTA_KEYS) $(TARGET_RECOVERY_ROOT_OUT)/res/keys + cat $(INSTALLED_DEFAULT_PROP_TARGET) $(recovery_build_prop) \ + > $(TARGET_RECOVERY_ROOT_OUT)/default.prop + $(MKBOOTFS) $(TARGET_RECOVERY_ROOT_OUT) | $(MINIGZIP) > $(recovery_ramdisk) + $(MKBOOTIMG) $(INTERNAL_RECOVERYIMAGE_ARGS) --output $@ + @echo ----- Made recovery image -------- $@ + $(hide) $(call assert-max-file-size,$@,$(BOARD_RECOVERYIMAGE_MAX_SIZE)) + +else +INSTALLED_RECOVERYIMAGE_TARGET := +endif + +.PHONY: recoveryimage +recoveryimage: $(INSTALLED_RECOVERYIMAGE_TARGET) + # ----------------------------------------------------------------- # system yaffs image # @@ -552,10 +637,10 @@ else SYSTEMIMAGE_SOURCE_DIR := $(TARGET_OUT) endif -$(INSTALLED_SYSTEMIMAGE): $(BUILT_SYSTEMIMAGE) | $(ACP) +$(INSTALLED_SYSTEMIMAGE): $(BUILT_SYSTEMIMAGE) $(INSTALLED_RECOVERYIMAGE_TARGET) | $(ACP) @echo "Install system fs image: $@" $(copy-file-to-target) - $(hide) $(call assert-max-file-size,$@,$(BOARD_SYSTEMIMAGE_MAX_SIZE)) + $(hide) $(call assert-max-file-size,$@ $(INSTALLED_RECOVERYIMAGE_TARGET),$(BOARD_SYSTEMIMAGE_MAX_SIZE)) systemimage: $(INSTALLED_SYSTEMIMAGE) @@ -651,91 +736,6 @@ userdatatarball-nodeps: $(FS_GET_STATS) # If neither TARGET_NO_KERNEL nor TARGET_NO_RECOVERY are true ifeq (,$(filter true, $(TARGET_NO_KERNEL) $(TARGET_NO_RECOVERY))) -# ----------------------------------------------------------------- -# Recovery image -INSTALLED_RECOVERYIMAGE_TARGET := $(PRODUCT_OUT)/recovery.img - -recovery_initrc := $(call include-path-for, recovery)/etc/init.rc -recovery_kernel := $(INSTALLED_KERNEL_TARGET) # same as a non-recovery system -recovery_ramdisk := $(PRODUCT_OUT)/ramdisk-recovery.img -recovery_build_prop := $(INSTALLED_BUILD_PROP_TARGET) -recovery_binary := $(call intermediates-dir-for,EXECUTABLES,recovery)/recovery -recovery_resources_common := $(call include-path-for, recovery)/res -recovery_resources_private := $(strip $(wildcard $(TARGET_DEVICE_DIR)/recovery/res)) -recovery_resource_deps := $(shell find $(recovery_resources_common) \ - $(recovery_resources_private) -type f) - -ifeq ($(recovery_resources_private),) - $(info No private recovery resources for TARGET_DEVICE $(TARGET_DEVICE)) -endif - -INTERNAL_RECOVERYIMAGE_ARGS := \ - $(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET)) \ - --kernel $(recovery_kernel) \ - --ramdisk $(recovery_ramdisk) - -# Assumes this has already been stripped -ifdef BOARD_KERNEL_CMDLINE - INTERNAL_RECOVERYIMAGE_ARGS += --cmdline "$(BOARD_KERNEL_CMDLINE)" -endif -ifdef BOARD_KERNEL_BASE - INTERNAL_RECOVERYIMAGE_ARGS += --base $(BOARD_KERNEL_BASE) -endif - -# Keys authorized to sign OTA packages this build will accept. The -# build always uses test-keys for this; release packaging tools will -# substitute other keys for this one. -OTA_PUBLIC_KEYS := $(SRC_TARGET_DIR)/product/security/testkey.x509.pem - -# Generate a file containing the keys that will be read by the -# recovery binary. -RECOVERY_INSTALL_OTA_KEYS := \ - $(call intermediates-dir-for,PACKAGING,ota_keys)/keys -DUMPKEY_JAR := $(HOST_OUT_JAVA_LIBRARIES)/dumpkey.jar -$(RECOVERY_INSTALL_OTA_KEYS): PRIVATE_OTA_PUBLIC_KEYS := $(OTA_PUBLIC_KEYS) -$(RECOVERY_INSTALL_OTA_KEYS): $(OTA_PUBLIC_KEYS) $(DUMPKEY_JAR) - @echo "DumpPublicKey: $@ <= $(PRIVATE_OTA_PUBLIC_KEYS)" - @rm -rf $@ - @mkdir -p $(dir $@) - java -jar $(DUMPKEY_JAR) $(PRIVATE_OTA_PUBLIC_KEYS) > $@ - -$(INSTALLED_RECOVERYIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) \ - $(INSTALLED_RAMDISK_TARGET) \ - $(INSTALLED_BOOTIMAGE_TARGET) \ - $(recovery_binary) \ - $(recovery_initrc) $(recovery_kernel) \ - $(INSTALLED_2NDBOOTLOADER_TARGET) \ - $(recovery_build_prop) $(recovery_resource_deps) \ - $(RECOVERY_INSTALL_OTA_KEYS) - @echo ----- Making recovery image ------ - rm -rf $(TARGET_RECOVERY_OUT) - mkdir -p $(TARGET_RECOVERY_OUT) - mkdir -p $(TARGET_RECOVERY_ROOT_OUT) - mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/etc - mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/tmp - echo Copying baseline ramdisk... - cp -R $(TARGET_ROOT_OUT) $(TARGET_RECOVERY_OUT) - echo Modifying ramdisk contents... - cp -f $(recovery_initrc) $(TARGET_RECOVERY_ROOT_OUT)/ - cp -f $(recovery_binary) $(TARGET_RECOVERY_ROOT_OUT)/sbin/ - cp -rf $(recovery_resources_common) $(TARGET_RECOVERY_ROOT_OUT)/ - $(foreach item,$(recovery_resources_private), \ - cp -rf $(item) $(TARGET_RECOVERY_ROOT_OUT)/) - cp $(RECOVERY_INSTALL_OTA_KEYS) $(TARGET_RECOVERY_ROOT_OUT)/res/keys - cat $(INSTALLED_DEFAULT_PROP_TARGET) $(recovery_build_prop) \ - > $(TARGET_RECOVERY_ROOT_OUT)/default.prop - $(MKBOOTFS) $(TARGET_RECOVERY_ROOT_OUT) | $(MINIGZIP) > $(recovery_ramdisk) - $(MKBOOTIMG) $(INTERNAL_RECOVERYIMAGE_ARGS) --output $@ - @echo ----- Made recovery image -------- $@ - $(hide) $(call assert-max-file-size,$@,$(BOARD_RECOVERYIMAGE_MAX_SIZE)) - -else -INSTALLED_RECOVERYIMAGE_TARGET := -endif - -.PHONY: recoveryimage -recoveryimage: $(INSTALLED_RECOVERYIMAGE_TARGET) - # ----------------------------------------------------------------- # bring in the installer image generation defines if necessary ifeq ($(TARGET_USE_DISKINSTALLER),true) @@ -799,7 +799,7 @@ $(BUILT_TARGET_FILES_PACKAGE): \ $(INSTALLED_BOOTIMAGE_TARGET) \ $(INSTALLED_RADIOIMAGE_TARGET) \ $(INSTALLED_RECOVERYIMAGE_TARGET) \ - $(BUILT_SYSTEMIMAGE) \ + $(INSTALLED_SYSTEMIMAGE) \ $(INSTALLED_USERDATAIMAGE_TARGET) \ $(INSTALLED_ANDROID_INFO_TXT_TARGET) \ $(built_ota_tools) \ @@ -857,6 +857,11 @@ endif $(hide) $(ACP) $(APKCERTS_FILE) $(zip_root)/META/apkcerts.txt $(hide) echo "$(PRODUCT_OTA_PUBLIC_KEYS)" > $(zip_root)/META/otakeys.txt $(hide) echo "$(PRIVATE_RECOVERY_API_VERSION)" > $(zip_root)/META/recovery-api-version.txt + $(hide) echo "blocksize $(BOARD_FLASH_BLOCK_SIZE)" > $(zip_root)/META/imagesizes.txt + $(hide) echo "boot $(BOARD_BOOTIMAGE_MAX_SIZE)" >> $(zip_root)/META/imagesizes.txt + $(hide) echo "recovery $(BOARD_RECOVERYIMAGE_MAX_SIZE)" >> $(zip_root)/META/imagesizes.txt + $(hide) echo "system $(BOARD_SYSTEMIMAGE_MAX_SIZE)" >> $(zip_root)/META/imagesizes.txt + $(hide) echo "userdata $(BOARD_USERDATAIMAGE_MAX_SIZE)" >> $(zip_root)/META/imagesizes.txt @# Zip everything up, preserving symlinks $(hide) (cd $(zip_root) && zip -qry ../$(notdir $@) .) @@ -882,7 +887,6 @@ $(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) otatools @echo "Package OTA: $@" $(hide) ./build/tools/releasetools/ota_from_target_files \ -p $(HOST_OUT) \ - -b $(TARGET_DEVICE_DIR)/BoardConfig.mk \ -k $(KEY_CERT_PAIR) \ $(BUILT_TARGET_FILES_PACKAGE) $@ @@ -1008,7 +1012,6 @@ $(INTERNAL_UPDATE_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) otatools @echo "Package: $@" $(hide) ./build/tools/releasetools/img_from_target_files \ -p $(HOST_OUT) \ - -b $(TARGET_DEVICE_DIR)/BoardConfig.mk \ $(BUILT_TARGET_FILES_PACKAGE) $@ .PHONY: updatepackage diff --git a/core/definitions.mk b/core/definitions.mk index 1d9dd74b15..485c2ae7ac 100644 --- a/core/definitions.mk +++ b/core/definitions.mk @@ -1540,8 +1540,16 @@ ifndef get-file-size $(error HOST_OS must define get-file-size) endif -# $(1): The file to check (often $@) -# $(2): The maximum size, in decimal bytes +# Convert a partition data size (eg, as reported in /proc/mtd) to the +# size of the image used to flash that partition (which includes a +# 64-byte spare area for each 2048-byte page). +# $(1): the partition data size +define image-size-from-data-size +$(shell echo $$(($(1) / 2048 * (2048+64)))) +endef + +# $(1): The file(s) to check (often $@) +# $(2): The maximum total image size, in decimal bytes # # If $(2) is empty, evaluates to "true" # @@ -1550,19 +1558,21 @@ endif # next whole flash block size. define assert-max-file-size $(if $(2), \ - fileSize=`$(call get-file-size,$(1))`; \ - maxSize=$(2); \ - onePct=`expr "(" $$maxSize + 99 ")" / 100`; \ - onePct=`expr "(" "(" $$onePct + $(BOARD_FLASH_BLOCK_SIZE) - 1 ")" / \ - $(BOARD_FLASH_BLOCK_SIZE) ")" "*" $(BOARD_FLASH_BLOCK_SIZE)`; \ - reserve=`expr 2 "*" $(BOARD_FLASH_BLOCK_SIZE)`; \ - if [ "$$onePct" -gt "$$reserve" ]; then \ - reserve="$$onePct"; \ + size=$$(for i in $(1); do $(call get-file-size,$$i); done); \ + total=$$(( $$( echo "$$size" | tr '\n' + ; echo 0 ) )); \ + printname=$$(echo -n "$(1)" | tr " " +); \ + echo "$$printname total size is $$total"; \ + img_blocksize=$(call image-size-from-data-size,$(BOARD_FLASH_BLOCK_SIZE)); \ + twoblocks=$$((img_blocksize * 2)); \ + onepct=$$((((($(2) / 100) - 1) / img_blocksize + 1) * img_blocksize)); \ + reserve=$$((twoblocks > onepct ? twoblocks : onepct)); \ + maxsize=$$(($(2) - reserve)); \ + if [ "$$total" -gt "$$maxsize" ]; then \ + echo "error: $$printname too large ($$total > [$(2) - $$reserve])"; \ + false; \ fi; \ - maxSize=`expr $$maxSize - $$reserve`; \ - if [ "$$fileSize" -gt "$$maxSize" ]; then \ - echo "error: $(1) too large ($$fileSize > [$(2) - $$reserve])"; \ - false; \ + if [ "$$total" -gt $$((maxsize - 32768)) ]; then \ + echo "WARNING: $$printname approaching size limit ($$total now; limit $$maxsize)"; \ fi \ , \ true \