一、问题描述

最近处理了一个amlogic 7.1 AB项目,升级出现system不匹配的问题,对比发现刷机包中的system与obj包中的不一致,那么就要从编译流程方面排查,将刷机和做包使用的固件进行同步

二、解决思路

说实话一开始其实没什么思路,从编译log入手也看的不是很明白,所以最好的办法就是拆分问题,1、了解make otapackage的大致流程 2、amlogic刷机包的大致生成流程,这两个方面确认好后,再回来看问题,有了些自己的想法去处理

1、make otapackage流程

总体流程其实应该是两个:

$(BUILT_TARGET_FILES_PACKAGE)      生成obj下的target文件

$(INTERNAL_OTA_PACKAGE_TARGET) 生成ota整包文件

 

otapackage 执行从build/core/Makefile 开始

$(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE)
    @echo "Package OTA: $@"
    $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH MKBOOTIMG=$(MKBOOTIMG) \
       ./build/tools/releasetools/ota_from_target_files -v \
       --block \
       $(UPDATE_DTB) \
       -p $(HOST_OUT) \
       -k $(KEY_CERT_PAIR) \
       $(if $(OEM_OTA_CONFIG), -o $(OEM_OTA_CONFIG)) \
       $(BUILT_TARGET_FILES_PACKAGE) $@
       
.PHONY: otapackage
otapackage: $(INTERNAL_OTA_PACKAGE_TARGET)

otapackage依赖 $(INTERNAL_OTA_PACKAGE_TARGET) 通过ota_from_target_files 生成ota整包

而$(INTERNAL_OTA_PACKAGE_TARGET) 仅依赖$(BUILT_TARGET_FILES_PACKAGE)

