Nehmen Sie an unserer Usability-Umfrage teil , um diese Website zu verbessern.
Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

Implementieren von A / B-Updates

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.

Implementieren der Bootsteuerung HAL

A / B-fähige Bootloader müssen die boot_control HAL unter hardware/libhardware/include/hardware/boot_control.h . Sie können Implementierungen mit dem Dienstprogramm system/extras/tests/bootloader/ system/extras/bootctl und system/extras/tests/bootloader/ system/extras/bootctl system/extras/tests/bootloader/ system/extras/bootctl .

Sie müssen auch die unten gezeigte Zustandsmaschine implementieren:

Abbildung 1. Bootloader-Statusmaschine

Einrichten des Kernels

So implementieren Sie A / B-Systemaktualisierungen:

  1. Wählen Sie die folgende Kernel-Patch-Serie aus (falls erforderlich):
  2. 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>"
    ... wobei der Wert <public-key-id> die ID des öffentlichen Schlüssels ist, mit dem die Signatur der Veritätstabelle überprüft wird (Einzelheiten siehe dm-verity ).
  3. Fügen Sie dem Systemschlüsselring das .X509-Zertifikat mit dem öffentlichen Schlüssel hinzu:
    1. Kopieren Sie das im .der Format formatierte .X509-Zertifikat in das Stammverzeichnis des kernel Verzeichnisses. Wenn das .X509 Zertifikat als formatiert ist .pem - Datei, verwenden Sie den folgenden openssl Befehl umwandeln .pem zu .der Format:
      openssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate>
    2. Erstellen Sie das zImage , um das Zertifikat als Teil des Systemschlüsselrings aufzunehmen. Überprüfen Sie zur Überprüfung den Eintrag procfs (erfordert die KEYS_CONFIG_DEBUG_PROC_KEYS von KEYS_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üsselring an (Markierung kennzeichnet die ID des öffentlichen Schlüssels).
    3. Ersetzen Sie das Leerzeichen durch # und übergeben Sie es in der Kernel-Befehlszeile als <public-key-id> . Android:#7e4333f9bba00adfe0ede979e28ed1920492b40f Sie beispielsweise Android:#7e4333f9bba00adfe0ede979e28ed1920492b40f anstelle von <public-key-id> .

Build-Variablen festlegen

A / B-fähige Bootloader müssen die folgenden Kriterien für Buildvariablen erfüllen:

Muss für A / B-Ziel definiert werden
  • AB_OTA_UPDATER := true
  • AB_OTA_PARTITIONS := \
    boot \
    system \
    vendor
    und andere Partitionen, die über update_engine aktualisiert update_engine (Radio, Bootloader usw.)
  • PRODUCT_PACKAGES += \
    update_engine \
    update_verifier
Ein Beispiel finden Sie unter /device/google/marlin/+/android-7.1.0_r1/device-common.mk . Sie können optional den unter Kompilieren beschriebenen Schritt dex2oat nach der Installation (aber vor dem Neustart) ausführen.
Sehr empfehlenswert für A / B-Ziele
  • Definieren Sie TARGET_NO_RECOVERY := true
  • Definieren Sie BOARD_USES_RECOVERY_AS_BOOT := true
  • Definieren Sie nicht BOARD_RECOVERYIMAGE_PARTITION_SIZE
Kann nicht für A / B-Ziel definieren
  • BOARD_CACHEIMAGE_PARTITION_SIZE
  • BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE
Optional für Debugbuilds PRODUCT_PACKAGES_DEBUG += update_engine_client

Festlegen von Partitionen (Slots)

A / B-Geräte benötigen keine Wiederherstellungspartition oder Cache-Partition, da Android diese Partitionen nicht mehr verwendet. Die Datenpartition wird jetzt für das heruntergeladene OTA-Paket verwendet, und der Wiederherstellungsimagecode befindet sich auf der Startpartition. Alle Partitionen, die A / B-ed sind, sollten wie folgt benannt werden (Slots heißen immer a , b usw.): boot_a , boot_b , system_a , system_b , vendor_a , vendor_b .

Zwischenspeicher

Bei Nicht-A / B-Updates wurde die Cache-Partition verwendet, um heruntergeladene OTA-Pakete zu speichern und Blöcke vorübergehend zu speichern, während Updates angewendet wurden. Es gab nie eine gute Möglichkeit, die Größe der Cache-Partition zu bestimmen: Wie groß sie sein musste, hing davon ab, welche Updates Sie anwenden wollten. Der schlimmste Fall wäre eine Cache-Partition, die so groß ist wie das System-Image. Bei A / B-Updates müssen keine Blöcke gespeichert werden (da Sie immer auf eine Partition schreiben, die derzeit nicht verwendet wird). Beim Streaming von A / B müssen Sie nicht das gesamte OTA-Paket herunterladen, bevor Sie es anwenden.

Wiederherstellung

Die Wiederherstellungs-RAM-Disk ist jetzt in der Datei boot.img enthalten. skip_initramfs Wiederherstellung kann der Bootloader die Option skip_initramfs nicht in die Kernel-Befehlszeile skip_initramfs .

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ären Systemabbild ausgeführt wird. Es gibt immer noch einen Wiederherstellungsmodus, der zum Zurücksetzen der Werksdaten und zum Seitenladen von Aktualisierungspaketen verwendet wird (daher stammt der Name "Wiederherstellung"). Der Code und die Daten für den Wiederherstellungsmodus werden in der regulären Startpartition auf einer Ramdisk gespeichert. Um das System-Image zu starten, weist der Bootloader den Kernel an, die Ramdisk zu überspringen (andernfalls startet das Gerät im Wiederherstellungsmodus. Der Wiederherstellungsmodus ist klein (und ein Großteil davon befand sich bereits auf der Startpartition), sodass die Startpartition nicht erhöht wird in Größe.

Fstab

Das slotselect Argument muss in der Zeile für die A / B-ed-Partitionen stehen. Beispielsweise:

<path-to-block-device>/vendor  /vendor  ext4  ro
wait,verify=<path-to-block-device>/metadata,slotselect

Keine Partition sollte als vendor . Stattdessen wird die Partition vendor_a oder vendor_b ausgewählt und auf dem /vendor Einhängepunkt vendor_b .

Kernel-Slot-Argumente

Das aktuelle Slot-Suffix sollte entweder über einen bestimmten DT-Knoten (Device Tree) ( /firmware/android/slot_suffix ) oder über das androidboot.slot_suffix werden.

Standardmäßig blinkt 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, werden diese Bilder auch von fastboot geflasht. 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 ist, wird der aktuelle Steckplatz als aktiv festgelegt.
  • fastboot --help . Details zu Befehlen abrufen.

Wenn der Bootloader Fastboot implementiert, sollte er den Befehl set_active <slot> , der den aktuell aktiven Slot auf den angegebenen Slot setzt (dies muss auch das nicht bootfähige Flag für diesen Slot löschen und die Anzahl der Wiederholungsversuche auf die Standardwerte zurücksetzen). Der Bootloader sollte auch 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, das vom nächsten gestartet wird.
  • slot-count . Gibt eine Ganzzahl zurück, die die Anzahl der verfügbaren Slots darstellt. Derzeit werden zwei Steckplätze unterstützt, sodass dieser Wert 2 beträgt.
  • slot-successful:<slot-suffix> . Gibt "Ja" zurück, wenn der angegebene Steckplatz als erfolgreich gestartet 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 Wiederholungsversuche, um zu versuchen, den angegebenen Steckplatz zu starten.

Führen Sie fastboot getvar all , um alle Variablen fastboot getvar all .

OTA-Pakete generieren

Die OTA-Pakettools folgen denselben Befehlen wie die Befehle für Nicht-A / B-Geräte. Die Datei target_files.zip muss generiert werden, indem die target_files.zip für das A / B-Ziel definiert werden. Die OTA-Pakettools identifizieren und generieren Pakete automatisch im Format für den A / B-Updater.

Beispiele:

  • So generieren Sie eine vollständige 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. B. _a ). Die Liste der Partitionen, für die der Nutzlastgenerator ein Update definiert, wird von der Variablen AB_OTA_PARTITIONS make konfiguriert.

Zum Beispiel, wenn ein Paar von Trennwänden bootloader_a und booloader_b enthalten sind ( _a und _b sind die Slot - Suffixe), können Sie diese Partitionen aktualisieren , indem Sie die folgenden auf dem Produkt oder Board - Konfiguration festgelegt wird :

AB_OTA_PARTITIONS := \
  boot \
  system \
  bootloader

Alle von update_engine aktualisierten update_engine dürfen vom Rest des Systems nicht geändert werden. Während inkrementeller oder Delta- Aktualisierungen werden die Binärdaten aus dem aktuellen Steckplatz verwendet, um die Daten im neuen Steckplatz zu generieren. Jede Änderung kann dazu führen, dass die neuen Steckplatzdaten während des Aktualisierungsvorgangs nicht überprüft werden und daher die Aktualisierung fehlschlägt.

Nachinstallation konfigurieren

Sie können den Schritt nach der Installation für jede aktualisierte Partition mithilfe eines Satzes von Schlüssel-Wert-Paaren unterschiedlich konfigurieren. /system/usr/bin/postinst den Pfad relativ zum Stammverzeichnis des Dateisystems in der Systempartition an, um ein Programm in einem neuen Image unter /system/usr/bin/postinst auszuführen.

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) werden soll. Fügen Sie den .mk Dateien des Produkts oder Geräts (falls zutreffend) Folgendes hinzu:

AB_OTA_POSTINSTALL_CONFIG += \
  RUN_POSTINSTALL_system=true \
  POSTINSTALL_PATH_system=usr/bin/postinst \
  FILESYSTEM_TYPE_system=ext4

Kompilieren

Aus Sicherheitsgründen kann system_server keine Just-in-Time- Kompilierung (JIT) verwenden . Dies bedeutet, dass Sie Odex-Dateien für system_server und seine Abhängigkeiten mindestens im system_server kompilieren müssen. alles andere ist optional.

Um Apps im Hintergrund zu kompilieren, müssen Sie der Gerätekonfiguration des Produkts (in device.mk des Produkts) Folgendes hinzufügen:

  1. Fügen Sie die nativen Komponenten in den Build ein, um sicherzustellen, dass Kompilierungsskript und Binärdateien kompiliert und in das Systemabbild aufgenommen werden.
      # A/B OTA dexopt package
      PRODUCT_PACKAGES += otapreopt_script
    
  2. 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 zum Installieren der voroptimierten Dateien in der nicht verwendeten zweiten Systempartition finden Sie unter Erste Startinstallation von DEX_PREOPT-Dateien .