赞
踩
最初加入了MTK_AB_OTA_UPDATER = yes
去除cache分区编译的控制开关
ifneq ($(strip $(MTK_AB_OTA_UPDATER)), yes)
BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
endif
diff --git a/mediateksample/k39tv1_64_bsp/BoardConfig.mk b/mediateksample/k39tv1_64_bsp/BoardConfig.mk index 13eb004..fd32381 100644 --- a/mediateksample/k39tv1_64_bsp/BoardConfig.mk +++ b/mediateksample/k39tv1_64_bsp/BoardConfig.mk @@ -6,10 +6,11 @@ include device/mediatek/mt6739/BoardConfig.mk #Config partition size -include $(MTK_PTGEN_OUT)/partition_size.mk +ifneq ($(strip $(MTK_AB_OTA_UPDATER)), yes) BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4 +endif BOARD_FLASH_BLOCK_SIZE := 4096 - MTK_INTERNAL_CDEFS := $(foreach t,$(AUTO_ADD_GLOBAL_DEFINE_BY_NAME),$(if $(filter-out no NO none NONE false FALSE,$($(t))),-D$(t))) MTK_INTERNAL_CDEFS += $(foreach t,$(AUTO_ADD_GLOBAL_DEFINE_BY_VALUE),$(if $(filter-out no NO none NONE false FALSE,$($(t))),$(foreach v,$(shell echo $($(t)) | tr '[a-z]' '[A-Z]'),-D$(v)))) MTK_INTERNAL_CDEFS += $(foreach t,$(AUTO_ADD_GLOBAL_DEFINE_BY_NAME_VALUE),$(if $(filter-out no NO none NONE false FALSE,$($(t))),-D$(t)=\"$(strip $($(t)))\")) diff --git a/mediateksample/k39tv1_64_bsp/ProjectConfig.mk b/mediateksample/k39tv1_64_bsp/ProjectConfig.mk index 99aebd3..3419c65 100755 --- a/mediateksample/k39tv1_64_bsp/ProjectConfig.mk +++ b/mediateksample/k39tv1_64_bsp/ProjectConfig.mk @@ -685,7 +685,8 @@ TRUSTONIC_TEE_SUPPORT = no USE_FRAUNHOFER_AAC = no USE_XML_AUDIO_POLICY_CONF = 1 WIFI_WEP_KEY_ID_SET = no -MTK_AB_OTA_UPDATER = no +CONFIG_MTK_AB_OTA_UPDATER = yes +MTK_AB_OTA_UPDATER = yes
搜索宏控相关文件如下
libiaobiao:~/code/s219_ab/device$ grep -rni "MTK_AB_OTA_UPDATER" mediateksample/k39tv1_64_bsp/BoardConfig.mk:9:ifneq ($(strip $(MTK_AB_OTA_UPDATER)), yes) mediateksample/k39tv1_64_bsp/ProjectConfig.mk:688:CONFIG_MTK_AB_OTA_UPDATER = yes mediateksample/k39tv1_64_bsp/ProjectConfig.mk:689:MTK_AB_OTA_UPDATER = yes mediatek/common/device.mk:3643:ifeq ($(strip $(MTK_AB_OTA_UPDATER)), yes) mediatek/common/BoardConfig.mk:228: ifeq ($(strip $(MTK_AB_OTA_UPDATER)), yes) mediatek/mt6739/BoardConfig.mk:132:ifneq ($(strip $(MTK_AB_OTA_UPDATER)),yes) mediatek/build/build/tools/ptgen/MT6739/ptgen.mk:71: MTK_AB_OTA_UPDATER=${MTK_AB_OTA_UPDATER} \ mediatek/build/build/tools/ptgen/MT6739/ptgen.pl:195: $ArgList{MTK_AB_OTA_UPDATER} = $ENV{MTK_AB_OTA_UPDATER}; mediatek/build/build/tools/ptgen/MT6739/ptgen.pl:260: if ($ArgList{MTK_AB_OTA_UPDATER} eq "yes") mediatek/build/build/tools/ptgen/MT6739/ptgen.pl:271: if ($ArgList{MTK_AB_OTA_UPDATER} eq "yes") mediatek/build/build/tools/ptgen/MT6739/ptgen.pl:768: if ($ArgList{MTK_AB_OTA_UPDATER} eq "yes") mediatek/build/build/tools/partition/gen-partition.py:123: if os.getenv("MTK_AB_OTA_UPDATER") == "yes":
# A/B System updates ifeq ($(strip $(MTK_AB_OTA_UPDATER)), yes) # Squashfs config system文件格式使用squashfs,这是与ext4不同的格式,目前没用到 #BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE := squashfs #PRODUCT_PACKAGES += mksquashfs #PRODUCT_PACKAGES += mksquashfsimage.sh #PRODUCT_PACKAGES += libsquashfs_utils #将recovery ramdisk放到boot.img文件内 BOARD_USES_RECOVERY_AS_BOOT := true #不再编译recovery.img TARGET_NO_RECOVERY := true #打开AB_OTA_UPDATER宏,这个本身是google原生的打开AB的主控开 AB_OTA_UPDATER := true # A/B OTA partitions AB升级中可升级的分区 AB_OTA_PARTITIONS := \ boot \ system \ lk \ preloader #编译update_engine update_verifier brillo_update_payload模块 PRODUCT_PACKAGES += \ update_engine \ shflags \ delta_generator \ bsdiff \ brillo_update_payload \ update_engine_sideload \ update_verifier \ #这两个时debug的调试工具update_engine_client 可以在adblog中输出升级流程 #bootctl是boot_control模块调用的工具,可以通过命令调用接口 PRODUCT_PACKAGES_DEBUG += \ update_engine_client \ bootctl # bootctrl HAL and HIDL 编译启动相关的bootctrl hal层 PRODUCT_PACKAGES += \ bootctrl.$(MTK_PLATFORM_DIR) \ android.hardware.boot@1.0-impl \ android.hardware.boot@1.0-service PRODUCT_STATIC_BOOT_CONTROL_HAL := bootctrl.$(MTK_PLATFORM_DIR) # A/B OTA dexopt package PRODUCT_PACKAGES += otapreopt_script # Install odex files into the other system image #编译了system_other 并将odex文件放入 BOARD_USES_SYSTEM_OTHER_ODEX := true # A/B OTA dexopt update_engine hookup AB_OTA_POSTINSTALL_CONFIG += \ RUN_POSTINSTALL_system=true \ POSTINSTALL_PATH_system=system/bin/otapreopt_script \ FILESYSTEM_TYPE_system=ext4 \ POSTINSTALL_OPTIONAL_system=true # Tell the system to enable copying odexes from other partition. PRODUCT_PACKAGES += \ cppreopts.sh PRODUCT_PROPERTY_OVERRIDES += \ ro.cp_system_other_odex=1 DEVICE_MANIFEST_FILE += device/mediatek/common/project_manifest/manifest_boot.xml endif #下面一个单独的判断,定义是否将rootfs放入system, ifneq ($(strip $(SYSTEM_AS_ROOT)), no) BOARD_BUILD_SYSTEM_ROOT_IMAGE := true endif
这部分的修改与odex化的编译有关,以下时相关的资料
开odex优化首次开机速度,是牺牲空间换取时间的做法,仅限于空间足够的设备。开了odex之后,在编译的时候,整个system image就会被预先优化。由于在启动时不再需要进行app的dex文件进行优化(dex2oat操作)从而提升其启动速度。
关于odex,有几个下面几个宏开关:
1、WITH_DEXPREOPT
这个开关在6.0 USER版本上是默认开启的,意思就是USER版本要开odex预编译。会导致system image中的所有东西都被提前优化(pre-optimized)。这可能导致system image非常大。
那么问题就来了,既然 WITH_DEXPREOPT := true 默认开启,那么为什么首次启动依然耗时很长呢?这个就和第二个宏开关——DONT_DEXPREOPT_PREBUILTS有关了。
2、DONT_DEXPREOPT_PREBUILTS
如果我们不想把prebuilts目录中的第三方应用进行预先优化(这些应用在他们的Android.mk文件中有include$(BUILD_PREBUILT) ),而是希望这些app通过playstore 或者app提供商进行升级,那么我们可以打开这个宏开关。
事实上,6.0上面,这个宏开关也是默认开启的。我们全局搜索一下“(BUILD_PREBUILT) ”会发现很多结果,这也就是为什么默认odex都开了,为什么开机并没有觉得快的原因了。
因此我们在做odex优化的时候,都会关闭DONT_DEXPREOPT_PREBUILTS,然后重新给我们预置的App添加 LOCAL_DEX_PREOPT :=false 让它们不进行预编译,这样也就能节省一些不必要的空间消耗。同时因为关闭了DONT_DEXPREOPT_PREBUILTS,很多可以随ROM升级的系统App也就进行了预编译,因此开机速度就有了明显的提高。
开AB后DONT_DEXPREOPT_PREBUILTS :=false 看到这里其实看不出什么,后面分析Makefile可以看出具体生成,不过暂时根据out下生成的system 和 system_other system下面是单独的APK 而system_other是单独的odex和vdex,
ifeq ($(BUILD_GMS),yes) ifeq ($(strip $(MTK_AB_OTA_UPDATER)), yes) DONT_DEXPREOPT_PREBUILTS := false else DONT_DEXPREOPT_PREBUILTS := true endif else ifeq ($(TARGET_BUILD_VARIANT),userdebug) DEX_PREOPT_DEFAULT := nostripping endif endif
以下是谷歌原生文档关于该宏的介绍,如果打开AB升级,将会关闭该宏
在非 A/B 设备的恢复映像中添加 DTBO
为防止非 A/B 设备上出现 OTA 失败的情况,恢复分区必须“自给自足”,不得依赖于其他分区。
启动到恢复模式时,引导加载程序必须加载与恢复映像兼容的 DTBO 映像。在执行 OTA 期间,如果在 DTBO 映像更新后(但在完成全部更新之前)出现问题,设备将尝试启动到恢复模式,以完成 OTA。不过,由于 DTBO 分区已更新,恢复映像(尚未更新)可能会出现不匹配的情况。
为防止出现这种情况,在 Android 9 中,恢复映像也必须包含来自 DTBO 映像的信息。非 A/B 设备的恢复映像还必须包含附加到内核的设备 DTB,以便在更新期间不依赖于 DTB 分区。
实现
虽然搭载 Android 9 的所有设备都必须使用新的启动映像标头(版本 1),但只有非 A/B 设备才必须填充恢复映像的 recovery_dtbo
部分。要在 BoardConfig.mk
设备的 recovery.img
中添加 recovery_dtbo
,请执行以下操作:
BOARD_INCLUDE_RECOVERY_DTBO
配置设置为 true
:BOARD_INCLUDE_RECOVERY_DTBO := true
BOARD_MKBOOTIMG_ARGS
变量以指定启动映像标头版本:BOARD_MKBOOTIMG_ARGS := --ramdisk_offset $(BOARD_RAMDISK_OFFSET) --tags_offset $(BOARD_KERNEL_TAGS_OFFSET) --header_version $(BOARD_BOOTIMG_HEADER_VERSION)
BOARD_PREBUILT_DTBOIMAGE
变量设置为 DTBO 映像的路径。Android 编译系统会使用该变量在创建恢复映像时设置 mkbootimg 工具的 recovery_dtbo
参数。BOARD_INCLUDE_RECOVERY_DTBO
、BOARD_MKBOOTIMG_ARGS
和 BOARD_PREBUILT_DTBOIMAGE
均正确设置,Android 编译系统会将变量 BOARD_PREBUILT_DTBOIMAGE
指定的 DTBO 添加到 recovery.img
中。ifeq ($(strip $(MTK_DTBO_FEATURE)),yes) ifeq ($(strip $(MTK_DTBO_UPGRADE_FROM_ANDROID_O)), yes) BOARD_PREBUILT_DTBOIMAGE := $(MTK_PTGEN_PRODUCT_OUT)/obj/PACKAGING/dtboimage/odmdtbo.img else BOARD_PREBUILT_DTBOIMAGE := $(MTK_PTGEN_PRODUCT_OUT)/obj/PACKAGING/dtboimage/dtbo.img endif ifneq ($(strip $(MTK_AB_OTA_UPDATER)),yes) BOARD_INCLUDE_RECOVERY_DTBO := true endif endif
mediatek/build/build/tools/ptgen/MT6739/ptgen.mk
MTK分区表存放位置:device/mediatek/build/build/tools/ptgen/xxx/xxx.xls
ptgen.pl文件会把xls文件解析成xxxAndroid_scatter.txt放在out/target/product/xxx/中
mtk的flashtool工具会读取这个文件把相关的镜像烧写到rom中
这里是根据判断选择对应分区文件,如果开了MTK_AB_OTA_UPDATER,选择我们emmc_ab的分区表,否则选择emmc的
$Partition_layout_xls = "$ptgen_location/partition_table_$ArgList{PLATFORM}"; if ($ArgList{EMMC_SUPPORT} eq "yes") { if ($ArgList{MTK_AB_OTA_UPDATER} eq "yes") { $ArgList{SHEET_NAME} = "emmc_ab"; } else { $ArgList{SHEET_NAME} = "emmc"; } } elsif ($ArgList{UFS_BOOTING} eq "yes") { if ($ArgList{MTK_AB_OTA_UPDATER} eq "yes") { $ArgList{SHEET_NAME} = "ufs_ab"; } else { $ArgList{SHEET_NAME} = "ufs"; } } else { $ArgList{SHEET_NAME} = "nand"; } }
device修改很多开关主要作用时更改image的生成,而这部分全部是在makefile中,这是我们主要分析的文件,继续开车
ifeq (,$(filter true, $(TARGET_NO_KERNEL) $(TARGET_NO_RECOVERY))) INSTALLED_RECOVERYIMAGE_TARGET := $(PRODUCT_OUT)/recovery.img else INSTALLED_RECOVERYIMAGE_TARGET := endif
device.mk中定义了TARGET_NO_RECOVERY := true 由于TARGET_NO_KERNEL :=false ,所以条件不成立,
INSTALLED_RECOVERYIMAGE_TARGET :=,也就是不再生成recovery.img
INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img MTK_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img INSTALLED_BOOTIMAGE_TARGET := $(call intermediates-dir-for,PACKAGING,boot)/boot.img #这里判断条件较多,不过android对那个if 对应那个endif 还进行了标注,方便我们查看代码 #TARGET_NO_KERNEL 如果是true 条件不成立,这里我加了打印,其实它的值是 fasle,进入if条件 ifneq ($(strip $(TARGET_NO_KERNEL)),true) $(warning "TARGET_NO_KERNEL is not supported anymore") # ----------------------------------------------------------------- # the boot image, which is a collection of other images. INTERNAL_BOOTIMAGE_ARGS := \ $(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET)) \ --kernel $(INSTALLED_KERNEL_TARGET) ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true) INTERNAL_BOOTIMAGE_ARGS += --ramdisk $(INSTALLED_RAMDISK_TARGET) endif INTERNAL_BOOTIMAGE_FILES := $(filter-out --%,$(INTERNAL_BOOTIMAGE_ARGS)) ifdef BOARD_KERNEL_BASE INTERNAL_BOOTIMAGE_ARGS += --base $(BOARD_KERNEL_BASE) endif ifdef BOARD_KERNEL_PAGESIZE INTERNAL_BOOTIMAGE_ARGS += --pagesize $(BOARD_KERNEL_PAGESIZE) endif ifeq ($(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY),true) ifeq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true) VERITY_KEYID := veritykeyid=id:`openssl x509 -in $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).x509.pem -text \ | grep keyid | sed 's/://g' | tr -d '[:space:]' | tr '[:upper:]' '[:lower:]' | sed 's/keyid//g'` endif endif INTERNAL_KERNEL_CMDLINE := $(strip $(BOARD_KERNEL_CMDLINE) buildvariant=$(TARGET_BUILD_VARIANT) $(VERITY_KEYID)) ifdef INTERNAL_KERNEL_CMDLINE INTERNAL_BOOTIMAGE_ARGS += --cmdline "$(INTERNAL_KERNEL_CMDLINE)" endif INTERNAL_MKBOOTIMG_VERSION_ARGS := \ --os_version $(PLATFORM_VERSION) \ --os_patch_level $(PLATFORM_SECURITY_PATCH) # BOARD_USES_RECOVERY_AS_BOOT = true must have BOARD_BUILD_SYSTEM_ROOT_IMAGE = true. #这里的意思是说BOARD_USES_RECOVERY_AS_BOOT和BOARD_BUILD_SYSTEM_ROOT_IMAGE必须同时定义 ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true) ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true) $(error BOARD_BUILD_SYSTEM_ROOT_IMAGE must be enabled for BOARD_USES_RECOVERY_AS_BOOT.) endif endif # We build recovery as boot image if BOARD_USES_RECOVERY_AS_BOOT is true. #如果BOARD_USES_RECOVERY_AS_BOOT为true,不走下面所有的代码,所以开启这个宏后,普通生成boot.img #的代码将全部失效 ifneq ($(BOARD_USES_RECOVERY_AS_BOOT),true) ifeq ($(TARGET_BOOTIMAGE_USE_EXT2),true) $(error TARGET_BOOTIMAGE_USE_EXT2 is not supported anymore) else ifeq (true,$(BOARD_AVB_ENABLE)) # TARGET_BOOTIMAGE_USE_EXT2 != true $(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(AVBTOOL) $(INTERNAL_BOOTIMAGE_FILES) $(BOARD_AVB_BOOT_KEY_PATH) $(call pretty,"Target boot image: $@") $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@ $(hide) $(call assert-max-image-size,$@,$(call get-hash-image-max-size,$(BOARD_BOOTIMAGE_PARTITION_SIZE))) $(hide) $(AVBTOOL) add_hash_footer \ --image $@ \ --partition_size $(BOARD_BOOTIMAGE_PARTITION_SIZE) \ --partition_name boot $(INTERNAL_AVB_BOOT_SIGNING_ARGS) \ $(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS) .PHONY: bootimage-nodeps bootimage-nodeps: $(MKBOOTIMG) $(AVBTOOL) $(BOARD_AVB_BOOT_KEY_PATH) @echo "make $@: ignoring dependencies" $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(INSTALLED_BOOTIMAGE_TARGET) $(hide) $(call assert-max-image-size,$(INSTALLED_BOOTIMAGE_TARGET),$(call get-hash-image-max-size,$(BOARD_BOOTIMAGE_PARTITION_SIZE))) $(hide) $(AVBTOOL) add_hash_footer \ --image $(INSTALLED_BOOTIMAGE_TARGET) \ --partition_size $(BOARD_BOOTIMAGE_PARTITION_SIZE) \ --partition_name boot $(INTERNAL_AVB_BOOT_SIGNING_ARGS) \ $(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS) else ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_BOOT_SIGNER)) # BOARD_AVB_ENABLE != true $(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES) $(BOOT_SIGNER) $(call pretty,"Target boot image: $@") $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@ $(BOOT_SIGNER) /boot $@ $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).pk8 $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).x509.pem $@ $(hide) $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE)) .PHONY: bootimage-nodeps bootimage-nodeps: $(MKBOOTIMG) $(BOOT_SIGNER) @echo "make $@: ignoring dependencies" $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(INSTALLED_BOOTIMAGE_TARGET) $(BOOT_SIGNER) /boot $(INSTALLED_BOOTIMAGE_TARGET) $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).pk8 $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).x509.pem $(INSTALLED_BOOTIMAGE_TARGET) $(hide) $(call assert-max-image-size,$(INSTALLED_BOOTIMAGE_TARGET),$(BOARD_BOOTIMAGE_PARTITION_SIZE)) else ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT)) # PRODUCT_SUPPORTS_BOOT_SIGNER != true $(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES) $(VBOOT_SIGNER) $(FUTILITY) $(call pretty,"Target boot image: $@") $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@.unsigned $(VBOOT_SIGNER) $(FUTILITY) $@.unsigned $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_KEY).vbpubk $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_KEY).vbprivk $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_SUBKEY).vbprivk $@.keyblock $@ $(hide) $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE)) .PHONY: bootimage-nodeps bootimage-nodeps: $(MKBOOTIMG) $(VBOOT_SIGNER) $(FUTILITY) @echo "make $@: ignoring dependencies" $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(INSTALLED_BOOTIMAGE_TARGET).unsigned $(VBOOT_SIGNER) $(FUTILITY) $(INSTALLED_BOOTIMAGE_TARGET).unsigned $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_KEY).vbpubk $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_KEY).vbprivk $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VBOOT_SIGNING_SUBKEY).vbprivk $(INSTALLED_BOOTIMAGE_TARGET).keyblock $(INSTALLED_BOOTIMAGE_TARGET) $(hide) $(call assert-max-image-size,$(INSTALLED_BOOTIMAGE_TARGET),$(BOARD_BOOTIMAGE_PARTITION_SIZE)) else # PRODUCT_SUPPORTS_VBOOT != true $(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES) $(call pretty,"Target boot image: $@") $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@ $(hide) $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE)) .PHONY: bootimage-nodeps bootimage-nodeps: $(MKBOOTIMG) @echo "make $@: ignoring dependencies" $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $(INSTALLED_BOOTIMAGE_TARGET) $(hide) $(call assert-max-image-size,$(INSTALLED_BOOTIMAGE_TARGET),$(BOARD_BOOTIMAGE_PARTITION_SIZE)) #这里是对每个判断条件的结尾进行了注释 endif # TARGET_BOOTIMAGE_USE_EXT2 endif # BOARD_USES_RECOVERY_AS_BOOT else # TARGET_NO_KERNEL
根据代码的判断,因为BOARD_USES_RECOVERY_AS_BOOT 为true 所以不走普通的生成方式,那么真正生成boot.img是在哪里呢,字面翻译这个宏的意思时说我们要用recovery作为现在的boot,代码如下
#条件成立,进入ifeq ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true) #添加依赖BOOT_SIGNER ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_BOOT_SIGNER)) $(INSTALLED_BOOTIMAGE_TARGET) : $(BOOT_SIGNER) endif #添加依赖VBOOT_SIGNER ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VBOOT)) $(INSTALLED_BOOTIMAGE_TARGET) : $(VBOOT_SIGNER) endif #添加依赖AVBTOOL BOARD_AVB_BOOT_KEY_PATH ifeq (true,$(BOARD_AVB_ENABLE)) $(INSTALLED_BOOTIMAGE_TARGET) : $(AVBTOOL) $(BOARD_AVB_BOOT_KEY_PATH) endif #具体生成boot的部分,添加依赖,并调用build-recoveryimage-target 生成boot.img $(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) $(ADBD) \ $(INSTALLED_RAMDISK_TARGET) \ $(INTERNAL_RECOVERYIMAGE_FILES) \ $(recovery_initrc) $(recovery_sepolicy) $(recovery_kernel) \ $(INSTALLED_2NDBOOTLOADER_TARGET) \ $(recovery_build_props) $(recovery_resource_deps) \ $(recovery_fstab) \ $(RECOVERY_INSTALL_OTA_KEYS) \ $(INSTALLED_VENDOR_DEFAULT_PROP_TARGET) \ $(BOARD_RECOVERY_KERNEL_MODULES) \ $(DEPMOD) $(call pretty,"Target boot image from recovery: $@") $(call build-recoveryimage-target, $@) endif #以下是生成recovery.img的代码,其实跟上面是一模一样的 $(INSTALLED_RECOVERYIMAGE_TARGET): $(MKBOOTFS) $(MKBOOTIMG) $(MINIGZIP) $(ADBD) \ $(INSTALLED_RAMDISK_TARGET) \ $(INSTALLED_BOOTIMAGE_TARGET) \ $(INTERNAL_RECOVERYIMAGE_FILES) \ $(recovery_initrc) $(recovery_sepolicy) $(recovery_kernel) \ $(INSTALLED_2NDBOOTLOADER_TARGET) \ $(recovery_build_props) $(recovery_resource_deps) \ $(recovery_fstab) \ $(RECOVERY_INSTALL_OTA_KEYS) \ $(INSTALLED_VENDOR_DEFAULT_PROP_TARGET) \ $(BOARD_RECOVERY_KERNEL_MODULES) \ $(DEPMOD) $(call build-recoveryimage-target, $@)
device.mk中定义了BOARD_USES_RECOVERY_AS_BOOT :=true,所以不再走原来生成boot.img的流程,使用生成recovery.img的方法打包成boot.img
# ----------------------------------------------------------------- # cache partition image #因为我们更改了BoardConfig.mk,所以BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE没有定义,不再生成cache.img ifdef BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE INTERNAL_CACHEIMAGE_FILES := \ $(filter $(TARGET_OUT_CACHE)/%,$(ALL_DEFAULT_INSTALLED_MODULES)) cacheimage_intermediates := \ $(call intermediates-dir-for,PACKAGING,cache) BUILT_CACHEIMAGE_TARGET := $(PRODUCT_OUT)/cache.img define build-cacheimage-target $(call pretty,"Target cache fs image: $(INSTALLED_CACHEIMAGE_TARGET)") @mkdir -p $(TARGET_OUT_CACHE) @mkdir -p $(cacheimage_intermediates) && rm -rf $(cacheimage_intermediates)/cache_image_info.txt $(call generate-userimage-prop-dictionary, $(cacheimage_intermediates)/cache_image_info.txt, skip_fsck=true) $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \ build/make/tools/releasetools/build_image.py \ $(TARGET_OUT_CACHE) $(cacheimage_intermediates)/cache_image_info.txt $(INSTALLED_CACHEIMAGE_TARGET) $(TARGET_OUT) $(hide) $(call assert-max-image-size,$(INSTALLED_CACHEIMAGE_TARGET),$(BOARD_CACHEIMAGE_PARTITION_SIZE)) endef # We just build this directly to the install location. INSTALLED_CACHEIMAGE_TARGET := $(BUILT_CACHEIMAGE_TARGET) $(INSTALLED_CACHEIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_CACHEIMAGE_FILES) $(BUILD_IMAGE_SRCS) $(build-cacheimage-target) .PHONY: cacheimage-nodeps cacheimage-nodeps: | $(INTERNAL_USERIMAGES_DEPS) $(build-cacheimage-target) else # BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE # we need to ignore the broken cache link when doing the rsync #我们需要在执行rsync时忽略已损坏的缓存链接 IGNORE_CACHE_LINK := --exclude=cache endif # BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE
BoardConfig.mk中更改了代码
ifneq ($(strip $(MTK_AB_OTA_UPDATER)), yes)
BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
endif
BOARD_FLASH_BLOCK_SIZE := 4096
所以生成cache.img的方法将不再执行,并忽略与cache相关的损坏的链接
# $(1): output file define build-systemimage-target @echo "Target system fs image: $(1)" #调用$(call create-system-vendor-symlink)创建符号链接 $(call create-system-vendor-symlink) #调用$(call create-system-product-symlink)创建符号链接 $(call create-system-product-symlink) #删除之前的system_image_info.txt @mkdir -p $(dir $(1)) $(systemimage_intermediates) && rm -rf $(systemimage_intermediates)/system_image_info.txt #调用call generate-userimage-prop-dictionary,重新生成system_image_info.txt $(call generate-userimage-prop-dictionary, $(systemimage_intermediates)/system_image_info.txt, \ skip_fsck=true) #调用build_image.py 传入system_image_info.txt和$(PRODUCT_OUT)/system创建system.img文件 $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \ build/make/tools/releasetools/build_image.py \ $(TARGET_OUT) $(systemimage_intermediates)/system_image_info.txt $(1) $(TARGET_OUT) \ || ( echo "Out of space? the tree size of $(TARGET_OUT) is (MB): " 1>&2 ;\ du -sm $(TARGET_OUT) 1>&2;\ if [ "$(INTERNAL_USERIMAGES_EXT_VARIANT)" == "ext4" ]; then \ maxsize=$(BOARD_SYSTEMIMAGE_PARTITION_SIZE); \ echo "The max is $$(( maxsize / 1048576 )) MB." 1>&2 ;\ else \ echo "The max is $$(( $(BOARD_SYSTEMIMAGE_PARTITION_SIZE) / 1048576 )) MB." 1>&2 ;\ fi; \ mkdir -p $(DIST_DIR); cp $(INSTALLED_FILES_FILE) $(DIST_DIR)/installed-files-rescued.txt; \ exit 1 ) endef $(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE) $(BUILD_IMAGE_SRCS) $(call build-systemimage-target,$@) INSTALLED_SYSTEMIMAGE := $(PRODUCT_OUT)/system.img SYSTEMIMAGE_SOURCE_DIR := $(TARGET_OUT)
这部分在之前分析make 生成 system.img时候提到过,传入的info文件将决定system.img中打包的内容
# $(1): the path of the output dictionary file # $(2): additional "key=value" pairs to append to the dictionary file. #调用该方法生成system_image_info.txt,其中BOARD_BUILD_SYSTEM_ROOT_IMAGE 宏是打开的会将如下两个值 #写入到info文件中 define generate-userimage-prop-dictionary $(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
ext_mkuserimg=mkuserimg_mke2fs.sh fs_type=ext4 system_size=2684354560 userdata_size=3221225472 vendor_fs_type=ext4 vendor_size=578813952 extfs_sparse_flag=-s squashfs_sparse_flag=-s selinux_fc=out/target/product/k39tv1_64_bsp/obj/ETC/file_contexts.bin_intermediates/file_contexts.bin boot_signer=true verity=true verity_key=build/target/product/security/verity verity_signer_cmd=verity_signer verity_fec=true system_verity_block_device=/dev/block/platform/bootdevice/by-name/system vendor_verity_block_device=/dev/block/platform/bootdevice/by-name/vendor recovery_as_boot=true system_root_image=true ramdisk_dir=out/target/product/k39tv1_64_bsp/root skip_fsck=true
这两个参数的加入
system_root_image=true
ramdisk_dir=out/target/product/k39tv1_64_bsp/root
决定了真正最后生成的system.img文件会将ramdisk和filesystem一并打包,也就是说目前的system.img包含了rootfs(查看9.0的代码可以发现,即使是非ab,也有这两个参数从存在了)
# ----------------------------------------------------------------- # system_other partition image #该BOARD_USES_SYSTEM_OTHER_ODEX打开后 会设定BOARD_USES_SYSTEM_OTHER 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 #BOARD_USES_SYSTEM_OTHER该宏为true,进入if生成system_other.img ifdef BOARD_USES_SYSTEM_OTHER INTERNAL_SYSTEMOTHERIMAGE_FILES := \ $(filter $(TARGET_OUT_SYSTEM_OTHER)/%,\ $(ALL_DEFAULT_INSTALLED_MODULES)\ $(ALL_PDK_FUSION_FILES)) \ $(PDK_FUSION_SYMLINK_STAMP) INSTALLED_FILES_FILE_SYSTEMOTHER := $(PRODUCT_OUT)/installed-files-system-other.txt $(INSTALLED_FILES_FILE_SYSTEMOTHER) : $(INTERNAL_SYSTEMOTHERIMAGE_FILES) $(FILESLIST) @echo Installed file list: $@ @mkdir -p $(dir $@) @rm -f $@ $(hide) $(FILESLIST) $(TARGET_OUT_SYSTEM_OTHER) > $(@:.txt=.json) $(hide) build/make/tools/fileslist_util.py -c $(@:.txt=.json) > $@ 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/make/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) ifneq (true,$(SANITIZE_LITE)) # Only create system_other when not building the second stage of a SANITIZE_LITE build. $(INSTALLED_SYSTEMOTHERIMAGE_TARGET): $(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_SYSTEMOTHERIMAGE_FILES) $(INSTALLED_FILES_FILE_SYSTEMOTHER) $(build-systemotherimage-target) endif .PHONY: systemotherimage-nodeps systemotherimage-nodeps: | $(INTERNAL_USERIMAGES_DEPS) $(build-systemotherimage-target) endif # BOARD_USES_SYSTEM_OTHER
device.mk打开ab后定义了生成system_other相关的宏# A/B BOARD_USES_SYSTEM_OTHER_ODEX := true,将system/app 和 system/priv-app下的odex文件存储到system_other.img中
这个img的生成有什么作用呢,查到这样一个说明
50% of system image is precompiled odex files (-2048MiB)
意思是说将原来system里面的odex文件放到system_other.img中,刷机的时候放入B分区,并在首次开机的时候拷贝到data区进行预加载,这样ab升级中的system分区与非ab的情况一样,目的是为了减小system分区的大小,不过百分之50有些夸张了,我们编译出来的实际只有100多M,
开启AB升级方案的项目,因为很多需要升级的镜像都有两份,所以存储空间将会增大。为缓解此问题,有个针对odex的优化方案。
编译版本会生成两个system镜像:system.img和system_other.img,其中,system_other.img中存储的就是odex文件,这样system.img就能小很多,意味着可以为system分区划分较小的空间。
在首次开机时,假设system.img镜像存储在A slot,那么此时的B slot是闲置的。所以可以把system.img刷入A slot的system分区,把system_other.img刷入B slot的system分区。在首次开机时,再把system_other.img中的odex文件拷贝到data分区。
6、vendor.img 和 userdata.img
这两个img的生成在打开ab后没有变化,生成流程于system.img相同,根据对应info,调用build_image.py生成对应的文件
make/tools/buildinfo.sh加入
if [ -n "$AB_OTA_UPDATER" ] ; then
echo "ro.build.ab_update=$AB_OTA_UPDATER"
fi
Makefile中会执行buildinfo.sh文件
$(intermediate_system_build_prop): $(BUILDINFO_SH) $(INTERNAL_BUILD_ID_MAKEFILE) $(BUILD_SYSTEM)/version_defaults.mk $(system_prop_file) $(INSTALLED_ANDROID_INFO_TXT_TARGET) ...... ...... bash $(BUILDINFO_SH) >> $@
system/build.prop中增加:ro.build.ab_update=true
# Carry the public key for update_engine if it's a non-IoT target that # uses the AB updater. We use the same key as otacerts but in RSA public key # format. #如果update_engine是非IoT目标,则携带公钥 #使用AB更新程序。 我们使用与otacerts相同的密钥但使用RSA公钥format。 ifeq ($(AB_OTA_UPDATER),true) ifneq ($(PRODUCT_IOT),true) ALL_DEFAULT_INSTALLED_MODULES += $(TARGET_OUT_ETC)/update_engine/update-payload-key.pub.pem $(TARGET_OUT_ETC)/update_engine/update-payload-key.pub.pem: $(addsuffix .x509.pem,$(DEFAULT_KEY_CERT_PAIR)) $(hide) rm -f $@ $(hide) mkdir -p $(dir $@) $(hide) openssl x509 -pubkey -noout -in $< > $@ ALL_DEFAULT_INSTALLED_MODULES += $(TARGET_RECOVERY_ROOT_OUT)/etc/update_engine/update-payload-key.pub.pem $(TARGET_RECOVERY_ROOT_OUT)/etc/update_engine/update-payload-key.pub.pem: $(TARGET_OUT_ETC)/update_engine/update-payload-key.pub.pem $(hide) cp -f $< $@ endif endif
#指定对应依赖 这个built_ota_tools其实生成的就是updater,如果是ab升级,obj包里不需要打包这个文件 ifeq ($(AB_OTA_UPDATER),true) updater_dep := system/update_engine/update_engine.conf else # Build OTA tools if not using the AB Updater. updater_dep := $(built_ota_tools) endif $(BUILT_TARGET_FILES_PACKAGE): $(updater_dep)
$(BUILT_TARGET_FILES_PACKAGE): ...... ...... #如果是非AB,拷贝对应image和生成ota_update_list.txt,如果是ab,生成ab_partitions.txt,拷贝对应image @# Copy raw images which need OTA updates from out folder to zip_root/IMAGES folder $(hide) BOARD_AVB_ENABLE="$(BOARD_AVB_ENABLE)" AB_OTA_UPDATER="$(AB_OTA_UPDATER)" AB_OTA_PARTITIONS="$(AB_OTA_PARTITIONS)" $(TARGET_RELEASETOOLS_EXTENSIONS)/mt_ota_preprocess.py $(zip_root) $(PRODUCT_OUT) $(PRODUCT_OUT)/ota_update_list.txt ifneq ($(INSTALLED_RECOVERYIMAGE_TARGET),) $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH MKBOOTIMG=$(MKBOOTIMG) \ build/make/tools/releasetools/make_recovery_patch $(zip_root) $(zip_root) endif ifeq ($(AB_OTA_UPDATER),true) @# When using the A/B updater, include the updater config files in the zip. #拷贝update_engine.conf 到META/update_engine_config.txt $(hide) cp $(TOPDIR)system/update_engine/update_engine.conf $(zip_root)/META/update_engine_config.txt $(hide) for part in $(AB_OTA_PARTITIONS); do \ #把AB_OTA_PARTITIONS定义的分区拷贝到META/ab_partitions.txt echo "$${part}" >> $(zip_root)/META/ab_partitions.txt; \ done $(hide) for conf in $(AB_OTA_POSTINSTALL_CONFIG); do \ #把AB_OTA_POSTINSTALL_CONFIG定义的内容拷贝到META/postinstall_config.txt echo "$${conf}" >> $(zip_root)/META/postinstall_config.txt; \ done @# Include the build type in META/misc_info.txt so the server can easily differentiate production builds. #build_type放入misc_info $(hide) echo "build_type=$(TARGET_BUILD_VARIANT)" >> $(zip_root)/META/misc_info.txt #ab_update放入misc_info $(hide) echo "ab_update=true" >> $(zip_root)/META/misc_info.txt ifdef BRILLO_VENDOR_PARTITIONS $(hide) mkdir -p $(zip_root)/VENDOR_IMAGES $(hide) for f in $(BRILLO_VENDOR_PARTITIONS); do \ pair1="$$(echo $$f | awk -F':' '{print $$1}')"; \ pair2="$$(echo $$f | awk -F':' '{print $$2}')"; \ src=$${pair1}/$${pair2}; \ dest=$(zip_root)/VENDOR_IMAGES/$${pair2}; \ mkdir -p $$(dirname "$${dest}"); \ cp $${src} $${dest}; \ done; endif ...... ......
AB情况下添加依赖,可执行文件brillo_update_payload,非AB情况下添加依赖brotli
ifeq ($(AB_OTA_UPDATER),true) $(INTERNAL_OTA_PACKAGE_TARGET): $(BRILLO_UPDATE_PAYLOAD) else $(INTERNAL_OTA_PACKAGE_TARGET): $(BROTLI) endif
关于device和build大致整理了这么多内容,因为我也是刚开始看,可能没有整理全,后面再继续填坑。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。