Boot-Partitionen des Anbieters

Android 11 führte das Konzept des Generic Kernel Image (GKI) ein. So aktivieren Sie einfach ein beliebiges Gerät mit der GKI Booten, Android 11 Geräte können Boot - Image - Header Version 3. In der Version 3 sind alle herstellerspezifischen Informationen berücksichtigt die aus der Nutzung boot - Partition und verlagert in eine neue vendor_boot Partition. Ein ARM64 Gerät Abschuss mit Android 11 auf dem Linux - Kernel 5.4 muss die Unterstützung vendor_boot Partition und das aktualisierte boot - Partition - Formats mit der GKI passieren zu testen.

Android 12 Geräte können Boot - Image - Header Version 4, die Träger, die mehrere Anbieter ramdisks in der Verwendung vendor_boot Partition. Mehrere Ramdisk-Fragmente von Herstellern werden nacheinander im Bereich der Hersteller-Ramdisk verkettet. Eine Hersteller-Ramdisk-Tabelle wird verwendet, um das Layout des Hersteller-Ramdisk-Abschnitts und die Metadaten jedes Hersteller-Ramdisk-Fragments zu beschreiben.

Partitionsstruktur

Die Bootpartition des Anbieters ist mit virtuellem A/B A/B-verknüpft und durch Android Verified Boot geschützt.

Version 3

Die Partition besteht aus einem Header, der Ramdisk des Herstellers und dem Device Tree Blob (DTB).

Abschnitt Seitenzahl
Bootheader des Anbieters (n Seiten) n = (2112 + page_size - 1) / page_size
Ramdisk des Anbieters (o Seiten) o = (vendor_ramdisk_size + page_size - 1) / page_size
DTB (p Seiten) p = (dtb_size + page_size - 1) / page_size

Version 4

Die Partition besteht aus einem Header, dem Vendor-Ramdisk-Abschnitt (bestehend aus allen Vendor-Ramdisk-Fragmenten, verkettet), dem Device Tree Blob (DTB) und der Vendor-Ramdisk-Tabelle.

Abschnitt Seitenzahl
Bootheader des Anbieters (n Seiten) n = (2128 + page_size - 1) / page_size
Ramdisk-Fragmente des Anbieters (o Seiten) o = (vendor_ramdisk_size + page_size - 1) / page_size
DTB (p Seiten) p = (dtb_size + page_size - 1) / page_size
Ramdisk-Tabelle des Anbieters (q Seiten) q = (vendor_ramdisk_table_size + page_size - 1) / page_size
Bootconfig (r Seiten) r = (bootconfig_size + page_size - 1) / page_size

Boot-Header des Anbieters

Der Inhalt des Anbieter - Boot - Partition Header besteht hauptsächlich aus Daten , die von den dort verlagert worden sind Boot - Image - Header . Es enthält auch Informationen über die Ramdisk des Herstellers.

Version 3

struct vendor_boot_img_hdr_v3
{
#define VENDOR_BOOT_MAGIC_SIZE 8
    uint8_t magic[VENDOR_BOOT_MAGIC_SIZE];
    uint32_t header_version;
    uint32_t page_size;           /* flash page size we assume */

    uint32_t kernel_addr;         /* physical load addr */
    uint32_t ramdisk_addr;        /* physical load addr */

    uint32_t vendor_ramdisk_size; /* size in bytes */

#define VENDOR_BOOT_ARGS_SIZE 2048
    uint8_t cmdline[VENDOR_BOOT_ARGS_SIZE];

    uint32_t tags_addr;           /* physical addr for kernel tags */

#define VENDOR_BOOT_NAME_SIZE 16
    uint8_t name[VENDOR_BOOT_NAME_SIZE]; /* asciiz product name */
    uint32_t header_size;         /* size of vendor boot image header in
                                   * bytes */
    uint32_t dtb_size;            /* size of dtb image */
    uint64_t dtb_addr;            /* physical load address */

};

Version 4

struct vendor_boot_img_hdr_v4
{
#define VENDOR_BOOT_MAGIC_SIZE 8
    uint8_t magic[VENDOR_BOOT_MAGIC_SIZE];
    uint32_t header_version;
    uint32_t page_size;           /* flash page size we assume */

    uint32_t kernel_addr;         /* physical load addr */
    uint32_t ramdisk_addr;        /* physical load addr */

    uint32_t vendor_ramdisk_size; /* size in bytes */

#define VENDOR_BOOT_ARGS_SIZE 2048
    uint8_t cmdline[VENDOR_BOOT_ARGS_SIZE];

    uint32_t tags_addr;           /* physical addr for kernel tags */

#define VENDOR_BOOT_NAME_SIZE 16
    uint8_t name[VENDOR_BOOT_NAME_SIZE]; /* asciiz product name */
    uint32_t header_size;         /* size of vendor boot image header in
                                   * bytes */
    uint32_t dtb_size;            /* size of dtb image */
    uint64_t dtb_addr;            /* physical load address */

