引導映像標題

Android 9 在啟動映像標頭中引入了一個版本字段,可以在保持向後兼容性的同時更新標頭。引導加載程序必須檢查標頭版本字段並相應地解析標頭。啟動設備:

  • 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];
};