Android P Image编译

最近尝试着修改Android P的编译脚本,目的是为了将系统源码和BSP源码分开编译。

由于厂家定制,Android内核的源码一般都在vendor目录下,本文尝试去掉vendor中的kernel源码,还能正常编译Android其他源码,便于做系统开发或者app发开,不依赖kernel源码编译。

相关源码:
build/make/core/Makefile
device/fsl/imx8q/mek_8q/AndroidBoard.mk
device/fsl/imx8q/mek_8q/BoardConfig.mk
device/fsl/common/build/dtbo.mk
system/core/fs_mgr/fs_mgr_avb.cpp
vendor\nxp-opensource\uboot-imx\lib\avb\libavb\avb_slot_verify.c
vendor\nxp-opensource\uboot-imx\lib\avb\libavb\avb_vbmeta_image.h

升级镜像文件包括:
boot.img
bootloader-imx8qm.img
bootloader-imx8qm-xen.img
dtbo-imx8qm.img
dtbo-imx8qm-xen.img
vendor.img
partition-table-28GB.img
system.img
spl-imx8qm.bin
libusb-1.0.dll
spl-imx8qm-xen.bin
u-boot-imx8qm-xen-dom0.imx
uuu.exe
uuu_imx_android_flash.bat
vbmeta-imx8qm.img
vbmeta-imx8qm-xen.img

device/fsl/imx8q/mek_8q/AndroidBoard.mk

AndroidBoard.mk中去掉kernel和uboot的编译脚本mk文件:

LOCAL_PATH := $(call my-dir)
# build without kernel and uboot,rm by sunxiaolin 20191021
#include device/fsl/common/build/kernel.mk
#include device/fsl/common/build/uboot.mk
include device/fsl/common/build/dtbo.mk
include device/fsl/common/build/imx-recovery.mk
include device/fsl/common/build/gpt.mk
include $(LOCAL_PATH)/AndroidUboot.mk
include $(FSL_PROPRIETARY_PATH)/fsl-proprietary/media-profile/media-profile.mk
ifneq ($(PRODUCT_IMX_CAR),true)
include $(FSL_PROPRIETARY_PATH)/fsl-proprietary/sensor/fsl-sensor.mk
endif

device/fsl/common/build/dtbo.mk

继续去掉dtbo的编译,因为dtbo.mk中包含了vbmeta-imx8qm.img的编译,而且vbmeta需要跟系统镜像system.img放在一起编译。dtbo-imx8qm.img则需要跟kernel,uboot部分一起编译。

1、去掉kernel_imx相关的编译内容
2、去掉dtboimage: $(BOARD_PREBUILT_DTBOIMAGE)相关的编译内容
3、修改vbmeta的编译内容,主要去掉

  • 去掉$(BOARD_PREBUILT_DTBOIMAGE)
  • 去掉DTBO_IMG=echo $(PRODUCT_OUT)/dtbo-$${DTS_PLATFORM}.img; \
  • 去掉RECOVERY_IMG=echo $(PRODUCT_OUT)/recovery-$${DTS_PLATFORM}.img; \
  • 去掉–include_descriptors_from_image $$DTBO_IMG \
  • 去掉–include_descriptors_from_image $$DTBO_IMG \
  • 去掉–include_descriptors_from_image $$RECOVERY_IMG \

device/fsl/imx8q/mek_8q/BoardConfig.mk

1、去掉所有vendor/目录的拷贝操作,例如:PRODUCT_COPY_FILES +=
device/fsl/imx8q/etc/wifi/fw_bcmdhd.bin:vendor/etc/wifi/fw_bcmdhd.bin
2、去掉所有KERNEL_OUT目录的拷贝操作,例如:

ifeq ($(PRODUCT_IMX_CAR_M4),true)
BOARD_VENDOR_KERNEL_MODULES += \
                            $(KERNEL_OUT)/drivers/hid/usbhid/usbhid.ko \
BOARD_RECOVERY_KERNEL_MODULES += \
							$(KERNEL_OUT)/drivers/gpu/drm/bridge/ds90ub947.ko \