    uint32_t vendor_ramdisk_table_size; /* size in bytes for the vendor ramdisk table */
    uint32_t vendor_ramdisk_table_entry_num; /* number of entries in the vendor ramdisk table */
    uint32_t vendor_ramdisk_table_entry_size; /* size in bytes for a vendor ramdisk table entry */
    uint32_t bootconfig_size; /* size in bytes for the bootconfig section */
};

#define VENDOR_RAMDISK_TYPE_NONE 0
#define VENDOR_RAMDISK_TYPE_PLATFORM 1
#define VENDOR_RAMDISK_TYPE_RECOVERY 2
#define VENDOR_RAMDISK_TYPE_DLKM 3

struct vendor_ramdisk_table_entry_v4
{
    uint32_t ramdisk_size; /* size in bytes for the ramdisk image */
    uint32_t ramdisk_offset; /* offset to the ramdisk image in vendor ramdisk section */
    uint32_t ramdisk_type; /* type of the ramdisk */
#define VENDOR_RAMDISK_NAME_SIZE 32
    uint8_t ramdisk_name[VENDOR_RAMDISK_NAME_SIZE]; /* asciiz ramdisk name */

#define VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE 16
    // Hardware identifiers describing the board, soc or platform which this
    // ramdisk is intended to be loaded on.
    uint32_t board_id[VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE];
};
  • vendor_ramdisk_size ist die Gesamtgröße aller Anbieter RAM - Disk - Fragmente.
  • ramdisk_type bezeichnet den Typ der RAM - Disk, möglich , Werte sind:
    • VENDOR_RAMDISK_TYPE_NONE gibt den Wert nicht spezifiziert ist.
    • VENDOR_RAMDISK_TYPE_PLATFORM ramdisks enthalten plattformspezifische Bits. Der Bootloader muss diese immer in den Speicher laden.
    • VENDOR_RAMDISK_TYPE_RECOVERY ramdisks enthalten Recovery - Ressourcen. Der Bootloader muss diese beim Booten in die Wiederherstellung in den Speicher laden.
    • VENDOR_RAMDISK_TYPE_DLKM ramdisks enthalten dynamisch ladbare Kernel - Module.
  • ramdisk_name ist ein eindeutiger Name des RAM - Disk.
  • board_id ist ein Vektor von Herstellern definierten Hardware - IDs.

Bootloader-Unterstützung

Da die Boot-Partition des Anbieters Informationen enthält (wie Flash-Seitengröße, Kernel, Ramdisk-Ladeadressen, die DTB selbst), die zuvor in der Boot-Partition vorhanden waren, muss der Bootloader sowohl auf die Boot- als auch auf die Boot-Partitionen des Anbieters zugreifen, um über genügend Daten zu verfügen, um den Bootvorgang abzuschließen .

Der Bootloader muss den generischen RAM - Disk in dem Speicher geladen werden unmittelbar nach dem Anbieter - RAM - Disk (die CPIO, gzip und LZ4 Formate unterstützen diese Art der Verkettung). Führen Sie keine Seitenausrichtung des generischen Ramdisk-Images durch und fügen Sie keinen anderen Platz zwischen ihm und dem Ende der Ramdisk des Herstellers im Speicher ein. Nach dem Kernel dekomprimiert, extrahiert er die verketteten Datei in ein initramfs , die Ergebnisse in einer Dateistruktur , die auf der Anbieter - RAM - Disk - Dateistruktur eine generische Ramdisk überlagerte ist.

Da die generische Ramdisk und die Vendor-Ramdisk verkettet werden, müssen sie das gleiche Format haben. Das GKI-Boot-Image verwendet eine lz4-komprimierte generische Ramdisk, sodass ein Gerät, das GKI-kompatibel ist, eine lz4-komprimierte Ramdisk eines Anbieters verwenden muss. Die Konfiguration dafür ist unten dargestellt.

Die Bootloader - Anforderungen für bootconfig unterstützen , werden auf der erläuterten Ausführungs bootconfig Seite.

Ramdisks mehrerer Anbieter (Version 4)

Mit Boot - Image - Header Version 4 kann der Bootloader wählen Sie entweder eine Teilmenge oder alle der Anbieter ramdisks zu Last als die initramfs beim Booten. Die Ramdisk-Tabelle des Herstellers enthält die Metadaten jeder Ramdisk und kann dem Bootloader bei der Entscheidung helfen, welche Ramdisks geladen werden sollen. Der Bootloader kann entscheiden, in welcher Reihenfolge die Ramdisks des ausgewählten Herstellers geladen werden, solange die generische Ramdisk zuletzt geladen wird.

