引導映像標題

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參數為0x10000000dtb_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欄位除了kernelramdisksecond sections之外,還包含啟動映像的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];
};