Boot-Image-Header

Mit Android 9 wurde im Boot-Image-Header ein Versionsfeld eingeführt, das Aktualisierungen des Headers ermöglicht und gleichzeitig die Abwärtskompatibilität gewährleistet. Der Bootloader muss das Header-Versionsfeld überprüfen und den Header entsprechend analysieren. Geräte starten mit:

  • Android 13 kann Boot-Header Version 3 oder 4 verwenden. Für Geräte, die die Generic Kernel Image (GKI) -Architektur unterstützen, ist Version 4 das primäre Boot-Image und das Feld os_version im Boot-Header muss Null sein. Es wird erwartet, dass der Geräte-Bootloader die Versionsinformationen stattdessen aus den Android Verified Boot (AVB)-Eigenschaften erhält.
  • Android 12 kann Boot-Header Version 3 oder 4 verwenden. Für Geräte, die die Generic Kernel Image (GKI) -Architektur unterstützen, ist Version 4 das primäre Boot-Image.
  • Android 11 kann die Boot-Header-Version 3 verwenden. Für Geräte, die die Generic Kernel Image (GKI) -Architektur unterstützen, muss diese Version für das primäre Boot-Image verwendet werden.
  • Android 10 muss Boot-Header Version 2 verwenden.
  • Android 9 muss Boot-Header Version 1 verwenden.
  • Es wird davon ausgegangen, dass Android 8 und niedriger einen Boot-Image-Header der Version 0 verwenden.

Bei allen Geräten mit Android 9 oder höher prüft die Vendor Test Suite (VTS) das Format des boot/recovery Images, um sicherzustellen, dass der Boot-Image-Header die richtige Version verwendet. Um AOSP-Details zu allen derzeit unterstützten Boot- und Hersteller-Boot-Image-Headern anzuzeigen, lesen Sie system/tools/mkbootimg/include/bootimg/bootimg.h .

Implementierung der Versionierung des Boot-Image-Headers

Das mkbootimg Tool akzeptiert die folgenden Argumente.

Streit Beschreibung
header_version Legt die Boot-Image-Header-Version fest. Ein Boot-Image mit einer Header-Version:
  • 1 oder 2 unterstützt ein Wiederherstellungs-DTBO-Image oder ein Wiederherstellungs-ACPIO-Image.
  • 3 unterstützt keine Wiederherstellungsimages.
recovery_dtbo Wird für Architekturen verwendet, die DTB verwenden. Gibt den Pfad zum Wiederherstellungs-DTBO-Image an. Optional für A/B-Geräte, die kein Wiederherstellungsimage benötigen. Nicht-A/B-Geräte mit header_version :
  • 1 oder 2 können diesen Pfad angeben oder den Abschnitt recovery_acpio verwenden, um einen Pfad zu einem Wiederherstellungs-ACPIO-Image anzugeben.
  • 3 kann kein Wiederherstellungs-DTBO-Image angeben.
recovery_acpio Wird für Architekturen verwendet, die ACPI anstelle von DTB verwenden. Gibt den Pfad zum Wiederherstellungs-ACPIO-Image an. Optional für A/B-Geräte, die kein Wiederherstellungsimage benötigen. Nicht-A/B-Geräte mit header_version :
  • 1 oder 2 können diesen Pfad angeben oder den Abschnitt recovery_dtbo verwenden, um einen Pfad zu einem Wiederherstellungs-DTBO-Image anzugeben.
  • 3 kann kein Wiederherstellungs-ACPIO-Image angeben.
dtb Pfad zum DTB-Image, das in den Start-/Wiederherstellungsimages enthalten ist.
dtb_offset Stellt beim Hinzufügen zum base die physische Ladeadresse für den endgültigen Gerätebaum bereit. Wenn das base beispielsweise 0x10000000 und das Argument dtb_offset 0x01000000 ist, wird das dtb_addr_field im Boot-Image-Header mit 0x11000000 gefüllt.

Das Gerät BoardConfig.mk verwendet die Konfiguration BOARD_MKBOOTIMG_ARGS , um header version zu den anderen Board-spezifischen Argumenten von mkbootimg hinzuzufügen. Zum Beispiel:

BOARD_MKBOOTIMG_ARGS := --ramdisk_offset $(BOARD_RAMDISK_OFFSET) --tags_offset $(BOARD_KERNEL_TAGS_OFFSET) --header_version $(BOARD_BOOTIMG_HEADER_VERSION)

Das Android-Build-System verwendet die BoardConfig Variable BOARD_PREBUILT_DTBOIMAGE , um das Argument recovery_dtbo des Tools „ mkbootimg “ während der Erstellung des Wiederherstellungsimages festzulegen. Einzelheiten zu den Änderungen des Android Open Source Project (AOSP) finden Sie in den zugehörigen Änderungslisten für die Versionierung des Boot-Image-Headers .

Boot-Image-Header, Version 4

Android 12 stellt im Boot-Image-Header der Version 4 eine boot_signature zur Verfügung, mit der sich die Integrität des Kernels und der Ramdisk überprüfen lässt. Die Prüfung erfolgt in VtsSecurityAvbTest und ist für Geräte erforderlich, die die GKI-Architektur verwenden. Die boot_signature ist jedoch nicht am gerätespezifischen verifizierten Startvorgang beteiligt und wird nur in VTS verwendet. Weitere Informationen finden Sie unter „GKI boot.img-Board-Konfiguration“ und „GKI-verifizierte Starteinstellungen“ .

