引导映像标题

Android 9 在启动映像标头中引入了一个版本字段,可以在保持向后兼容性的同时更新标头。引导加载程序必须检查标头版本字段并相应地解析标头。启动设备:

  • Android 13 可以使用启动标头版本 3 或 4。对于支持通用内核映像 (GKI)架构的设备,版本 4 是主启动映像,并且启动标头中的os_version字段必须为零。设备引导加载程序应改为从Android 验证引导 (AVB) 属性中获取版本信息。
  • Android 12 可以使用启动标头版本 3 或 4。对于支持通用内核映像 (GKI)架构的设备,版本 4 是主启动映像。
  • Android 11 可以使用启动标头版本 3。对于支持通用内核映像 (GKI)架构的设备,此版本必须用于主启动映像。
  • Android 10 必须使用启动头文件版本 2。
  • Android 9 必须使用启动头文件版本 1。
  • Android 8 及更低版本被视为使用启动映像标头版本 0。

对于运行 Android 9 或更高版本的所有设备,供应商测试套件 (VTS)会检查boot/recovery映像的格式,以确保启动映像标头使用正确的版本。要查看所有当前支持的引导和供应商引导映像头的 AOSP 详细信息,请参阅system/tools/mkbootimg/include/bootimg/bootimg.h

实施引导映像标头版本控制

mkbootimg工具接受以下参数。

争论描述
header_version设置启动映像标头版本。带有标头版本的启动映像:
  • 1 或 2 支持恢复 DTBO 映像或恢复 ACPIO 映像。
  • 3 不支持恢复映像。
recovery_dtbo用于使用 DTB 的架构。指定恢复 DTBO 映像的路径。对于不需要恢复映像的 A/B 设备是可选的。使用header_version的非 A/B 设备:
  • 1 或 2 可以指定此路径或使用recovery_acpio部分指定恢复 ACPIO 映像的路径。
  • 3 无法指定恢复 DTBO 映像。
recovery_acpio用于使用 ACPI 而不是 DTB 的体系结构。指定恢复 ACPIO 映像的路径。对于不需要恢复映像的 A/B 设备是可选的。使用header_version的非 A/B 设备:
  • 1 或 2 可以指定此路径或使用recovery_dtbo部分指定恢复 DTBO 映像的路径。
  • 3 无法指定恢复 ACPIO 映像。
dtb引导/恢复映像中包含的 DTB 映像的路径。
dtb_offset添加到base参数时,提供最终设备树的物理加载地址。例如,如果base参数是0x10000000并且dtb_offset参数是0x01000000 ,则引导映像头中的dtb_addr_field填充为0x11000000

设备BoardConfig.mk使用配置BOARD_MKBOOTIMG_ARGSheader version添加到mkbootimg的其他板特定参数。例如:

BOARD_MKBOOTIMG_ARGS := --ramdisk_offset $(BOARD_RAMDISK_OFFSET) --tags_offset $(BOARD_KERNEL_TAGS_OFFSET) --header_version $(BOARD_BOOTIMG_HEADER_VERSION)

Android 构建系统在创建恢复镜像的过程中使用BoardConfig变量BOARD_PREBUILT_DTBOIMAGE来设置mkbootimg工具的参数recovery_dtbo 。有关 Android 开源项目 (AOSP) 更改的详细信息,请查看启动映像标头版本控制的相关更改列表。

引导映像标头,版本 4

Android 12 在启动映像头版本 4 中提供了一个boot_signature ,可用于检查内核和 ramdisk 的完整性。检查在VtsSecurityAvbTest中完成,对于使用 GKI 架构的设备是必需的。但是, boot_signature不涉及特定于设备的验证启动过程,仅用于 VTS。有关详细信息,请参阅GKI boot.img 板配置GKI 验证的引导设置

供应商引导映像标头版本 4 支持多个供应商 ramdisk 片段。

启动映像标头版本的版本 4 使用以下格式。

