bootconfig in Android 12 implementieren

In Android 12 ersetzt die Boot-Konfiguration 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. Für Ihre Nutzung ist jedoch der folgende Unterschied wichtig:

  • Parameter müssen durch den Escape-Zeichenfolge für Zeilenumbrüche \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. Die erste Uprev unterstützt die Boot-Header-Version bis zur neuesten Version. 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 Beispiel für die Erstellung von mkbootimg-Änderungen zum Erstellen von vendor_boot.img mit dem Anbieter-Boot-Header v4 finden Sie unter mkbootimg changes for bootconfig. Mit den Cuttlefish-Änderungen können Sie Folgendes tun:

Implementierung

Partner müssen ihren Bootloadern Unterstützung hinzufügen und ihre androidboot.*-Buildzeitparameter aus der Kernel-Befehlszeile in die Boot-Konfigurationsdatei 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-cmdline-Parameter 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-Abschnitt im Arbeitsspeicher. Der Abschnitt „bootconfig“ enthält Speicherzuweisungen für Folgendes:

  • Parameter
  • 4 B parameters size
  • 4 B parameters checksum
  • 12 B-Boot-Config-Magischer-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 (in Byte) im Feld „Vendor Boot Header“ vendor_bootconfig_size 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-Befehlszeilenparameter 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 gehen Sie dann so vor:
    1. Verwenden Sie die Variable BOARD_BOOTCONFIG, um einen neuen bootconfig-Parameter hinzuzufügen.
    2. Lassen Sie die Kernel-cmdline-Parameter unverändert, damit das Gerät weiterhin ordnungsgemäß starten kann. Das erleichtert die Fehlerbehebung und Validierung erheblich.
  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.

Überlegungen zum Over-the-air-Upgrade und -Downgrade

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 mit Bootconfig-Unterstützung. Wenn Sie auf eine frühere Version downgraden, müssen anstelle von „bootconfig“ Kernel-Befehlszeilenparameter 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 die Kernel-Befehlszeilenparameter weiter verwendet werden. Dasselbe gilt für das Upgraden von Kernelversionen.

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.