Der Hersteller-Boot-Image-Header Version 4 unterstützt mehrere Hersteller-Ramdisk-Fragmente.

Version 4 der Boot-Image-Header-Version verwendet das folgende 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 aktualisiert den Boot-Image-Header auf Version 3, wodurch die folgenden Daten entfernt werden:

  • Bootloader der zweiten Stufe. Die Felder second_size und second_addr erscheinen nicht mehr im Boot-Image-Header. Geräte mit einem Bootloader der zweiten Stufe müssen diesen Bootloader in einer eigenen Partition speichern.

  • Wiederherstellungsbild. Die Anforderung zur Angabe eines Wiederherstellungsabbilds ist veraltet und die Felder recovery_dtbo_size “, recovery_dtbo_offset “, recovery_acpio_size “ und „ recovery_acpio_offset “ werden nicht mehr im Header des Startabbilds angezeigt.

    • A/B-Geräte verwenden ein Update- und Wiederherstellungsschema, das es unnötig macht, ein DTBO- oder ACPIO-Image für die Wiederherstellung anzugeben.

    • Nicht-A/B-Geräte, die ein Wiederherstellungsimage (entweder DTBO oder ACPIO) angeben möchten, sollten Boot-Image-Header Version 1 oder 2 verwenden.

  • Gerätebaum-Blob (DTB). Das DTB wird in der Boot-Partition des Anbieters gespeichert, sodass die Felder dtb_size und dtb_addr nicht mehr im Boot-Image-Header angezeigt werden (aber im Boot-Image-Header des Anbieters vorhanden sind).

Geräte können den Boot-Image-Header Version 3 verwenden, um der Generic Kernel Image (GKI) -Architektur zu entsprechen, die den Kernel vereinheitlicht und Herstellermodule, die für den Start erforderlich sind, in die vendor_boot Partition verschiebt (was bedeutet, dass das Boot-Image nur GKI-Komponenten enthält). Geräte, die:

  • Verwenden Sie GKI (erfordert den Android-4.19- oder Android-5.4-Kernel), aber verwenden Sie nicht. A/B-Updates können ein Wiederherstellungsimage angeben, indem Sie Boot-Image Version 3 für das Boot-Image und Boot-Image Version 2 für das Wiederherstellungs-Image verwenden.

  • Verwenden Sie kein GKI und keine A/B-Updates. Sie können ein Wiederherstellungsimage angeben, indem Sie Boot-Image Version 1 oder 2 sowohl für Boot- als auch für Wiederherstellungsimages verwenden.

Version 3 der Boot-Image-Header-Version verwendet das folgende 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 aktualisiert den Boot-Image-Header auf Version 2, wodurch ein Abschnitt für Wiederherstellungs -DTB-Image- Informationen (Image-Größe und physische Ladeadresse) hinzugefügt wird.

Version 2 der Boot-Image-Header-Version verwendet das folgende 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 wandelt das unused Feld des Boot-Image-Headers in ein Header-Versionsfeld um. Geräte, die mit Android 9 gestartet werden, müssen den Boot-Image-Header verwenden, wobei die Header-Version auf 1 oder höher eingestellt ist (dies wird von VTS überprüft).

Version 1 der Boot-Image-Header-Version verwendet das folgende 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 */
};

Nicht-A/B-Geräte können ein DTB/ACPI-Overlay-Image für die Wiederherstellung angeben, um Fehler bei Over-the-Air-Updates (OTA) zu vermeiden. (A/B-Geräte haben dieses Problem nicht und müssen kein Overlay-Image angeben.) Sie können entweder ein DTBO-Image oder ein ACPIO-Image angeben, aber nicht beides (da sie von unterschiedlichen Architekturen verwendet werden). So konfigurieren Sie den Boot-Image-Header korrekt, wenn Sie Folgendes verwenden:

  • Ein DTBO-Image für die Wiederherstellung, einschließlich der Felder recovery_dtbo_size “ und recovery_dtbo_offset (und nicht der Felder recovery_acpio_size und recovery_acpio_offset “).

  • Ein ACPIO-Image für die Wiederherstellung, einschließlich der Felder recovery_acpio_size “ und recovery_acpio_offset (und nicht der Felder recovery_dtbo_size und recovery_dtbo_offset “).

Das Feld header_size enthält die Größe des Boot-Image-Headers. Wenn die Boot-Image-Header-Version auf 1 gesetzt ist, enthält das id Feld zusätzlich zu den Abschnitten kernel “, „ ramdisk “ und second sections “ den SHA-1-Digest für den Abschnitt recovery_[dtbo|acpio] des Boot-Images. Einzelheiten zu den Feldern recovery_[dtbo|acpio]_size und recovery_[dtbo|acpio]_offset finden Sie unter Wiederherstellungsimages .

Legacy-Boot-Image-Header, Version 0

Bei Geräten, die vor Android 9 gestartet wurden und den Legacy-Boot-Image-Header verwenden, wird davon ausgegangen, dass sie einen Boot-Image-Header der Version 0 verwenden.

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