struct boot_img_hdr
{
#define BOOT_MAGIC_SIZE 8
    uint8_t magic[BOOT_MAGIC_SIZE];

    uint32_t kernel_size;    /* size in bytes */
    uint32_t ramdisk_size;   /* size in bytes */

    uint32_t os_version;

    uint32_t header_size;    /* size of boot image header in bytes */
    uint32_t reserved[4];
    uint32_t header_version; /* offset remains constant for version check */

#define BOOT_ARGS_SIZE 512
#define BOOT_EXTRA_ARGS_SIZE 1024
    uint8_t cmdline[BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE];

    uint32_t signature_size; /* size in bytes */
};

引导映像标头,版本 3

Android 11 将启动映像标头更新为版本 3,该版本删除了以下数据:

  • 第二阶段引导加载程序。 second_sizesecond_addr字段不再出现在引导映像头中。具有第二阶段引导加载程序的设备必须将该引导加载程序存储在其自己的分区中。

  • 恢复图像。指定恢复映像的要求已被弃用,并且recovery_dtbo_sizerecovery_dtbo_offsetrecovery_acpio_sizerecovery_acpio_offset字段不再出现在启动映像标头中。

    • A/B 设备使用更新和恢复方案,无需指定 DTBO 或 ACPIO 映像进行恢复。

    • 想要指定恢复映像(DTBO 或 ACPIO)的非 A/B 设备应使用启动映像标头版本 1 或 2。

  • 设备树 blob (DTB)。 DTB 存储在供应商引导分区中,因此dtb_sizedtb_addr字段不再出现在引导映像标头中(但存在于供应商引导映像标头中)。

设备可以使用启动映像头版本 3 以符合通用内核映像 (GKI)架构,该架构统一了核心内核并将启动所需的供应商模块移动到vendor_boot分区(意味着启动映像仅包含 GKI 组件)。设备:

  • 使用 GKI(需要 android-4.19 或 android-5.4 内核)但不使用 A/B 更新可以通过使用启动映像版本 3 作为启动映像并使用启动映像版本 2 作为恢复映像来指定恢复映像。

  • 不使用 GKI 和不使用 A/B 更新可以通过对启动和恢复映像使用启动映像版本 1 或 2 来指定恢复映像。

启动映像标头版本的版本 3 使用以下格式。

struct boot_img_hdr
{
#define BOOT_MAGIC_SIZE 8
    uint8_t magic[BOOT_MAGIC_SIZE];

    uint32_t kernel_size;    /* size in bytes */
    uint32_t ramdisk_size;   /* size in bytes */

    uint32_t os_version;

    uint32_t header_size;    /* size of boot image header in bytes */
    uint32_t reserved[4];
    uint32_t header_version; /* offset remains constant for version check */

#define BOOT_ARGS_SIZE 512
#define BOOT_EXTRA_ARGS_SIZE 1024
    uint8_t cmdline[BOOT_ARGS_SIZE + BOOT_EXTRA_ARGS_SIZE];
};

引导映像标头,版本 2

Android 10 将启动镜像头更新到版本 2,增加了一个用于恢复DTB 镜像信息(镜像大小和物理加载地址)的部分。

启动映像标头版本的版本 2 使用以下格式。

struct boot_img_hdr
{
    uint8_t magic[BOOT_MAGIC_SIZE];
    uint32_t kernel_size;               /* size in bytes */
    uint32_t kernel_addr;               /* physical load addr */

    uint32_t ramdisk_size;              /* size in bytes */
    uint32_t ramdisk_addr;              /* physical load addr */

    uint32_t second_size;               /* size in bytes */
    uint32_t second_addr;               /* physical load addr */