$(BUILT_TARGET_FILES_PACKAGE): \
        $(HOST_OUT_EXECUTABLES)/bsdiff \
        $(INSTALLED_BOOTIMAGE_TARGET) \
        $(INSTALLED_RADIOIMAGE_TARGET) \
        $(INSTALLED_RECOVERYIMAGE_TARGET) \
        $(INSTALLED_SYSTEMIMAGE) \
        $(INSTALLED_USERDATAIMAGE_TARGET) \
        $(INSTALLED_CACHEIMAGE_TARGET) \
        $(INSTALLED_VENDORIMAGE_TARGET) \
        $(INSTALLED_SYSTEMOTHERIMAGE_TARGET) \
        $(INSTALLED_ANDROID_INFO_TXT_TARGET) \
        $(SELINUX_FC) \
        $(APKCERTS_FILE) \
        $(HOST_OUT_EXECUTABLES)/fs_config \
        | $(ACP)
    @echo "Package target files: $@"
    
   ......
   ......
    
    $(hide) (cd $(zip_root) && zip -qX ../$(notdir $@) META/*filesystem_config.txt)
    $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH MKBOOTIMG=$(MKBOOTIMG) \
   ./build/tools/releasetools/add_img_to_target_files -a -v -p $(HOST_OUT) $@

 

$(BUILT_TARGET_FILES_PACKAGE)需要很多依赖关系,其中$(INSTALLED_SYSTEMIMAGE) 就是重新打包system.img的,方法最后会调用add_img_to_target_files生成target文件中的IMAGES

 

注意:我们再次梳理下这里

$(INSTALLED_SYSTEMIMAGE)生成了out下的刷机固件

$(BUILT_TARGET_FILES_PACKAGE)文件拷贝到target后通过add脚本生成了做升级包需要的IMAGES/system.img

 

make otapackage完之后,如果不加任何的脚本或者其他流程,刷机包跟差分包使用固件是不一样的

 

2、amlogic刷机包的大致生成流程

[ 99% 194/195] Package: out/target/product/p212/aml_upgrade_package.img
cp device/amlogic/p212/upgrade/aml_sdc_burn.ini out/target/product/p212/upgrade/aml_sdc_burn.ini
cp device/amlogic/p212/upgrade/u-boot.bin.sd.bin out/target/product/p212/upgrade/u-boot.bin.sd.bin
cp device/amlogic/p212/upgrade/u-boot.bin.usb.bl2 out/target/product/p212/upgrade/u-boot.bin.usb.bl2
cp device/amlogic/p212/upgrade/u-boot.bin.usb.tpl out/target/product/p212/upgrade/u-boot.bin.usb.tpl
cp device/amlogic/p212/upgrade/platform.conf out/target/product/p212/upgrade/platform.conf
cp device/amlogic/common/products/mbox/upgrade/aml_upgrade_package_AB.conf out/target/product/p212/upgrade/aml_upgrade_package_AB.conf
ln -sf out/target/product/p212/boot.img out/target/product/p212/upgrade/boot.img
ln -sf out/target/product/p212/u-boot.bin out/target/product/p212/upgrade/u-boot.bin
ln -sf out/target/product/p212/dtb.img out/target/product/p212/upgrade/dtb.img
ln -sf out/target/product/p212/system.img out/target/product/p212/upgrade/system.img
ln -sf out/target/product/p212/userdata.img out/target/product/p212/upgrade/userdata.img

./vendor/amlogic/tools/aml_upgrade/aml_image_v2_packer -r out/target/product/p212/upgrade/aml_upgrade_package_AB.conf 
out/target/product/p212/upgrade/ out/target/product/p212/aml_upgrade_package.img

[Msg]Pack Item[USB         ,              DDR] from (out/target/product/p212/upgrade/u-boot.bin.usb.bl2),sz[0xc000]B,
[Msg]Pack Item[USB         ,            UBOOT] from (out/target/product/p212/upgrade/u-boot.bin.usb.tpl),sz[0xb4000]B,ft[normal]    
[Msg]Pack Item[PARTITION   ,         _aml_dtb] from (out/target/product/p212/upgrade/dtb.img),sz[0x16000]B,ft[normal]   
[Msg]Pack Item[VERIFY      ,         _aml_dtb] from (out/target/product/p212/upgrade/dtb.img),vry[sha1sum dccc4db852e30f2c3383e332e1ec1995a3a916e7] 
[Msg]Pack Item[UBOOT       ,     aml_sdc_burn] from (out/target/product/p212/upgrade/u-boot.bin.sd.bin),sz[0xc0200]B,ft[normal] 
[Msg]Pack Item[ini         ,     aml_sdc_burn] from (out/target/product/p212/upgrade/aml_sdc_burn.ini),sz[0x25a]B,
[Msg]Pack Item[PARTITION   ,           boot_a] from (out/target/product/p212/upgrade/boot.img),sz[0x8f4800]B,ft[normal] 
[Msg]Pack Item[VERIFY      ,           boot_a] from (out/target/product/p212/upgrade/boot.img),vry[sha1sum d285ec4aab9676e8b20323c0f622e8572f98de56]    
[Msg]Pack Item[PARTITION   ,       bootloader] from (out/target/product/p212/upgrade/u-boot.bin),sz[0xc0000]B,ft[normal]    
[Msg]Pack Item[VERIFY      ,       bootloader] from (out/target/product/p212/upgrade/u-boot.bin),vry[sha1sum e1bc055fd718d28ca17dad577fcb148d1aef95dc]  
[Msg]Pack Item[PARTITION   ,             logo] from (out/target/product/p212/upgrade/logo.img),sz[0x52a5e0]B,ft[normal] 
[Msg]Pack Item[VERIFY      ,             logo] from (out/target/product/p212/upgrade/logo.img),vry[sha1sum ca14e1dab9f71ca762317ee7f4ed1fd211e1b657]    
[Msg]Pack Item[xml         ,         manifest] from (out/target/product/p212/upgrade/manifest.xml),sz[0x17688]B,ft[normal]  
[Msg]Pack Item[dtb         ,           meson1] from (out/target/product/p212/upgrade/dtb.img),Duplicated for _aml_dtb.PARTITION

[Msg]Pack Item[conf        ,         platform] from (out/target/product/p212/upgrade/platform.conf),sz[0xca]B,
[Msg]Pack Item[PARTITION   ,         system_a] from (out/target/product/p212/upgrade/system.img),sz[0x46d0911c]B,ft[sparse] 
[Msg]Pack Item[VERIFY      ,         system_a] from (out/target/product/p212/upgrade/system.img),vry[sha1sum 023134dd6d1b72d3c0593f05ddcf7397bc2d516e]  
[Msg]version:0x2 crc:0x0f9baa07 size:1205436956 bytes[1149MB]
Pack image[out/target/product/p212/aml_upgrade_package.img] OK
 out/target/product/p212/aml_upgrade_package.img installed

以上是编译部分的log,可以看出生成aml_upgrade_package.img的大致流程

1、创建upgrade目录

2、将需要刷机的img文件拷贝入upgrade

3、执行脚本进行pack

 

这个工作所有的代码都由一个文件完成./device-amlogic/common/factory.mk,那么问题来了,怎么跑起来这个mk文件的

在devce  和 build 下 grep之后发现 只有这么一句

device-amlogic/p212/AndroidBoard.mk:20:include device/amlogic/common/factory.mk

 

这里运行机制也是从otapackage 开始,可以看出有两个依赖

droidcore: $(INSTALLED_AML_UPGRADE_PACKAGE_TARGET) $(INSTALLED_MANIFEST_XML)

otapackage: $(INSTALLED_AML_UPGRADE_PACKAGE_TARGET) $(INSTALLED_MANIFEST_XML)

.PHONY:aml_upgrade
aml_upgrade:$(INSTALLED_AML_UPGRADE_PACKAGE_TARGET)
$(INSTALLED_AML_UPGRADE_PACKAGE_TARGET): \
    $(addprefix $(PRODUCT_OUT)/,$(BUILT_IMAGES)) \
    $(UPGRADE_FILES) \
    $(INSTALLED_AML_USER_IMAGES) \
    $(INSTALLED_AML_LOGO) \
    $(INSTALLED_MANIFEST_XML) \
    $(TARGET_USB_BURNING_V2_DEPEND_MODULES)
    mkdir -p $(PRODUCT_UPGRADE_OUT)
    $(hide) $(foreach file,$(UPGRADE_FILES), \
        echo cp $(file) $(PRODUCT_UPGRADE_OUT)/$(notdir $(file)); \
        cp -f $(file) $(PRODUCT_UPGRADE_OUT)/$(notdir $(file)); \
        )
    $(hide) $(foreach file,$(BUILT_IMAGES), \
        echo ln -sf $(PRODUCT_OUT)/$(file) $(PRODUCT_UPGRADE_OUT)/$(file); \
        ln -sf $(ANDROID_BUILD_TOP)/$(PRODUCT_OUT)/$(file) $(PRODUCT_UPGRADE_OUT)/$(file); \
        )
ifeq ($(PRODUCT_BUILD_SECURE_BOOT_IMAGE_DIRECTLY),true)
    $(hide) rm -f $(PRODUCT_UPGRADE_OUT)/u-boot.bin.encrypt.*
    $(hide) $(ACP) $(PRODUCT_OUT)/u-boot.bin.encrypt.* $(PRODUCT_UPGRADE_OUT)/
    ln -sf $(ANDROID_BUILD_TOP)/$(PRODUCT_OUT)/dtb.img $(PRODUCT_UPGRADE_OUT)/dtb.img
    ln -sf $(ANDROID_BUILD_TOP)/$(PRODUCT_OUT)/u-boot.bin.encrypt.efuse $(PRODUCT_UPGRADE_OUT)/SECURE_BOOT_SET
endif# ifeq ($(PRODUCT_BUILD_SECURE_BOOT_IMAGE_DIRECTLY),true)
    $(security_dm_verity_conf)
    $(update-aml_upgrade-conf)
    $(hide) $(foreach userPartName, $(BOARD_USER_PARTS_NAME), \
        $(call aml-user-img-update-pkg,$(userPartName),$(PACKAGE_CONFIG_FILE)))
    @echo "Package: $@"
    @echo ./vendor/amlogic/tools/aml_upgrade/aml_image_v2_packer -r \
        $(PACKAGE_CONFIG_FILE)  $(PRODUCT_UPGRADE_OUT)/ $@
    ./vendor/amlogic/tools/aml_upgrade/aml_image_v2_packer -r \
        $(PACKAGE_CONFIG_FILE)  $(PRODUCT_UPGRADE_OUT)/ $@
    @echo " $@ installed"
else
#none
INSTALLED_AML_UPGRADE_PACKAGE_TARGET :=
endif

 

$(INSTALLED_AML_UPGRADE_PACKAGE_TARGET)还存在有别的依赖,直到最后生成aml_upgrade_package.img刷机包

 

3、定位问题

从上述两个流程可以看出,amlogic把这两个流程合并为了 同一个命令 make otapackage 中执行,但是从完整的编译log可以看出目前的流程大致分为了:

1、编译kernel

2、编译system

3、打包刷机镜像

4、执行obj包的生成

 

这样编译倒是省条命令,但是刷机的跟做包的不一致,尝试调整了几次执行的顺序,先执行完make otapakcage 在进行打包,但是因为都是由otapackage目标发起,没找到具体可以更改顺序的方法

既然不好换,换一种思路,把两个流程分开执行,既然factory.mk 里面是以otapackage 为目标的,那么可以换成别的么,实际测试发现可以

更换为

pack: $(INSTALLED_AML_UPGRADE_PACKAGE_TARGET) $(INSTALLED_MANIFEST_XML)

执行make pack -j 可以编出刷机包

但是编译的时候会从新对system.img进行打包,这个就不是我们需要的了,对于我这种修改问题的方法,卡在解决的关键就是怎么去除pack时候的system打包

三、解决方法

对这个mk文件不是很了解,去除system打包这一步折腾了比较长的时间,从$(INSTALLED_AML_UPGRADE_PACKAGE_TARGET)依赖关系入手,最后找到了$(BUILT_IMAGES)相关

 

ifeq ($(AB_OTA_UPDATER),true)
BUILT_IMAGES += system.img userdata.img
else
BUILT_IMAGES += system.img userdata.img cache.img
endif

 

更改为BUILT_IMAGES += userdata.img 发现不再单独生成system.img 变成了简单的拷贝和打包的动作了

 

那么到这里也就更改完成

1、make otapackage 通过自己的拷贝脚本 把中间包里的system拷贝到out下

2、make pack  通过脚本对out下的固件进行打包,这样upgrade out obj 理论上 system 都是一摸一样的