Android 11 führte das Konzept des Generic Kernel Image (GKI) ein. Um ein einfaches Booten eines beliebigen Geräts mit der GKI zu ermöglichen, können Android 11-Geräte den Boot-Image-Header Version 3 verwenden. In Version 3 werden alle herstellerspezifischen Informationen aus der boot
Partition herausgerechnet und in eine neue vendor_boot
-Partition verschoben. Ein ARM64-Gerät, das mit Android 11 auf dem 5.4-Linux-Kernel gestartet wird, muss die vendor_boot
Partition und das aktualisierte boot
Partitionsformat unterstützen, um die Tests mit dem GKI zu bestehen.
Android 12-Geräte können die Boot-Image-Header-Version 4 verwenden, die das Einschließen mehrerer Anbieter-Ramdisks in die vendor_boot
Partition unterstützt. Mehrere Vendor-Ramdisk-Fragmente werden im Vendor-Ramdisk-Abschnitt nacheinander verkettet. Eine Vendor-Ramdisk-Tabelle wird verwendet, um das Layout des Vendor-Ramdisk-Abschnitts und die Metadaten jedes Vendor-Ramdisk-Fragments zu beschreiben.
Partitionsstruktur
Die Bootpartition des Anbieters ist A/B-geladen mit virtuellem A/B und durch Android Verified Boot geschützt.
Fassung 3
Die Partition besteht aus einem Header, der Ramdisk des Anbieters und dem Device Tree Blob (DTB).
Abschnitt | Seitenzahl |
---|---|
Boot-Header des Anbieters (n Seiten) | n = (2112 + page_size - 1) / page_size |
Anbieter Ramdisk (o Seiten) | o = (vendor_ramdisk_size + page_size - 1) / page_size |
DTB (p Seiten) | p = (dtb_size + page_size - 1) / page_size |
Fassung 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 |
---|---|
Boot-Header des Anbieters (n Seiten) | n = (2128 + page_size - 1) / page_size |
Hersteller-Ramdisk-Fragmente (o Seiten) | o = (vendor_ramdisk_size + page_size - 1) / page_size |
DTB (p Seiten) | p = (dtb_size + page_size - 1) / page_size |
Hersteller-Ramdisk-Tabelle (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 Hersteller-Startpartitions-Headers besteht hauptsächlich aus Daten, die aus dem Start-Image-Header dorthin verschoben wurden. Es enthält auch Informationen über die Ramdisk des Herstellers.
Fassung 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 */
};
Fassung 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 Ramdisk-Fragmente des Anbieters. -
ramdisk_type
bezeichnet den Typ der Ramdisk, mögliche Werte sind:-
VENDOR_RAMDISK_TYPE_NONE
gibt an, dass der Wert nicht angegeben ist. -
VENDOR_RAMDISK_TYPE_PLATFORM
Ramdisks enthalten plattformspezifische Bits. Der Bootloader muss diese immer in den Speicher laden. -
VENDOR_RAMDISK_TYPE_RECOVERY
Ramdisks enthalten Wiederherstellungsressourcen. Der Bootloader muss diese beim Booten in die Wiederherstellung in den Arbeitsspeicher laden. -
VENDOR_RAMDISK_TYPE_DLKM
Ramdisks enthalten dynamisch ladbare Kernelmodule.
-
-
ramdisk_name
ist ein eindeutiger Name der Ramdisk. -
board_id
ist ein Vektor von anbieterdefinierten Hardwarekennungen.
Bootloader-Unterstützung
Da die Boot-Partition des Anbieters Informationen enthält (z. B. Flash-Seitengröße, Kernel, Ladeadressen der Ramdisk, den DTB selbst), die zuvor in der Boot-Partition vorhanden waren, muss der Bootloader sowohl auf die Boot- als auch auf die Boot-Partition des Anbieters zugreifen, um genügend Daten zum Abschließen des Bootens zu haben .
Der Bootloader muss die generische Ramdisk unmittelbar nach der Anbieter-Ramdisk in den Speicher laden (die Formate CPIO, Gzip und lz4 unterstützen diese Art der Verkettung). Richten Sie das generische Ramdisk-Image nicht an den Seiten aus und fügen Sie keine anderen Leerzeichen zwischen ihm und dem Ende der Anbieter-Ramdisk im Speicher ein. Nachdem der Kernel dekomprimiert hat, extrahiert er die verkettete Datei in ein initramfs
, was zu einer Dateistruktur führt, bei der es sich um eine generische Ramdisk handelt, die der Dateistruktur der Ramdisk des Anbieters überlagert ist.
Da die generische Ramdisk und die Anbieter-Ramdisk verkettet werden, müssen sie dasselbe Format haben. Das GKI-Boot-Image verwendet eine lz4-komprimierte generische Ramdisk, sodass ein Gerät, das GKI-konform ist, eine lz4-komprimierte Ramdisk eines Anbieters verwenden muss. Die Konfiguration dafür ist unten dargestellt.
Die Bootloader-Anforderungen zur Unterstützung von bootconfig werden auf der Seite Implementing Bootconfig erläutert.
Ramdisks mehrerer Anbieter (Version 4)
Mit der Boot-Image-Header-Version 4 kann der Bootloader entweder eine Teilmenge oder alle Ramdisks des Herstellers auswählen, die während des Bootens als initramfs
geladen werden sollen. Die Hersteller-Ramdisk-Tabelle enthält die Metadaten jeder Ramdisk und kann dem Bootloader bei der Entscheidung helfen, welche Ramdisk geladen werden soll. Der Bootloader kann entscheiden, in welcher Reihenfolge die ausgewählten Hersteller-Ramdisks geladen werden, solange die generische Ramdisk zuletzt geladen wird.
Beispielsweise kann der Bootloader das Laden von Anbieter-Ramdisks des Typs VENDOR_RAMDISK_TYPE_RECOVERY
während des normalen Bootens auslassen, um Ressourcen zu sparen, sodass nur Anbieter-Ramdisks des Typs VENDOR_RAMDISK_TYPE_PLATFORM
und VENDOR_RAMDISK_TYPE_DLKM
in den Arbeitsspeicher geladen werden. Andererseits werden Hersteller-Ramdisks vom Typ VENDOR_RAMDISK_TYPE_PLATFORM
, VENDOR_RAMDISK_TYPE_RECOVERY
und VENDOR_RAMDISK_TYPE_DLKM
beim Booten im Wiederherstellungsmodus in den Arbeitsspeicher geladen.
Alternativ kann der Bootloader die Vendor-Ramdisk-Tabelle ignorieren und den gesamten Vendor-Ramdisk-Abschnitt laden. Dies hat den gleichen Effekt wie das Laden aller Ramdisk-Fragmente des Herstellers in der vendor_boot
Partition.
Unterstützung aufbauen
So implementieren Sie Anbieter-Boot-Unterstützung für ein Gerät:
Setzen
BOARD_BOOT_HEADER_VERSION
auf3
oder höher.Setzen
BOARD_RAMDISK_USE_LZ4
auf „true
“, wenn Ihr Gerät GKI-kompatibel ist oder anderweitig eine lz4-komprimierte generische Ramdisk verwendet.Stellen Sie
BOARD_VENDOR_BOOTIMAGE_PARTITION_SIZE
auf eine angemessene Größe für Ihr Gerät ein, unter Berücksichtigung der Kernel-Module, die auf der Ramdisk des Anbieters installiert werden müssen.Aktualisieren
AB_OTA_PARTITIONS
, umvendor_boot
und alle herstellerspezifischen Listen von OTA-Partitionen auf dem Gerät einzuschließen.Kopieren Sie Ihre Geräte-
fstab
in/first_stage_ramdisk
in dervendor_boot
Partition, nicht in derboot
Partition. Beispiel:$(LOCAL_PATH)/fstab.hardware:$(TARGET_COPY_OUT_VENDOR_RAMDISK)/first_stage_ramdisk/fstab.$(PRODUCT_PLATFORM)
.
So schließen Sie mehrere Hersteller-Ramdisks in vendor_boot
:
- Legen Sie
BOARD_BOOT_HEADER_VERSION
auf4
fest. Legen Sie
BOARD_VENDOR_RAMDISK_FRAGMENTS
auf eine Liste mit logischen Ramdisk-Fragmentnamen von Anbietern fest, die invendor_boot
eingeschlossen werden sollen.Um eine vorgefertigte Ramdisk eines Anbieters hinzuzufügen, legen
BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).PREBUILT
auf den vorgefertigten Dateipfad fest.Um eine Ramdisk eines DLKM-Anbieters hinzuzufügen, setzen
BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).KERNEL_MODULE_DIRS
auf die Liste der einzuschließenden Kernel-Modulverzeichnisse.Setzen
BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).MKBOOTIMG_ARGS
aufmkbootimg
Argumente. Dies sind die Argumente--board_id[0-15]
und--ramdisk_type
für das Ramdisk-Fragment des Anbieters. Für Ramdisk des DLKM-Anbieters wäre der Standardwert für--ramdisk_type
DLKM
, wenn nicht anders angegeben.
So erstellen Sie Wiederherstellungsressourcen als eigenständige recovery
-Ramdisk in vendor_boot
:
- Legen Sie
BOARD_BOOT_HEADER_VERSION
auf4
fest. - Setzen
BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT
auftrue
. - Setzen
BOARD_INCLUDE_RECOVERY_RAMDISK_IN_VENDOR_BOOT
auftrue
. - Dadurch wird ein Anbieter-Ramdisk-Fragment hinzugefügt, dessen
ramdisk_name
recovery
undramdisk_type
VENDOR_RAMDISK_TYPE_RECOVERY
. Die Ramdisk enthält dann alle Wiederherstellungsdateien, die unter$(TARGET_RECOVERY_ROOT_OUT)
installiert sind.
mkbootimg
Argumente
Streit | Beschreibung |
---|---|
--ramdisk_type | Der Typ der Ramdisk kann entweder NONE , PLATFORM , RECOVERY oder DLKM . |
--board_id[0-15] | Geben Sie den board_id Vektor an, standardmäßig 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
Der sich daraus ergebende „ vendor_boot
würde zwei Anbieter-Ramdisk-Fragmente enthalten. Die erste ist die "Standard"-Ramdisk, die das DLKM-Verzeichnis baz
und den Rest der Dateien in $(TARGET_VENDOR_RAMDISK_OUT)
. Die zweite ist die Ramdisk dlkm_foobar
, die die DLKM-Verzeichnisse foo
und bar
enthält, und --ramdisk_type
standardmäßig DLKM
.