    uint32_t tags_addr;                 /* physical addr for kernel tags */
    uint32_t page_size;                 /* flash page size we assume */
    uint32_t header_version;
    uint32_t os_version;
    uint8_t name[BOOT_NAME_SIZE];       /* asciiz product name */
    uint8_t cmdline[BOOT_ARGS_SIZE];
    uint32_t id[8];                     /* timestamp / checksum / sha1 / etc */
    uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
    uint32_t recovery_[dtbo|acpio]_size;    /* size of recovery image */
    uint64_t recovery_[dtbo|acpio]_offset;  /* offset in boot image */
    uint32_t header_size;               /* size of boot image header in bytes */
    uint32_t dtb_size;                  /* size of dtb image */
    uint64_t dtb_addr;                  /* physical load address */
};

引导映像标头,版本 1

Android 9 将引导映像标头的unused字段转换为标头版本字段。搭载 Android 9 的设备必须使用头文件版本设置为 1 或更高版本的启动映像头文件(这由 VTS 验证)。

启动映像标头版本的版本 1 使用以下格式。

struct boot_img_hdr
{
    uint8_t magic[BOOT_MAGIC_SIZE];
    uint32_t kernel_size;               /* size in bytes */
    uint32_t kernel_addr;               /* physical load addr */
    uint32_t ramdisk_size;              /* size in bytes */
    uint32_t ramdisk_addr;              /* physical load addr */

    uint32_t second_size;               /* size in bytes */
    uint32_t second_addr;               /* physical load addr */

    uint32_t tags_addr;                 /* physical addr for kernel tags */
    uint32_t page_size;                 /* flash page size we assume */
    uint32_t header_version;
    uint32_t os_version;
    uint8_t name[BOOT_NAME_SIZE];       /* asciiz product name */
    uint8_t cmdline[BOOT_ARGS_SIZE];
    uint32_t id[8];                     /* timestamp / checksum / sha1 / etc */
    uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
    uint32_t recovery_[dtbo|acpio]_size;    /* size of recovery image */
    uint64_t recovery_[dtbo|acpio]_offset;  /* offset in boot image */
    uint32_t header_size;               /* size of boot image header in bytes */
};

非 A/B 设备可以指定DTB/ACPI 覆盖图像进行恢复,以帮助缓解无线 (OTA) 更新失败。 (A/B 设备没有这个问题,不需要指定覆盖图像。)您可以指定 DTBO 图像或 ACPIO 图像,但不能同时指定两者(因为它们被不同的体系结构使用)。要正确配置启动映像标头,请在使用时:

  • 用于恢复的 DTBO 映像,包括recovery_dtbo_sizerecovery_dtbo_offset字段(并且不包括recovery_acpio_sizerecovery_acpio_offset字段)。

  • 用于恢复的 ACPIO 映像,包括recovery_acpio_sizerecovery_acpio_offset字段(并且不包括recovery_dtbo_sizerecovery_dtbo_offset字段)。

header_size字段包含引导映像标头的大小。如果引导映像标头版本设置为 1,则id字段包含引导映像的recovery_[dtbo|acpio]部分以及kernelramdisksecond sections的 SHA-1 摘要。有关recovery_[dtbo|acpio]_sizerecovery_[dtbo|acpio]_offset字段的详细信息,请参阅恢复映像

旧版引导映像标头,版本 0

在 Android 9 之前使用旧版启动映像标头启动的设备被视为使用启动映像标头版本 0。

struct boot_img_hdr
{
    uint8_t magic[BOOT_MAGIC_SIZE];
    uint32_t kernel_size;                /* size in bytes */
    uint32_t kernel_addr;                /* physical load addr */

    uint32_t ramdisk_size;               /* size in bytes */
    uint32_t ramdisk_addr;               /* physical load addr */

    uint32_t second_size;                /* size in bytes */
    uint32_t second_addr;                /* physical load addr */

    uint32_t tags_addr;                  /* physical addr for kernel tags */
    uint32_t page_size;                  /* flash page size we assume */
    uint32_t unused;
    uint32_t os_version;
    uint8_t name[BOOT_NAME_SIZE];        /* asciiz product name */
    uint8_t cmdline[BOOT_ARGS_SIZE];
    uint32_t id[8];                      /* timestamp / checksum / sha1 / etc */
    uint8_t extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
};