OTA-Aktualisierung für A/B-Geräte ohne dynamische Partitionen

Android 10 unterstützt dynamische Partitionen, ein Partitionierungssystem für den Nutzerbereich, mit dem Partitionen während OTA-Updates (Over-the-Air) erstellt, in der Größe angepasst und gelöscht werden können.

Auf dieser Seite wird beschrieben, wie OTA-Clients dynamische Partitionen während eines Updates für A/B-Geräte anpassen, die ohne Unterstützung für dynamische Partitionen auf den Markt gekommen sind, und wie OTA-Clients auf Android 10 aktualisiert werden.

Hintergrund

Bei der Aktualisierung eines A/B-Geräts zur Unterstützung dynamischer Partitionen bleibt die GUID-Partitionstabelle (GPT) auf dem Gerät erhalten. Es gibt also keine super-Partition auf dem Gerät. Metadaten werden unter system_a und system_b gespeichert. Dies kann jedoch durch Ändern von BOARD_SUPER_PARTITION_METADATA_DEVICE angepasst werden.

Jedes blockorientierte Gerät hat zwei Metadaten-Slots. In jedem Blockgerät wird nur ein Metadaten-Slot verwendet. Beispiel: Metadaten 0 unter system_a und Metadaten 1 unter system_b entsprechen Partitionen in den Slots A bzw. B. Zur Laufzeit spielt es keine Rolle, welcher Slot aktualisiert wird.

Auf dieser Seite werden die Metadaten-Slots als „Metadata S“ (Quelle) und „Metadata T“ (Ziel) bezeichnet. Entsprechend werden Partitionen als system_s, vendor_t usw. bezeichnet.

Weitere Informationen zu Build-Systemkonfigurationen finden Sie unter Geräte aktualisieren.

Weitere Informationen dazu, wie Partitionen zu Updategruppen gehören, finden Sie unter Änderungen an der Boardkonfiguration für neue Geräte.

Beispiel für Metadaten auf einem Gerät:

  • Physisches Blockgerät system_a
    • Metadaten 0
      • Gruppe foo_a
        • Logische (dynamische) Partition system_a
        • Logische (dynamische) Partition product_services_a
        • Andere Partitionen, die von Foo aktualisiert wurden
      • Gruppe bar_a
        • Logische (dynamische) Partition vendor_a
        • Logische (dynamische) Partition product_a
        • Andere von Bar aktualisierte Partitionen
    • Metadaten 1 (nicht verwendet)
  • Physisches Blockgerät system_b
    • Metadaten 0 (nicht verwendet)
    • Metadaten 1
      • Gruppe „foo_b“
        • Logische (dynamische) Partition system_b
        • Logische (dynamische) Partition product_services_b
        • Andere Partitionen, die von Foo aktualisiert wurden
      • Gruppe „bar_b“
        • Logische (dynamische) Partition vendor_b
        • Logische (dynamische) Partition product_b
        • Andere von Bar aktualisierte Partitionen

Mit dem lpdump-Tool unter system/extras/partition_tools können Sie die Metadaten auf Ihrem Gerät sichern. Beispiel:

lpdump --slot 0 /dev/block/by-name/system_a
lpdump --slot 1 /dev/block/by-name/system_b

Update nachrüsten

Auf Geräten mit Android 9 und niedriger unterstützt der OTA-Client auf dem Gerät die Zuordnung dynamischer Partitionen vor dem Update nicht. Es wird ein zusätzlicher Satz von Patches erstellt, damit die Zuordnung direkt auf die vorhandenen physischen Partitionen angewendet werden kann.

Der OTA-Generator erstellt die endgültige super.img-Datei, die den Inhalt aller dynamischen Partitionen enthält, und teilt das Image dann in mehrere Images auf, die den Größen der physischen Blockgeräte entsprechen, die dem System, dem Anbieter usw. zugeordnet sind. Diese Bilder haben die Namen super_system.img, super_vendor.img usw. Der OTA-Client wendet diese Images auf die physischen Partitionen an und nicht auf die logischen (dynamischen) Partitionen.

