Bootconfig in Android 12 implementieren

In Android 12 ersetzt die Bootconfig-Funktion die Kernel-Cmdline-Optionen androidboot.*, die unter Android 11 und niedriger verwendet werden. Die Funktion „bootconfig“ ist ein Mechanismus, mit dem Konfigurationsdetails vom Build und Bootloader an Android 12 übergeben werden.

Diese Funktion bietet eine Möglichkeit, die Konfigurationsparameter für den Android-Nutzerbereich von denen für den Kernel zu trennen. Durch das Verschieben der langen androidboot.*-Kernelparameter in die bootconfig-Datei wird Speicherplatz auf der Kernel-Cmdline geschaffen und für eine zukünftige Erweiterung zur Verfügung gestellt.

Sowohl der Kernel als auch der Android-Nutzerbereich müssen bootconfig unterstützen.

  • Erste Version mit dieser Unterstützung: Android 12
  • Erste Kernel-Version mit dieser Unterstützung: 12-5.4.xx Kernel

Implementieren Sie die Bootconfig-Funktion für neue Geräte, die mit einer Kernel-Version von 12-5.10.xx auf den Markt gebracht werden. Sie müssen diese nicht implementieren, wenn Sie Geräte aktualisieren.

Beispiele und Quelle

Wenn Sie sich die Beispiele und den Quellcode in diesem Abschnitt ansehen, beachten Sie, dass sich das Format des bootconfig-Codes nur geringfügig vom Format der Kernel-Cmdline unterscheidet, die unter Android 11 und niedriger verwendet wird. Der folgende Unterschied ist jedoch für Ihre Verwendung wichtig:

  • Parameter müssen durch die Escapesequenz \n für Zeilenumbrüche getrennt werden, nicht durch Leerzeichen.

Bootloader-Beispiel

Ein Bootloader-Beispiel finden Sie in der Implementierung des U-Boot-Referenz-Bootloaders von Cuttlefish. Zwei Commits in der Referenz sind unten aufgeführt. Zuerst wird die Unterstützung der Boot-Header-Version auf die neueste Version erhöht. Im Beispiel aktualisiert das erste Commit die Versionsunterstützung auf die nächste Version, v4. Im zweiten Schritt wird eine Bootconfig-Verarbeitung hinzugefügt und das Hinzufügen von Parametern während der Laufzeit demonstriert:

Build-Beispiel

Ein Build-Beispiel, das mkbootimg-Änderungen zum Erstellen von vendor_boot.img mit dem Boot-Header des Anbieters Version 4 zeigt, findest du unter mkbootimg changes for bootconfig. In den Änderungen an Sepien sehen Sie Folgendes:

Implementierung

Partner müssen Unterstützung für ihre Bootloader hinzufügen und ihre androidboot.*-Parameter zur Erstellungszeit von der Kernel-Cmdline in die Bootconfig-Datei verschieben. Am besten implementieren Sie diese Änderung inkrementell. Informationen zum Verfolgen eines inkrementellen Prozesses finden Sie im Abschnitt Inkrementelle Implementierung und Validierung.

Verweisen Sie stattdessen auf die Datei /proc/bootconfig, wenn in der Datei „/proc/cmdline“ nach Änderungen nach androidboot.*-Parametern gesucht wird. Die ro.boot.*-Attribute werden mit den neuen bootconfig-Werten festgelegt, sodass Sie mit diesen Attributen keine Änderungen am Code vornehmen müssen.

Build-Änderungen

Erhöhen Sie zuerst Ihre Boot-Header-Version auf Version 4:

- BOARD_BOOT_HEADER_VERSION := 3

+ BOARD_BOOT_HEADER_VERSION := 4

Fügen Sie den Kernel-cmdline-Parameter bootconfig hinzu. Dadurch sucht der Kernel nach dem Abschnitt „bootconfig“:

BOARD_KERNEL_CMDLINE += bootconfig

Die bootconfig-Parameter werden aus den Parametern in der Variablen BOARD_BOOTCONFIG erstellt, ähnlich wie die Kernel-Cmdline aus BOARD\_KERNEL\_CMDLINE.

Alle androidboot.*-Parameter können unverändert verschoben werden. Das sieht dann so aus:

- BOARD_KERNEL_CMDLINE += androidboot..selinux=enforcing

+ BOARD_BOOTCONFIG += androidboot..selinux=enforcing

Bootloader-Änderungen

Der Bootloader richtet initramfs ein, bevor er zum Kernel wechselt. Die Kernel-Bootkonfiguration sucht nach dem bootconfig-Abschnitt und sucht danach, ob sich dieser mit dem erwarteten Trailer ganz am Ende von initramfs, befindet.

Der Bootloader ruft die Layoutinformationen für vendor_boot.img aus dem Boot-Image-Header des Anbieters ab.