endif

build/make/core/Makefile

build/make/core/Makefile文件是整个Android编译的核心文件。

1、去掉boot.img部分的编译内容,例如:
#INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
2、去掉vendor.img部分的编译内容。例如:
#BUILT_VENDORIMAGE_TARGET := $(PRODUCT_OUT)/vendor.img
3、去掉dtbo.img部分的编译内容。例如:
#INSTALLED_DTBOIMAGE_TARGET := $(PRODUCT_OUT)/dtbo.img
4、去掉avb校验,注释一下部分的代码:

#ifdef BOARD_AVB_BOOT_KEY_PATH
#$(eval $(call check-and-set-avb-chain-args,BOOT))
#else
#INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
#    --include_descriptors_from_image $(INSTALLED_BOOTIMAGE_TARGET)
#endif

修改了以上这么多之后,系统可以分开编译过。

分开之后,Android系统打包升级Image包括:
partition-table-28GB.img
system.img
spl-imx8qm.bin
libusb-1.0.dll
spl-imx8qm-xen.bin
u-boot-imx8qm-xen-dom0.imx
uuu.exe
uuu_imx_android_flash.bat
vbmeta-imx8qm.img
vbmeta-imx8qm-xen.img

Android系统内核打包升级Image包括:
boot.img
bootloader-imx8qm.img
bootloader-imx8qm-xen.img
dtbo-imx8qm.img
dtbo-imx8qm-xen.img
vendor.img

使用uuu.exe工具进行正常升级,发现系统起不来,报错:

Read public key error
AVB TIPC client not initialized

vendor.img avb校验失败:Android P Image编译_第1张图片
avb主要是bootloader的校验和vendor的校验,校验失败后系统启动不了。

avb校验

vendor\nxp-opensource\uboot-imx\lib\avb\libavb\avb_slot_verify.c
vendor\nxp-opensource\uboot-imx\lib\avb\libavb\avb_vbmeta_image.h

bootloader校验

avb_vbmeta_image.h中定义了

/* Flags for the vbmeta image.
 *
 * AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED: If this flag is set,
 * hashtree image verification will be disabled.
 *
 * AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED: If this flag is set,
 * verification will be disabled and descriptors will not be parsed.
 */
typedef enum {
  AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED = (1 << 0),
  AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED = (1 << 1)
} AvbVBMetaImageFlags;

位运算:
(1 << 0),即0x00000001
(1 << 1),即0x00000010

这两个flag分别表示是否使能dm-verity和verification功能,默认是会开启这两个验证功能。

禁止avb校验功能,即verification功能;禁止dm-verity

vendor\nxp-opensource\uboot-imx\lib\avb\libavb\avb_slot_verify.c

