启动映像头文件

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 设备,此参数为可选参数。如果非 A/B 设备使用的 header_version 为:
  • 1 或 2,则设备可以指定此路径,也可以使用 recovery_acpio 部分指定 ACPIO 恢复映像的路径。
  • 3,则设备无法指定 DTBO 恢复映像。
recovery_acpio 适用于使用 ACPI(而非 DTB)的架构。指定 ACPIO 恢复映像的路径。对于不需要恢复映像的 A/B 设备,此参数为可选参数。如果非 A/B 设备使用的 header_version 为:
  • 1 或 2,则设备可以指定此路径,也可以使用 recovery_dtbo 部分指定 DTBO 恢复映像的路径。
  • 3,则设备无法指定 ACPIO 恢复映像。
dtb 启动/恢复映像中 DTB 映像的路径。
dtb_offset 在添加到 base 参数时,系统会提供最终设备树的实际加载地址。例如,如果 base 参数为 0x10000000dtb_offset 参数为 0x01000000,启动映像头文件中的 dtb_addr_field 将填充为 0x11000000

设备 BoardConfig.mk 使用 BOARD_MKBOOTIMG_ARGS 配置将 header 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 fragment。

启动映像头文件版本 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 恢复映像。

    • 如果非 A/B 设备需要指定恢复映像(DTBO 或 ACPIO),则应使用启动映像头文件版本 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,那么除了 kernelramdisksecond sections 之外,id 字段还包含启动映像 recovery_[dtbo|acpio] 部分的 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];
};