Diagramm des Layouts für die Speicherzuweisung von Bootconfig

Abbildung 1: Arbeitsspeicherzuweisung für Android 12-Bootconfig

Der Bootloader erstellt den Bootconfig-Abschnitt im Arbeitsspeicher. Der Abschnitt „bootconfig“ enthält Arbeitsspeicherzuweisungen für Folgendes:

  • Parameter
  • 4 B Größe parameters size
  • 4 B Größe parameters checksum
  • 12 Mrd. magischer Bootconfig-String (#BOOTCONFIG\n)

Die Parameter stammen aus zwei Quellen: Parameter, die zum Zeitpunkt der Build-Erstellung bekannt sind, und Parameter, die zum Zeitpunkt der Build-Erstellung nicht bekannt sind. Unbekannte Parameter müssen hinzugefügt werden.

Zum Zeitpunkt der Build-Erstellung bekannte Parameter werden im Abschnitt "bootconfig" am Ende des Images vendor_boot gepackt. Die Größe des Abschnitts wird (als Byte) im Boot-Header-Feld vendor_bootconfig_size des Anbieters gespeichert.

Die Parameter, die zum Zeitpunkt der Erstellung nicht bekannt sind, sind nur während der Laufzeit im Bootloader bekannt. Diese müssen am Ende des Abschnitts „Bootconfig-Parameter“ hinzugefügt werden, bevor der bootconfig-Trailer angewendet wird.

Wenn Sie nach dem Anwenden des bootconfig-Trailers Parameter hinzufügen müssen, überschreiben Sie den Trailer und wenden Sie ihn noch einmal an.

Inkrementelle Implementierung und Validierung

Implementieren Sie das bootconfig-Feature inkrementell, indem Sie dem in diesem Abschnitt beschriebenen Verfahren folgen. Lassen Sie die Kernel-cmdline-Parameter unverändert, während die bootconfig-Parameter hinzugefügt werden.

Dies sind die Schritte für eine inkrementelle Implementierung mit Validierung:

  1. Nehmen Sie den Bootloader vor, erstellen Sie Änderungen und gehen Sie dann so vor:
    1. Verwenden Sie die Variable BOARD_BOOTCONFIG, um einen neuen Bootconfig-Parameter hinzuzufügen.
    2. Behalten Sie die Kernel-cmdline-Parameter bei, damit das Gerät weiterhin korrekt gestartet werden kann. Dies vereinfacht die Fehlerbehebung und Validierung erheblich.
  2. Bestätigen Sie Ihre Arbeit, indem Sie den Inhalt von /proc/bootconfig überprüfen. Prüfen Sie, ob der neu hinzugefügte Parameter nach dem Starten des Geräts angezeigt wird.
  3. Verschieben Sie die androidboot.*-Parameter von der Kernel-cmdline in die Bootconfig-Konfiguration. Verwenden Sie dazu die Variable BOARD_BOOTCONFIG und den Bootloader.
  4. Überprüfe, ob jeder der Parameter in /proc/bootconfig vorhanden ist UND dass er nicht in /proc/cmdline vorhanden ist. Wenn Sie dies überprüfen können, war die Implementierung erfolgreich.

Überlegungen zum Upgrade und Downgrade von OTA

Wenn Sie OTA-Upgrades und -Downgrades zwischen verschiedenen Android-Versionen oder verschiedenen Kernel-Versionen verwalten, sollten Sie besondere Vorsicht walten lassen.

Android 12 ist die erste Version, die bootconfig unterstützt. Bei einem Downgrade auf eine frühere Version müssen anstelle von bootconfig die Kernel-Cmdline-Parameter verwendet werden.

Kernel-Versionen 12 bis 5.4 und höher unterstützen bootconfig. Bei einem Downgrade auf eine frühere Version(einschließlich 11 bis 5.4) müssen Kernel-Cmdline-Parameter verwendet werden.

Bei Upgrades von Android 11 und niedriger auf Android 12 und höher können weiterhin Kernel-cmdline-Parameter verwendet werden. Dasselbe gilt für das Upgrade der Kernel-Versionen.

Fehlerbehebung

Wenn Sie den Schritt verify ausführen und die erwarteten Parameter in /proc/bootconfig nicht sehen, prüfen Sie die Kernel-Logs in logcat. Es ist immer ein Logeintrag für bootconfig vorhanden, wenn der Kernel dies unterstützt.

Beispiel für eine Logausgabe

$ adb logcat | grep bootconfig
02-24 17:00:07.610     0     0 I Load bootconfig: 128 bytes 9 nodes

Wenn ein Fehlerlog zurückgegeben wird, gab es ein Problem beim Laden der Bootkonfiguration. Unter init/main.c finden Sie verschiedene Fehlertypen.