static AvbSlotVerifyResult load_and_verify_vbmeta({
	//省略一部分代码
	//...
	
	/* If verification has been disabled by setting a bit in the image,
	 * we're done... except that we need to load the entirety of the
	 * requested partitions.
	 */
	 //修改vbmeta_header.flags标志为AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED
	vbmeta_header.flags = AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED;
	if (vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED) {
	  AvbSlotVerifyResult sub_ret;
	  avb_debugv(
	      full_partition_name, ": VERIFICATION_DISABLED bit is set.\n", NULL);
	  /* If load_requested_partitions() fail it is always a fatal
	   * failure (e.g. ERROR_INVALID_ARGUMENT, ERROR_OOM, etc.) rather
	   * than recoverable (e.g. one where result_should_continue()
	   * returns true) and we want to convey that error.
	   */
	  sub_ret = load_requested_partitions(
	      ops, requested_partitions, ab_suffix, slot_data);
	  if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) {
	    ret = sub_ret;
	  }
	  goto out;
	}

	//省略一部分代码
	//...

     /* Compare the flags for top-level VBMeta struct with flags in
     * the command-line descriptor so command-line snippets only
     * intended for a certain mode (dm-verity enabled/disabled)
     * are skipped if applicable.
     */
    apply_cmdline = true;
     //修改toplevel_vbmeta_flags标志为AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED
    toplevel_vbmeta_flags = AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED;
    if (toplevel_vbmeta_flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED) {
      if (kernel_cmdline_desc.flags &
          AVB_KERNEL_CMDLINE_FLAGS_USE_ONLY_IF_HASHTREE_NOT_DISABLED) {
        apply_cmdline = false;
      }
    } else {
      if (kernel_cmdline_desc.flags &
          AVB_KERNEL_CMDLINE_FLAGS_USE_ONLY_IF_HASHTREE_DISABLED) {
        apply_cmdline = false;
      }
    }
}
AvbSlotVerifyResult avb_slot_verify({
	//省略一部分代码
	//...
	
    /* If verification is disabled, we are done ... we specifically
     * don't want to add any androidboot.* options since verification
     * is disabled.
     */
     //add by sunxiaolin 20191107
     //修改toplevel_vbmeta.flags标志为AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED
     toplevel_vbmeta.flags = (1 << 1);
    if (toplevel_vbmeta.flags & AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED) {
      /* Since verification is disabled we didn't process any
       * descriptors and thus there's no cmdline... so set root= such
       * that the system partition is mounted.
       */
      avb_assert(slot_data->cmdline == NULL);
      slot_data->cmdline =
          avb_strdup("root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)");
      if (slot_data->cmdline == NULL) {
        ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
        goto fail;
      }
    } else {
      /* Add options - any failure in avb_append_options() is either an
       * I/O or OOM error.
       */
      AvbSlotVerifyResult sub_ret = avb_append_options(ops,
                                                       slot_data,
                                                       &toplevel_vbmeta,
                                                       algorithm_type,
                                                       hashtree_error_mode);
      if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) {
        ret = sub_ret;
        goto fail;
      }
    }
    
	//省略一部分代码
	//...
}

禁止dm-verity还有一种方法,即在升级成功后,使用:
adb disable-verity
重启生效。

还需要修改vendor校验

vendor校验

system/core/fs_mgr/fs_mgr_avb.cpp

FsManagerAvbUniquePtr FsManagerAvbHandle::DoOpen(FsManagerAvbOps* avb_ops) {
	//省略一部分代码
	//...

    // Checks whether FLAGS_VERIFICATION_DISABLED is set:
    //   - Only the top-level vbmeta struct is read.
    //   - vbmeta struct in other partitions are NOT processed, including AVB HASH descriptor(s)
    //     and AVB HASHTREE descriptor(s).
    AvbVBMetaImageHeader vbmeta_header;
    avb_vbmeta_image_header_to_host_byte_order(
        (AvbVBMetaImageHeader*)avb_handle->avb_slot_data_->vbmeta_images[0].vbmeta_data,
        &vbmeta_header);
    //将vbmeta_header.flags设置为:AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED
    vbmeta_header.flags = AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED;
    bool verification_disabled =
        ((AvbVBMetaImageFlags)vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED);

    if (verification_disabled) {
        avb_handle->status_ = kAvbHandleVerificationDisabled;
    } else {
        // Verifies vbmeta structs against the digest passed from bootloader in kernel cmdline.
        std::unique_ptr<FsManagerAvbVerifier> avb_verifier = FsManagerAvbVerifier::Create();
        if (!avb_verifier) {
            LERROR << "Failed to create FsManagerAvbVerifier";
            return nullptr;
        }
        if (!avb_verifier->VerifyVbmetaImages(*avb_handle->avb_slot_data_)) {
            LERROR << "VerifyVbmetaImages failed";
            return nullptr;
        }

        // Checks whether FLAGS_HASHTREE_DISABLED is set.
        bool hashtree_disabled =
            ((AvbVBMetaImageFlags)vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED);
        if (hashtree_disabled) {
            avb_handle->status_ = kAvbHandleHashtreeDisabled;
        }
    }

	//省略一部分代码
	//...
}

你可能感兴趣的:(Android,系统)