Zum Beispiel kann der Bootloader Laden Anbieter ramdisks vom Typ auslassen VENDOR_RAMDISK_TYPE_RECOVERY während des normalen Boot zu schonen Ressourcen, so dass nur Anbieter ramdisks vom Typ VENDOR_RAMDISK_TYPE_PLATFORM und VENDOR_RAMDISK_TYPE_DLKM in den Speicher geladen. Auf der anderen Seite, Anbieter ramdisks vom Typ VENDOR_RAMDISK_TYPE_PLATFORM , VENDOR_RAMDISK_TYPE_RECOVERY und VENDOR_RAMDISK_TYPE_DLKM in dem Speicher geladen , wenn in der Recovery - Modus zu booten.

Alternativ kann der Bootloader die Vendor-Ramdisk-Tabelle ignorieren und den gesamten Vendor-Ramdisk-Abschnitt laden. Dies hat die gleiche Wirkung hat wie alle der Anbieter Ramdisk - Fragmente im Laden vendor_boot Partition.

Build-Unterstützung

So implementieren Sie die Boot-Unterstützung des Anbieters für ein Gerät:

  • Set BOARD_BOOT_HEADER_VERSION bis 3 oder mehr beträgt .

  • Set BOARD_RAMDISK_USE_LZ4 zu true , wenn Ihr Gerät ist GKI-kompatibel ist , oder wenn es anders verwendet einen LZ 4-komprimierte generic Ramdisk.

  • Set BOARD_VENDOR_BOOTIMAGE_PARTITION_SIZE auf eine geeignete Größe für das Gerät, die Kernel - Module unter Berücksichtigung , die auf dem Anbieter Ramdisk gehen muß.

  • Update AB_OTA_PARTITIONS enthalten vendor_boot und alle herstellerspezifischen Listen der OTA - Partitionen auf dem Gerät.

  • Kopieren Sie Ihr Gerät fstab in /first_stage_ramdisk in der vendor_boot Partition nicht die boot - Partition. Zum Beispiel $(LOCAL_PATH)/fstab.hardware:$(TARGET_COPY_OUT_VENDOR_RAMDISK)/first_stage_ramdisk/fstab.$(PRODUCT_PLATFORM) .

Um mehrere Anbieter ramdisks in umfassen vendor_boot :

  • Set BOARD_BOOT_HEADER_VERSION bis 4 .
  • Set BOARD_VENDOR_RAMDISK_FRAGMENTS auf eine Liste von logischen Anbieter Ramdisk Fragment Namen in einbezogen werden vendor_boot .

  • Einen vorkompilierte Anbieter Ramdisk, Satz hinzuzufügen BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).PREBUILT zum prebuilt Dateipfad.

  • Um einen DLKM Anbieter Ramdisk, Satz hinzufügen BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).KERNEL_MODULE_DIRS in der Liste der Kernel - Modul Verzeichnisse enthalten sein.

  • Set BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).MKBOOTIMG_ARGS mkbootimg Argumente. Dies sind die --board_id[0-15] und --ramdisk_type Argumente für den Verkäufer Ramdisk Fragment. Für DLKM Anbieter Ramdisk, der Standard - --ramdisk_type wäre DLKM , wenn es nicht anders angegeben ist.

Um Recovery - Ressourcen als eigenständiger zu bauen recovery Ramdisk in vendor_boot :

  • Set BOARD_BOOT_HEADER_VERSION bis 4 .
  • Set BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT zu true .
  • Set BOARD_INCLUDE_RECOVERY_RAMDISK_IN_VENDOR_BOOT zu true .
  • Dies fügt einen Anbieter Ramdisk Fragment , dessen ramdisk_name ist recovery und ramdisk_type ist VENDOR_RAMDISK_TYPE_RECOVERY . Der RAM - Disk enthält dann alle Recovery - Dateien, die Dateien unter installiert sind $(TARGET_RECOVERY_ROOT_OUT) .

mkbootimg Argumente

Streit Beschreibung
--ramdisk_type Der Typ des RAM - Disk kann eines sein, von NONE , PLATFORM , RECOVERY oder DLKM .
--board_id[0-15] Geben Sie den board_id Vektor, standardmäßig auf 0 .

Nachfolgend eine Beispielkonfiguration:

BOARD_KERNEL_MODULE_DIRS := foo bar baz
BOARD_BOOT_HEADER_VERSION := 4
BOARD_VENDOR_RAMDISK_FRAGMENTS := dlkm_foobar
BOARD_VENDOR_RAMDISK_FRAGMENT.dlkm_foobar.KERNEL_MODULE_DIRS := foo bar
BOARD_VENDOR_RAMDISK_FRAGMENT.dlkm_foobar.MKBOOTIMG_ARGS := --board_id0 0xF00BA5 --board_id1 0xC0FFEE

Die sich ergebende vendor_boot würde zwei Anbieter - RAM - Disk - Fragmente enthalten. Die erste ist die „default“ Ramdisk, die das DLKM Verzeichnis enthält baz und den Rest der Dateien in $(TARGET_VENDOR_RAMDISK_OUT) . Die zweite ist die dlkm_foobar RAM - Disk, die die DLKM Verzeichnisse enthält foo und bar , und die --ramdisk_type standardmäßig DLKM .