Android 9 introduced a version field in the boot image header, enabling updates to the header while maintaining backward compatibility. The bootloader must check the header version field and parse the header accordingly. Devices launching with:
- Android 13 can use boot header version 3 or 4. For
devices supporting the Generic Kernel Image
(GKI)
architecture, version 4 is the primary boot image and the
os_version
field in the boot header must be zero. The device bootloader is expected to obtain the version information from the Android Verified Boot (AVB) properties instead. - Android 12 can use boot header version 3 or 4. For devices supporting the Generic Kernel Image (GKI) architecture, version 4 is the primary boot image.
- Android 11 can use boot header version 3. For devices supporting Generic Kernel Image (GKI) architecture, this version must be used for the primary boot image.
- Android 10 must use boot header version 2.
- Android 9 must use boot header version 1.
- Android 8 and lower are considered as using a boot image header version 0.
For all devices running with Android 9 or higher, the
Vendor Test Suite (VTS) checks the format of the
boot/recovery
image to ensure that the boot image header uses the correct
version. To view AOSP details on all supported boot and vendor boot
image headers, refer to
system/tools/mkbootimg/include/bootimg/bootimg.h
.
Implement boot image header versioning
The mkbootimg
tool accepts the following arguments.
Argument | Description |
---|---|
header_version |
Sets the boot image header version. A boot image with a header version:
|
recovery_dtbo |
Used for architectures that use DTB. Specifies the path to the recovery
DTBO image. Optional for A/B devices, which don't need a recovery image.
Non-A/B devices using header_version :
|
recovery_acpio |
Used for architectures that use ACPI instead of DTB. Specifies the path
to the recovery ACPIO image. Optional for A/B devices, which don't need a
recovery image. Non-A/B devices using header_version :
|
dtb |
Path to the DTB image that's included in the boot/recovery images. |
dtb_offset |
When added to the base argument, provides the physical load
address for the final device tree. For example, if the base
argument is 0x10000000 and the dtb_offset argument
is 0x01000000 , the dtb_addr_field in the boot image
header is populated as 0x11000000 . |
The device BoardConfig.mk
uses the config BOARD_MKBOOTIMG_ARGS
to add
header version
to the other board-specific arguments of mkbootimg
. For
example:
BOARD_MKBOOTIMG_ARGS := --ramdisk_offset $(BOARD_RAMDISK_OFFSET) --tags_offset $(BOARD_KERNEL_TAGS_OFFSET) --header_version $(BOARD_BOOTIMG_HEADER_VERSION)
The Android build system uses the BoardConfig
variable
BOARD_PREBUILT_DTBOIMAGE
to set the argument recovery_dtbo
of the
mkbootimg
tool during the creation of the recovery image. For details on the
Android Open Source Project (AOSP) changes, review the associated changelists
for boot image header
versioning.
Boot image header, version 4
Android 12 provides a boot_signature
in the boot image
header version 4, which can be used to check the integrity of the kernel and the
ramdisk. The check is done in
VtsSecurityAvbTest
and is required for devices using the GKI architecture. However, the
boot_signature
isn't involved in the device-specific verified boot process
and is only used in VTS. See GKI boot.img board
configuration
and GKI verified boot
settings
for details.
Vendor boot image header version 4 supports multiple vendor ramdisk fragments.
Version 4 of the boot image header version uses the following format.
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 */
};
Boot image header, version 3
Android 11 updates the boot image header to version 3, which removes the following data:
Second-stage bootloader. The
second_size
andsecond_addr
fields no longer appear in the boot image header. Devices with a second-stage bootloader must store that bootloader in its own partition.Recovery image. The requirement for specifying a recovery image has been deprecated, and the
recovery_dtbo_size
,recovery_dtbo_offset
,recovery_acpio_size
, andrecovery_acpio_offset
fields no longer appear in the boot image header.A/B devices use an update and recovery scheme that makes it unnecessary to specify a DTBO or ACPIO image for recovery.
Non-A/B devices that want to specify a recovery image (either DTBO or ACPIO) should use boot image header version 1 or 2.
Device tree blob (DTB). The DTB is stored in the vendor boot partition, so the
dtb_size
anddtb_addr
fields no longer appear in the boot image header (but are present in the vendor boot image header).
Devices can use boot image header version 3 to comply with Generic Kernel Image
(GKI) architecture,
which unifies the core kernel and moves vendor modules that are required for
boot to the vendor_boot
partition (meaning the boot image contains only GKI
components). Devices that:
Use GKI (requires the android-4.19 or android-5.4 kernel) but don't use A/B updates can specify a recovery image by using boot image version 3 for the boot image and boot image version 2 for the recovery image.
Don't use GKI and don't use A/B updates can specify a recovery image by using boot image version 1 or 2 for both boot and recovery images.
Version 3 of the boot image header version uses the following format.
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];
};
Boot image header, version 2
Android 10 updates the boot image header to version 2, which adds a section for recovery DTB image information (image size and physical load address).
Version 2 of the boot image header version uses the following format.
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 */
};
Boot image header, version 1
Android 9 converts the unused
field of the boot
image header to a header version field. Devices launching with Android
9 must use the boot image header with the header
version set to 1 or higher (this is verified by VTS).
Version 1 of the boot image header version uses the following format.
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 */
};
Non-A/B devices can specify a DTB/ACPI overlay image for recovery to help mitigate over-the-air (OTA) update failures. (A/B devices don't have this problem and don't need to specify an overlay image.) You can specify either a DTBO image or an ACPIO image, but not both (because they're used by different architectures). To configure the boot image header correctly, when using:
A DTBO image for recovery, include the
recovery_dtbo_size
andrecovery_dtbo_offset
fields (and don't include therecovery_acpio_size
andrecovery_acpio_offset
fields).An ACPIO image for recovery, include the
recovery_acpio_size
andrecovery_acpio_offset
fields (and don't include therecovery_dtbo_size
andrecovery_dtbo_offset
fields).
The header_size
field contains the size of the boot image header. If the boot
image header version is set to 1, the id
field contains the SHA-1 digest for
the recovery_[dtbo|acpio]
section of the boot image in addition to the
kernel
, ramdisk
, and second sections
. For details on the
recovery_[dtbo|acpio]_size
and recovery_[dtbo|acpio]_offset
fields, see
Recovery Images.
Legacy boot image header, version 0
Devices launched before Android 9 using the legacy boot image header are considered as using a boot image header version 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];
};