Da der OTA-Client nicht weiß, wie dynamische Partitionen zugeordnet werden, werden alle Schritte nach der Installation für diese Partitionen automatisch deaktiviert, wenn das Updatepaket generiert wird. Weitere Informationen finden Sie unter Konfiguration nach der Installation.

Der Aktualisierungsvorgang ist derselbe wie bei Android 9.

Vor dem Update:

ro.boot.dynamic_partitions=
ro.boot.dynamic_partitions_retrofit=

Nach dem Update:

ro.boot.dynamic_partitions=true
ro.boot.dynamic_partitions_retrofit=true

Künftige Updates nach der Nachrüstung

Nach dem Retrofit-Update wird der OTA-Client aktualisiert, damit er mit dynamischen Partitionen funktioniert. Die Bereiche für Quellpartitionen erstrecken sich nie über physische Zielpartitionen hinweg.

Aktualisierung mit einem regulären Aktualisierungspaket

  1. Partitionsmetadaten für super initialisieren:
    1. Erstellen Sie neue Metadaten M aus Metadaten S (Quellmetadaten). Wenn beispielsweise in den Metadaten S [system_s, vendor_s, product_s] als Blockgeräte verwendet werden, dann werden in den neuen Metadaten M [system_t, vendor_t, product_t] als Blockgeräte verwendet. Alle Gruppen und Partitionen werden in M verworfen.
    2. Fügen Sie Zielgruppen und Partitionen gemäß dem Feld dynamic_partition_metadata im Update-Manifest hinzu. Die Größe der einzelnen Partitionen finden Sie unter new_partition_info.
    3. Schreibe M in Metadaten T.
    4. Die hinzugefügten Partitionen im Gerätezurordner als beschreibbar zuordnen.
  2. Wenden Sie das Update auf die Blockgeräte an.
    1. Ordnen Sie die Quellpartitionen bei Bedarf dem Device Mapper als schreibgeschützt zu. Dies ist für das Sideloading erforderlich, da die Quellpartitionen vor dem Update nicht zugeordnet werden.
    2. Wendet ein vollständiges oder Delta-Update auf alle Blockgeräte im Ziel-Slot an.
    3. Hängen Sie die Partitionen ein, um das Post-Install-Skript auszuführen, und hängen Sie sie dann wieder aus.
  3. Zielpartitionen aufheben

Aktualisierungsvorgang mit einem Retrofit-Aktualisierungspaket

Wenn das Retrofit-Updatepaket auf einem Gerät angewendet wird, auf dem dynamische Partitionen bereits aktiviert sind, wendet der OTA-Client die geteilte super.img-Datei direkt auf Blockgeräte an. Der Aktualisierungsvorgang ähnelt einem Retrofit-Update. Weitere Informationen finden Sie unter Aktualisierung nachträglich einfügen.

Nehmen wir beispielsweise Folgendes an:

  • Slot A ist der aktive Slot.
  • system_a enthält die aktiven Metadaten in Slot 0.
  • system_a, vendor_a und product_a werden als Blockgeräte verwendet.

Wenn der OTA-Client ein Retrofit-Updatepaket empfängt, wendet er super_system.img auf dem physischen system_b, super_vendor.img auf dem physischen vendor_b und super_product.img auf dem physischen product_b an. Das physische Blockgerät system_b enthält die richtigen Metadaten, um die logischen system_b, vendor_b und product_b beim Booten zuzuordnen.

Updatepakete generieren

Inkrementelles OTA

