bootconfig in Android 12 implementieren

In Android 12 ersetzt die Boot-Config-Funktion die androidboot.*-Kernel-cmdline-Optionen, die unter Android 11 und niedriger verwendet werden. Die Bootconfig-Funktion ist ein Mechanismus zum Übergeben von Konfigurationsdetails vom Build und Bootloader an Android 12.

Mit dieser Funktion können die Konfigurationsparameter für den Android-Userspace von denen für den Kernel getrennt werden. Wenn Sie die langen androidboot.*-Kernelparameter in die Boot-Konfigurationsdatei verschieben, schaffen Sie Platz auf der Kernel-Befehlszeile und machen sie für zukünftige Erweiterungen verfügbar.

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

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

Implementieren Sie die Bootconfig-Funktion für neue Geräte, die mit der Kernelversion 12-5.10.xx gestartet werden. Sie müssen sie nicht implementieren, wenn Sie Geräte aktualisieren.

Beispiele und Quelle

Beachten Sie bei den Beispielen und dem Quellcode in diesem Abschnitt, dass sich das Format des bootconfig-Codes nur geringfügig vom Format der Kernel-Befehlszeile unterscheidet, die in Android 11 und niedriger verwendet wird. Der folgende Unterschied ist jedoch wichtig für Ihre Verwendung:

  • Parameter müssen durch den Escape-Zeichen-Zeilenumbruch \n und nicht durch Leerzeichen getrennt werden.

Beispiel für einen Bootloader

Ein Beispiel für einen Bootloader finden Sie in der Cuttlefish-U-Boot-Referenz-Bootloader-Implementierung. Unten sind zwei Commits in der Referenz 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. Der zweite Code führt zwei Dinge aus: Er fügt die Boot-Konfigurationsverwaltung hinzu und zeigt, wie Parameter zur Laufzeit hinzugefügt werden:

Beispiel erstellen

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. Mit den Cuttlefish-Änderungen können Sie Folgendes tun:

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. Weitere Informationen zu einem inkrementellen Prozess finden Sie im Abschnitt Inkrementelle Implementierung und Validierung.

Wenn Sie Änderungen vorgenommen haben, bei denen in der Datei „/proc/cmdline“ nach androidboot.*-Parametern gesucht wird, verweisen Sie stattdessen auf die Datei /proc/bootconfig. Die ro.boot.*-Properties werden mit den neuen bootconfig-Werten festgelegt. Sie müssen also keine Änderungen am Code vornehmen, der diese Properties verwendet.

Änderungen am Build

Aktualisieren Sie zuerst die Boot-Header-Version auf Version 4:

- BOARD_BOOT_HEADER_VERSION := 3

+ BOARD_BOOT_HEADER_VERSION := 4

Fügen Sie den bootconfig-Kernel-Befehlszeilenparameter 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-Befehlszeile aus BOARD\_KERNEL\_CMDLINE.

Alle androidboot.*-Parameter können unverändert verschoben werden, z. B. so:

- BOARD_KERNEL_CMDLINE += androidboot..selinux=enforcing

+ BOARD_BOOTCONFIG += androidboot..selinux=enforcing

Änderungen am Bootloader

Der Bootloader richtet die initramfs ein, bevor er zum Kernel springt. In der Kernel-Bootkonfiguration wird nach dem Abschnitt „bootconfig“ gesucht, der sich am Ende von initramfs, mit dem erwarteten Trailer befinden muss.

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

Diagramm des Speicherzuweisungslayouts der Boot-Konfiguration

Abbildung 1: Arbeitsspeicherzuweisung für Boot-Config-Datei in Android 12

Der Bootloader erstellt den Bootconfig-Bereich 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 Erstellung bekannt sind, und Parameter, die zum Zeitpunkt der Erstellung nicht bekannt sind. Unbekannte Parameter müssen hinzugefügt werden.

Parameter, die zum Zeitpunkt des Builds bekannt sind, werden am Ende des vendor_boot-Images im Abschnitt „bootconfig“ verpackt. 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 zur Laufzeit im Bootloader bekannt. Sie 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 die Bootconfig-Funktion nach und nach. Folgen Sie dazu der Anleitung in diesem Abschnitt. Lassen Sie die Kernel-Cmdline-Parameter unverändert, während die bootconfig-Parameter hinzugefügt werden.

So führen Sie eine inkrementelle Implementierung mit Validierung durch:

  1. Nehmen Sie die Änderungen am Bootloader und am Build vor und führen Sie dann die folgenden Schritte aus:
    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 sehr.
  2. Prüfen Sie Ihre Arbeit anhand des Inhalts von /proc/bootconfig. Prüfen Sie, ob der neu hinzugefügte Parameter nach dem Starten des Geräts angezeigt wird.
  3. Verschieben Sie die androidboot.*-Parameter mithilfe der Variablen BOARD_BOOTCONFIG und des Bootloaders aus der Kernel-Befehlszeile in die Bootkonfiguration.
  4. Prüfen Sie, ob alle Parameter in /proc/bootconfig vorhanden und nicht in /proc/cmdline enthalten sind. Wenn das der Fall ist, war die Implementierung erfolgreich.

OTA-Upgrades und -Downgrades

Bei der Verwaltung von OTA-Upgrades und -Downgrades zwischen verschiedenen Android-Versionen oder verschiedenen Kernelversionen ist besondere Vorsicht geboten.

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.

Die Kernelversionen 12–5.4 und höher unterstützen bootconfig. Wenn Sie auf eine frühere Version downgraden(einschließlich 11-5.4), müssen Kernel-Befehlszeilenparameter 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 beim Schritt verify (Prüfen) die erwarteten Parameter in /proc/bootconfig nicht sehen, prüfen Sie die Kernel-Protokolle in logcat. Wenn der Kernel dies unterstützt, ist immer ein Protokolleintrag für „bootconfig“ vorhanden.

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 Fehlerprotokoll zurückgegeben wird, ist beim Laden der Boot-Konfiguration ein Problem aufgetreten. Informationen zu verschiedenen Fehlertypen finden Sie unter init/main.c.