OEMs und SoC-Anbieter, die A/B-Systemaktualisierungen implementieren möchten, müssen sicherstellen, dass ihr Bootloader die boot_control-HAL implementiert und die richtigen Parameter an den Kernel übergibt.
Implementierung der Boot-Steuerung HAL
A/B-fähige Bootloader müssen die boot_control
HAL unter hardware/libhardware/include/hardware/boot_control.h
implementieren. Sie können Implementierungen mit dem Dienstprogramm system/extras/bootctl
und system/extras/tests/bootloader/
testen.
Sie müssen auch den unten gezeigten Zustandsautomaten implementieren:

Einrichten des Kernels
So implementieren Sie A/B-Systemaktualisierungen:
- Wählen Sie die folgende Kernel-Patch-Serie aus (falls erforderlich):
- Wenn Sie ohne Ramdisk booten und „Als Wiederherstellung starten“ verwenden, wählen Sie android-review.googlesource.com/#/c/158491/ aus.
- Um dm-verity ohne Ramdisk einzurichten, wählen Sie android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18 aus.
- Stellen Sie sicher, dass die Kernel-Befehlszeilenargumente die folgenden zusätzlichen Argumente enthalten:
skip_initramfs rootwait ro init=/init root="/dev/dm-0 dm=system none ro,0 1 android-verity <public-key-id> <path-to-system-partition>"
<public-key-id>
die ID des öffentlichen Schlüssels ist, der zur Überprüfung der Verity-Table-Signatur verwendet wird (Einzelheiten finden Sie unter dm-verity ). - Fügen Sie das .X509-Zertifikat mit dem öffentlichen Schlüssel zum Systemschlüsselbund hinzu:
- Kopieren Sie das im
.der
Format formatierte .X509-Zertifikat in das Stammverzeichnis deskernel
. Wenn das .X509-Zertifikat als.pem
Datei formatiert ist, verwenden Sie den folgendenopenssl
Befehl, um vom.pem
in.der
Format zu konvertieren:openssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate>
- Erstellen Sie das
zImage
so, dass es das Zertifikat als Teil des Systemschlüsselbunds enthält. Überprüfen Sie zur Überprüfung denprocfs
Eintrag (erfordert die Aktivierung vonKEYS_CONFIG_DEBUG_PROC_KEYS
):angler:/# cat /proc/keys 1c8a217e I------ 1 perm 1f010000 0 0 asymmetri Android: 7e4333f9bba00adfe0ede979e28ed1920492b40f: X509.RSA 0492b40f [] 2d454e3e I------ 1 perm 1f030000 0 0 keyring .system_keyring: 1/4
Die erfolgreiche Aufnahme des .X509-Zertifikats zeigt das Vorhandensein des öffentlichen Schlüssels im Systemschlüsselbund an (Hervorhebung kennzeichnet die ID des öffentlichen Schlüssels). - Ersetzen Sie das Leerzeichen durch
#
und übergeben Sie es als<public-key-id>
in der Kernel-Befehlszeile. Übergeben Sie beispielsweiseAndroid:#7e4333f9bba00adfe0ede979e28ed1920492b40f
anstelle von<public-key-id>
.
- Kopieren Sie das im
Build-Variablen festlegen
A/B-fähige Bootloader müssen die folgenden Build-Variablenkriterien erfüllen:
Muss für A/B-Ziel definiert werden |
/device/google/marlin/+/android-7.1.0_r1/device-common.mk . Sie können optional den Schritt nach der Installation (jedoch vor dem Neustart) von dex2oat ausführen, der unter „Kompilieren“ beschrieben wird. |
---|---|
Für A/B-Ziele dringend empfohlen |
|
Kann nicht für A/B-Ziel definiert werden |
|
Optional für Debug-Builds | PRODUCT_PACKAGES_DEBUG += update_engine_client |
Partitionen (Slots) festlegen
A/B-Geräte benötigen keine Wiederherstellungspartition oder Cache-Partition, da Android diese Partitionen nicht mehr verwendet. Die Datenpartition wird nun für das heruntergeladene OTA-Paket verwendet und der Wiederherstellungs-Image-Code befindet sich auf der Boot-Partition. Alle Partitionen, die A/B-ed sind, sollten wie folgt benannt werden (Steckplätze werden immer a
, b
usw. genannt): boot_a
, boot_b
, system_a
, system_b
, vendor_a
, vendor_b
.
Zwischenspeicher
Bei Nicht-A/B-Updates wurde die Cache-Partition zum Speichern heruntergeladener OTA-Pakete und zum vorübergehenden Zwischenspeichern von Blöcken während der Aktualisierungsanwendung verwendet. Es gab nie eine gute Möglichkeit, die Cache-Partition zu dimensionieren: Wie groß sie sein musste, hing davon ab, welche Updates Sie anwenden wollten. Im schlimmsten Fall wäre eine Cache-Partition so groß wie das System-Image. Bei A/B-Updates müssen keine Blöcke zwischengespeichert werden (da Sie immer auf eine Partition schreiben, die derzeit nicht verwendet wird), und bei A/B-Streaming müssen Sie nicht das gesamte OTA-Paket herunterladen, bevor Sie es anwenden.
Erholung
Die Wiederherstellungs-RAM-Disk ist jetzt in der Datei boot.img
enthalten. Bei der Wiederherstellung kann der Bootloader die Option skip_initramfs
nicht in die Kernel-Befehlszeile einfügen.
Bei Nicht-A/B-Updates enthält die Wiederherstellungspartition den Code, der zum Anwenden von Updates verwendet wird. A/B-Updates werden von update_engine
angewendet, das im regulär gestarteten Systemabbild ausgeführt wird. Es gibt immer noch einen Wiederherstellungsmodus, der verwendet wird, um das Zurücksetzen der Werksdaten und das Querladen von Aktualisierungspaketen zu implementieren (daher stammt der Name „Wiederherstellung“). Der Code und die Daten für den Wiederherstellungsmodus werden in der regulären Boot-Partition auf einer Ramdisk gespeichert; Um das Systemabbild zu starten, weist der Bootloader den Kernel an, die Ramdisk zu überspringen (andernfalls startet das Gerät im Wiederherstellungsmodus. Der Wiederherstellungsmodus ist klein (und vieles davon befand sich bereits auf der Startpartition), sodass die Startpartition nicht größer wird.
Fstab
Das Argument slotselect
muss für die A/B-Partitionen in der Zeile stehen. Zum Beispiel:
<path-to-block-device>/vendor /vendor ext4 ro wait,verify=<path-to-block-device>/metadata,slotselect
Keine Partition sollte den Namen vendor
tragen. Stattdessen wird die Partition vendor_a
oder vendor_b
ausgewählt und am Mountpunkt /vendor
gemountet.
Kernel-Slot-Argumente
Das aktuelle Slot-Suffix sollte entweder über einen bestimmten Gerätebaumknoten (DT) ( /firmware/android/slot_suffix
) oder über die Kernel-Befehlszeile androidboot.slot_suffix
oder das Bootconfig-Argument übergeben werden.
Standardmäßig flasht Fastboot den aktuellen Steckplatz auf einem A/B-Gerät. Wenn das Update-Paket auch Bilder für den anderen, nicht aktuellen Steckplatz enthält, flasht Fastboot auch diese Bilder. Zu den verfügbaren Optionen gehören:
-
--slot SLOT
. Überschreiben Sie das Standardverhalten und fordern Sie Fastboot auf, den als Argument übergebenen Steckplatz zu flashen. -
--set-active [ SLOT ]
. Stellen Sie den Steckplatz als aktiv ein. Wenn kein optionales Argument angegeben wird, wird der aktuelle Steckplatz als aktiv festgelegt. -
fastboot --help
. Erhalten Sie Details zu Befehlen.
Wenn der Bootloader Fastboot implementiert, sollte er den Befehl set_active <slot>
unterstützen, der den aktuell aktiven Steckplatz auf den angegebenen Steckplatz setzt (dadurch muss auch das Unbootable-Flag für diesen Steckplatz gelöscht und die Anzahl der Wiederholungsversuche auf Standardwerte zurückgesetzt werden). Der Bootloader sollte außerdem die folgenden Variablen unterstützen:
-
has-slot:<partition-base-name-without-suffix>
. Gibt „Ja“ zurück, wenn die angegebene Partition Slots unterstützt, andernfalls „Nein“. -
current-slot
. Gibt das Slot-Suffix zurück, von dem aus als nächstes gebootet wird. -
slot-count
. Gibt eine Ganzzahl zurück, die die Anzahl der verfügbaren Slots darstellt. Derzeit werden zwei Steckplätze unterstützt, daher beträgt dieser Wert2
. -
slot-successful:<slot-suffix>
. Gibt „Ja“ zurück, wenn der angegebene Steckplatz als erfolgreich gebootet markiert wurde, andernfalls „Nein“. -
slot-unbootable:<slot-suffix>
. Gibt „Ja“ zurück, wenn der angegebene Steckplatz als nicht bootfähig markiert ist, andernfalls „Nein“. -
slot-retry-count
. Anzahl der verbleibenden Versuche, den angegebenen Steckplatz zu starten.
Um alle Variablen anzuzeigen, führen Sie fastboot getvar all
aus.
OTA-Pakete generieren
Die OTA-Pakettools befolgen dieselben Befehle wie die Befehle für Nicht-A/B-Geräte. Die Datei target_files.zip
muss durch Definieren der Build-Variablen für das A/B-Ziel generiert werden. Die OTA-Pakettools identifizieren und generieren automatisch Pakete im Format für den A/B-Updater.
Beispiele:
- So generieren Sie einen vollständigen OTA:
./build/make/tools/releasetools/ota_from_target_files \ dist_output/tardis-target_files.zip \ ota_update.zip
- So generieren Sie einen inkrementellen OTA:
./build/make/tools/releasetools/ota_from_target_files \ -i PREVIOUS-tardis-target_files.zip \ dist_output/tardis-target_files.zip \ incremental_ota_update.zip
Partitionen konfigurieren
Die update_engine
kann jedes Paar von A/B-Partitionen aktualisieren, die auf derselben Festplatte definiert sind. Ein Partitionspaar hat ein gemeinsames Präfix (z. B. system
oder boot
) und ein Suffix pro Steckplatz (z. _a
). Die Liste der Partitionen, für die der Nutzlastgenerator eine Aktualisierung definiert, wird durch die Make-Variable AB_OTA_PARTITIONS
konfiguriert.
Wenn beispielsweise ein Partitionspaar bootloader_a
und booloader_b
enthalten ist ( _a
und _b
sind die Steckplatzsuffixe), können Sie diese Partitionen aktualisieren, indem Sie Folgendes in der Produkt- oder Board-Konfiguration angeben:
AB_OTA_PARTITIONS := \ boot \ system \ bootloader
Alle von update_engine
aktualisierten Partitionen dürfen vom Rest des Systems nicht geändert werden. Bei inkrementellen oder Delta- Updates werden die Binärdaten aus dem aktuellen Slot verwendet, um die Daten im neuen Slot zu generieren. Jede Änderung kann dazu führen, dass die Überprüfung der neuen Steckplatzdaten während des Aktualisierungsvorgangs fehlschlägt und daher die Aktualisierung fehlschlägt.
Konfigurieren nach der Installation
Sie können den Schritt nach der Installation für jede aktualisierte Partition mithilfe einer Reihe von Schlüssel-Wert-Paaren unterschiedlich konfigurieren. Um ein Programm unter /system/usr/bin/postinst
in einem neuen Image auszuführen, geben Sie den Pfad relativ zum Stammverzeichnis des Dateisystems in der Systempartition an.
Beispielsweise ist usr/bin/postinst
system/usr/bin/postinst
(wenn keine RAM-Disk verwendet wird). Geben Sie außerdem den Dateisystemtyp an, der an den Systemaufruf mount(2)
übergeben werden soll. Fügen Sie Folgendes zu den .mk
Dateien des Produkts oder Geräts hinzu (falls zutreffend):
AB_OTA_POSTINSTALL_CONFIG += \ RUN_POSTINSTALL_system=true \ POSTINSTALL_PATH_system=usr/bin/postinst \ FILESYSTEM_TYPE_system=ext4
Kompilieren
Anwendungen können im Hintergrund vor dem Neustart mit dem neuen Systemabbild kompiliert werden. Um Apps im Hintergrund zu kompilieren, fügen Sie Folgendes zur Gerätekonfiguration des Produkts hinzu (in der Datei „device.mk“ des Produkts):
- Beziehen Sie die nativen Komponenten in den Build ein, um sicherzustellen, dass Kompilierungsskripte und Binärdateien kompiliert und in das Systemabbild aufgenommen werden.
# A/B OTA dexopt package PRODUCT_PACKAGES += otapreopt_script
- Verbinden Sie das Kompilierungsskript mit
update_engine
, sodass es als Schritt nach der Installation ausgeführt wird.# A/B OTA dexopt update_engine hookup AB_OTA_POSTINSTALL_CONFIG += \ RUN_POSTINSTALL_system=true \ POSTINSTALL_PATH_system=system/bin/otapreopt_script \ FILESYSTEM_TYPE_system=ext4 \ POSTINSTALL_OPTIONAL_system=true
Hilfe bei der Installation der vorab ausgewählten Dateien in der nicht verwendeten zweiten Systempartition finden Sie unter Erststartinstallation von DEX_PREOPT-Dateien .