Beim Generieren inkrementeller OTAs für Nachrüstgeräte hängen die Updates davon ab, ob im Basis-Build PRODUCT_USE_DYNAMIC_PARTITIONS und PRODUCT_RETROFIT_DYNAMIC_PARTITIONS definiert sind.

  • Wenn im Basis-Build die Variablen nicht definiert sind, handelt es sich um ein Update, das nachträglich hinzugefügt wird. Das Updatepaket enthält die geteilte Datei super.img und deaktiviert den Schritt nach der Installation.
  • Wenn im Basis-Build die Variablen definiert sind, entspricht dies einem typischen Update mit dynamischen Partitionen. Das Update-Paket enthält die Images für logische (dynamische) Partitionen. Der Schritt nach der Installation kann aktiviert werden.

Vollständiges OTA

Für Nachrüstgeräte werden zwei vollständige OTA-Pakete generiert.

  • $(PRODUCT)-ota-retrofit-$(TAG).zip enthält immer den Split super.img und deaktiviert den Schritt nach der Installation für die Aktualisierung.
    • Sie wird mit einem zusätzlichen Argument --retrofit_dynamic_partitions für das Skript ota_from_target_files generiert.
    • Sie kann auf alle Builds angewendet werden.
  • $(PRODUCT)-ota-$(TAG).zip enthält logische Bilder für zukünftige Updates.
    • Wenden Sie dies nur auf Builds an, bei denen dynamische Partitionen aktiviert sind. Weitere Informationen zur Durchsetzung finden Sie unten.

Nicht nachrüstbares Update für alte Builds ablehnen

Wenden Sie das reguläre vollständige OTA-Paket nur auf Builds an, für die dynamische Partitionen aktiviert sind. Wenn der OTA-Server falsch konfiguriert ist und diese Pakete auf Geräten mit Android 9 oder niedriger bereitstellt, können die Geräte nicht mehr gestartet werden. Der OTA-Client unter Android 9 und niedriger kann nicht zwischen einem Retrofit-OTA-Paket und einem regulären vollständigen OTA-Paket unterscheiden. Daher lehnt der Client das vollständige Paket nicht ab.

Damit das Gerät das vollständige OTA-Paket nicht akzeptiert, können Sie einen Schritt nach der Installation einfordern, um die vorhandene Gerätekonfiguration zu prüfen. Beispiel:

device/device_name/dynamic_partitions/check_dynamic_partitions

#!/system/bin/sh
DP_PROPERTY_NAME="ro.boot.dynamic_partitions"
DP_RETROFIT_PROPERTY_NAME="ro.boot.dynamic_partitions_retrofit"

DP_PROPERTY=$(getprop ${DP_PROPERTY_NAME})
DP_RETROFIT_PROPERTY=$(getprop ${DP_RETROFIT_PROPERTY_NAME})

if [ "${DP_PROPERTY}" != "true" ] || [ "${DP_RETROFIT_PROPERTY}" != "true" ] ; then
    echo "Error: applied non-retrofit update on build without dynamic" \
         "partitions."
    echo "${DP_PROPERTY_NAME}=${DP_PROPERTY}"
    echo "${DP_RETROFIT_PROPERTY_NAME}=${DP_RETROFIT_PROPERTY}"
    exit 1
fi

device/device_name/dynamic_partitions/Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= check_dynamic_partitions
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_SRC_FILES := check_dynamic_partitions
LOCAL_PRODUCT_MODULE := true
include $(BUILD_PREBUILT)

device/device_name/device.mk

PRODUCT_PACKAGES += check_dynamic_partitions

# OPTIONAL=false so that the error in check_dynamic_partitions will be
# propagated to OTA client.
AB_OTA_POSTINSTALL_CONFIG += \
    RUN_POSTINSTALL_product=true \
    POSTINSTALL_PATH_product=bin/check_dynamic_partitions \
    FILESYSTEM_TYPE_product=ext4 \
    POSTINSTALL_OPTIONAL_product=false \

Wenn das reguläre OTA-Paket auf einem Gerät ohne aktivierte dynamische Partitionen angewendet wird, wird check_dynamic_partitions als Schritt nach der Installation ausgeführt und das Update wird abgelehnt.