Android 9在啟動映像標頭中引入了version字段,可以在更新標頭的同時保持向後兼容性。引導加載程序必須檢查標頭版本字段,並相應地分析標頭。使用以下命令啟動的設備:
- 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 | 設置啟動映像頭版本。具有標頭版本的引導映像:
|
recovery_dtbo | 用於使用DTB的體系結構。指定恢復DTBO映像的路徑。對於不需要恢復映像的A / B設備是可選的。使用header_version 非A / B設備:
|
recovery_acpio | 用於使用ACPI而不是DTB的體系結構。指定恢復ACPIO映像的路徑。對於不需要恢復映像的A / B設備是可選的。使用header_version 非A / B設備:
|
dtb | 引導/恢復映像中包含的DTB映像的路徑。 |
dtb_offset | 當添加到base 參數時,提供最終設備樹的物理加載地址。例如,如果該base 參數是0x10000000 和dtb_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)更改的詳細信息,請查看相關的更改列表以進行啟動映像頭版本控制。
引導映像頭,版本3
Android 11將啟動映像標頭更新為版本3,該版本會刪除以下數據:
第二階段的引導程序。
second_size
和second_addr
字段不再出現在引導映像頭中。具有第二階段引導加載程序的設備必須將該引導加載程序存儲在其自己的分區中。恢復映像。指定恢復映像的要求已被棄用,並且
recovery_dtbo_size
,recovery_dtbo_offset
,recovery_acpio_size
和recovery_acpio_offset
字段不再出現在引導映像頭中。A / B設備使用更新和恢復方案,該方案無需指定DTBO或ACPIO映像進行恢復。
想要指定恢復映像的非A / B設備(DTBO或ACPIO)應使用啟動映像頭版本1或2。
設備樹Blob(DTB)。 DTB存儲在供應商啟動分區中,因此
dtb_size
和dtb_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_size
和recovery_dtbo_offset
字段(並且不包括recovery_acpio_size
和recovery_acpio_offset
字段)。用於恢復的ACPIO映像包括
recovery_acpio_size
和recovery_acpio_offset
字段(並且不包括recovery_dtbo_size
和recovery_dtbo_offset
字段)。
header_size
字段包含引導映像頭的大小。如果引導映像頭版本設置為1,則id
字段包含kernel
, ramdisk
和second sections
以外的引導映像的recovery_[dtbo|acpio]
的SHA-1摘要。有關recovery_[dtbo|acpio]_size
和recovery_[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];
};