dynamisches Systemupdate

Mit Dynamic System Updates (DSU) können Sie ein Android-Systemimage erstellen, das Nutzer aus dem Internet herunterladen und testen können, ohne das aktuelle Systemimage zu beschädigen. In diesem Dokument wird beschrieben, wie Sie DSU unterstützen.

Kernelanforderungen

Informationen zu den Kernelanforderungen finden Sie unter Dynamische Partitionen implementieren.

Außerdem verwendet DSU das Kernel-Feature „device-mapper-verity“ (dm-verity), um das Android-Systemimage zu überprüfen. Sie müssen daher die folgenden Kernelkonfigurationen aktivieren:

  • CONFIG_DM_VERITY=y
  • CONFIG_DM_VERITY_FEC=y

Anforderungen an Partitionen

Ab Android 11 muss für die /data-Partition das Dateisystem F2FS oder ext4 verwendet werden. F2FS bietet eine bessere Leistung und wird empfohlen, der Unterschied sollte jedoch unbedeutend sein.

Hier einige Beispiele für die Dauer eines dynamischen Systemupdates auf einem Pixel-Gerät:

  • Mit F2FS:
    • 109 Sekunden, 8 GB Nutzerdaten, 867 MB System, Dateisystemtyp: F2FS, Verschlüsselung: aes-256-xts:aes-256-cts
    • 104 Sekunden, 8 GB Nutzerdaten, 867 MB System, Dateisystemtyp: F2FS, Verschlüsselung: ice
  • Mit ext4:
    • 135 Sekunden, 8 GB Nutzerdaten, 867 MB System, Dateisystemtyp: ext4, Verschlüsselung: aes-256-xts:aes-256-cts

Wenn der Vorgang auf Ihrer Plattform viel länger dauert, prüfen Sie, ob das Mount-Flag ein Flag enthält, das „sync“-Schreibvorgänge auslöst. Alternativ können Sie explizit ein „async“-Flag angeben, um eine bessere Leistung zu erzielen.

Die metadata-Partition (mindestens 16 MB) ist erforderlich, um Daten zu den installierten Images zu speichern. Sie muss während des Mounts in der ersten Phase bereitgestellt werden.

Für die userdata-Partition muss das Dateisystem F2FS oder ext4 verwendet werden. Wenn Sie F2FS verwenden, müssen Sie alle F2FS-bezogenen Patches einbeziehen, die im gemeinsamen Android-Kernelverfügbar sind.

DSU wurde mit Kernel/Common 4.9 entwickelt und getestet. Für diese Funktion wird Kernel 4.9 oder höher empfohlen.

Verhalten der HAL des Anbieters

Weaver HAL

Die Weaver HAL bietet eine feste Anzahl von Slots zum Speichern von Nutzersicherheitsschlüsseln. DSU benötigt zwei zusätzliche Schlüssel-Slots. Wenn ein OEM eine Weaver HAL hat, muss sie genügend Slots für ein generisches Systemimage (GSI) und ein Host-Image haben.

Gatekeeper HAL

Die Gatekeeper HAL muss große USER_ID Werte unterstützen, da die GSI die UIDs um +1000000 an die HAL weiterleitet.

Boot überprüfen

Wenn Sie das Booten von GSI-Images für Entwickler im LOCKED-Status unterstützen möchten, ohne den verifizierten Bootmodus zu deaktivieren, müssen Sie GSI-Schlüssel für Entwickler einbeziehen. Fügen Sie dazu die folgende Zeile in die Datei device/<device_name>/device.mk ein:

$(call inherit-product, $(SRC_TARGET_DIR)/product/developer_gsi_keys.mk)

Rollback-Schutz

Bei Verwendung von DSU muss das heruntergeladene Android-Systemimage neuer sein als das aktuelle Systemimage auf dem Gerät. Dazu werden die Sicherheitspatch-Levels in der Android Verified Boot (AVB) AVB-Property-Beschreibung beider Systemimages verglichen: Prop: com.android.build.system.security_patch -> '2019-04-05'.

Bei Geräten, die AVB nicht verwenden, müssen Sie den Sicherheitspatch-Level des aktuellen Systemimages mit dem Bootloader in die Kernel-Befehlszeile oder -Bootkonfiguration einfügen: androidboot.system.security_patch=2019-04-05.

Hardwareanforderungen

Wenn Sie eine DSU-Instanz starten, werden zwei temporäre Dateien zugewiesen:

  • Eine logische Partition zum Speichern von GSI.img (1–1,5 GB)
  • Eine leere /data-Partition mit 8 GB als Sandbox für die Ausführung der GSI

Wir empfehlen, vor dem Starten einer DSU-Instanz mindestens 10 GB freien Speicherplatz zu reservieren. DSU unterstützt auch die Zuweisung von einer SD-Karte. Wenn eine SD-Karte vorhanden ist, hat sie die höchste Priorität für die Zuweisung. Die SD-Kartenunterstützung ist für Geräte mit geringerer Leistung, die möglicherweise nicht genügend internen Speicher haben, von entscheidender Bedeutung. Wenn eine SD-Karte vorhanden ist, muss sie nicht übernommen werden. DSU unterstützt keine übernommenen SD-Karten.

Verfügbare Frontends

Sie können DSU mit adb, einer OEM-App oder dem DSU-Loader mit einem Klick (in Android 11 oder höher) starten.

DSU mit adb starten

Geben Sie die folgenden Befehle ein, um DSU mit adb zu starten:

$ simg2img out/target/product/.../system.img system.raw
$ gzip -c system.raw > system.raw.gz
$ adb push system.raw.gz /storage/emulated/0/Download
$ adb shell am start-activity \
-n com.android.dynsystem/com.android.dynsystem.VerificationActivity  \
-a android.os.image.action.START_INSTALL    \
-d file:///storage/emulated/0/Download/system.raw.gz  \
--el KEY_SYSTEM_SIZE $(du -b system.raw|cut -f1)  \
--el KEY_USERDATA_SIZE 8589934592

DSU mit einer App starten

Der Haupteinstiegspunkt für DSU ist die API android.os.image.DynamicSystemClient.java:

public class DynamicSystemClient {


...
...

     /**
     * Start installing DynamicSystem from URL with default userdata size.
     *
     * @param systemUrl A network URL or a file URL to system image.
     * @param systemSize size of system image.
     */
    public void start(String systemUrl, long systemSize) {
        start(systemUrl, systemSize, DEFAULT_USERDATA_SIZE);
    }

Sie müssen diese App auf dem Gerät bündeln/vorinstallieren. Da DynamicSystemClient eine System-API ist, können Sie die App nicht mit der regulären SDK-API erstellen und nicht bei Google Play veröffentlichen. Diese App dient zu Folgendem:

  1. Eine Imageliste und die entsprechende URL mit einem vom Anbieter definierten Schema abrufen.
  2. Die Bilder in der Liste mit dem Gerät abgleichen und kompatible Bilder zur Auswahl für den Nutzer anzeigen.
  3. DynamicSystemClient.start so aufrufen:

    DynamicSystemClient aot = new DynamicSystemClient(...)
       aot.start(
            ...URL of the selected image...,
            ...uncompressed size of the selected image...);
    
    

Die URL verweist auf eine komprimierte, nicht spärliche Systemimage-Datei, die Sie mit den folgenden Befehlen erstellen können:

$ simg2img ${OUT}/system.img ${OUT}/system.raw
$ gzip ${OUT}/system.raw
$ ls ${OUT}/system.raw.gz

Der Dateiname sollte folgendes Format haben:

<android version>.<lunch name>.<user defined title>.raw.gz

Beispiele:

  • o.aosp_taimen-userdebug.2018dev.raw.gz
  • p.aosp_taimen-userdebug.2018dev.raw.gz

DSU-Loader mit einem Klick

In Android 11 wurde der DSU-Ladeprogramm mit einem Klick eingeführt, ein Frontend in den Entwicklereinstellungen.

DSU-Loader starten

Abbildung 1 : DSU-Loader starten

Wenn der Entwickler auf die Schaltfläche DSU-Ladeprogramm klickt, wird ein vorkonfigurierter DSU-JSON-Deskriptor aus dem Web abgerufen und alle anwendbaren Bilder werden im unverankerten Menü angezeigt. Wählen Sie ein Image aus, um die DSU-Installation zu starten. Der Fortschritt wird in der Benachrichtigungsleiste angezeigt.

Fortschritt der DSU-Image-Installation

Abbildung 2 : Fortschritt der DSU-Imageinstallation

Standardmäßig lädt der DSU-Ladeprogramm einen JSON-Deskriptor, der die GSI-Images enthält. In den folgenden Abschnitten wird gezeigt, wie Sie OEM-signierte DSU-Pakete erstellen und über das DSU-Ladeprogramm laden.

Funktions-Flag

Die DSU-Funktion ist unter dem Funktions-Flag settings_dynamic_android verfügbar. Bevor Sie DSU verwenden, müssen Sie das entsprechende Funktions-Flag aktivieren.

Aktivieren Sie das Funktions-Flag.

Abbildung 3 : Funktions-Flag aktivieren

Die Benutzeroberfläche für Funktions-Flags ist möglicherweise auf einem Gerät mit einem Nutzer-Build nicht verfügbar. Verwenden Sie in diesem Fall stattdessen den Befehl adb:

$ adb shell setprop persist.sys.fflag.override.settings_dynamic_system 1

Systemimages des Anbieters auf GCE (optional)

Einer der möglichen Speicherorte für die Systemimages ist der Google Compute Engine-Bucket (GCE). Der Release-Administrator verwendet die GCP-Speicherkonsole, um das veröffentlichte Systemimage hinzuzufügen, zu löschen oder zu ändern.

Die Images müssen öffentlich zugänglich sein, wie hier gezeigt:

Öffentlicher Zugriff in GCE

Abbildung 4 : Öffentlicher Zugriff in GCE

Die Anleitung zum öffentlichen Zugriff auf ein Element finden Sie in der Google Cloud-Dokumentation.

DSU mit mehreren Partitionen in einer ZIP-Datei

Ab Android 11 kann DSU mehrere Partitionen haben. Es kann beispielsweise zusätzlich zu system.img auch product.img enthalten. Wenn das Gerät gestartet wird, erkennt die erste Phase von init die installierten DSU-Partitionen und ersetzt die Partition auf dem Gerät vorübergehend, wenn die installierte DSU aktiviert ist. Das DSU-Paket kann eine Partition enthalten, die keine entsprechende Partition auf dem Gerät hat.

DSU-Prozess mit mehreren Partitionen

Abbildung 5 : DSU-Prozess mit mehreren Partitionen

OEM-signierte DSU

Damit alle auf dem Gerät ausgeführten Images vom Gerätehersteller autorisiert sind, müssen alle Images in einem DSU-Paket signiert sein. Angenommen, es gibt ein DSU-Paket mit zwei Partitionen-Images wie unten:

dsu.zip {
    - system.img
    - product.img
}

Sowohl system.img als auch product.img müssen mit dem OEM-Schlüssel signiert werden, bevor sie in die ZIP-Datei eingefügt werden. Üblicherweise wird ein asymmetrischer Algorithmus verwendet, z. B. RSA, bei dem der geheime Schlüssel zum Signieren des Pakets und der öffentliche Schlüssel zum Überprüfen verwendet wird. Die Ramdisk der ersten Phase muss den öffentlichen Schlüssel für das Pairing enthalten, z. B. /avb/*.avbpubkey. Wenn das Gerät AVB bereits übernommen hat, reicht das vorhandene Signaturverfahren aus. In den folgenden Abschnitten wird der Signaturprozess veranschaulicht und die Platzierung des öffentlichen AVB-Schlüssels hervorgehoben, der zum Überprüfen der Images im DSU-Paket verwendet wird.

DSU-JSON-Deskriptor

Der DSU-JSON-Deskriptor beschreibt DSU-Pakete. Er unterstützt zwei Primitive. Das erste, include, enthält zusätzliche JSON-Deskriptoren oder leitet das DSU-Ladeprogramm an einen neuen Speicherort weiter. Beispiel:

{
    "include": ["https://.../gsi-release/gsi-src.json"]
}

Das zweite, image, wird verwendet, um veröffentlichte DSU-Pakete zu beschreiben. Innerhalb des Image-Primitivs gibt es mehrere Attribute:

  • Die Attribute name und details sind Strings, die im Dialogfeld zur Auswahl für den Nutzer angezeigt werden.

  • Die Attribute cpu_api, vndk und os_version werden für Kompatibilitätsprüfungen verwendet, die im nächsten Abschnitt beschrieben werden.

  • Das optionale Attribut pubkey beschreibt den öffentlichen Schlüssel, der mit dem geheimen Schlüssel gepairt ist, der zum Signieren des DSU-Pakets verwendet wird. Wenn es angegeben ist, kann der DSU-Dienst prüfen, ob das Gerät den Schlüssel hat, der zum Überprüfen des DSU-Pakets verwendet wird. So wird verhindert, dass ein nicht erkanntes DSU-Paket installiert wird, z. B. ein DSU, das von OEM-A signiert wurde, auf einem Gerät von OEM-B.

  • Das optionale Attribut tos verweist auf eine Textdatei, in der die Nutzungsbedingungen für das entsprechende DSU-Paket beschrieben sind. Wenn ein Entwickler ein DSU-Paket auswählt, für das das Attribut „Nutzungsbedingungen“ angegeben ist, wird das in Abbildung 6 gezeigte Dialogfeld geöffnet, in dem der Entwickler aufgefordert wird, die Nutzungsbedingungen zu akzeptieren, bevor er das DSU-Paket installiert.

    Dialogfeld „Nutzungsbedingungen“

    Abbildung 6 : Dialogfeld „Nutzungsbedingungen“

Hier ist ein DSU-JSON-Deskriptor für die GSI:

{
   "images":[
      {
         "name":"GSI+GMS x86",
         "os_version":"10",
         "cpu_abi": "x86",
         "details":"exp-QP1A.190711.020.C4-5928301",
         "vndk":[
            27,
            28,
            29
         ],
         "pubkey":"",
         "tos": "https://dl.google.com/developers/android/gsi/gsi-tos.txt",
         "uri":"https://.../gsi/gsi_gms_x86-exp-QP1A.190711.020.C4-5928301.zip"
      },
      {
         "name":"GSI+GMS ARM64",
         "os_version":"10",
         "cpu_abi": "arm64-v8a",
         "details":"exp-QP1A.190711.020.C4-5928301",
         "vndk":[
            27,
            28,
            29
         ],
         "pubkey":"",
         "tos": "https://dl.google.com/developers/android/gsi/gsi-tos.txt",
         "uri":"https://.../gsi/gsi_gms_arm64-exp-QP1A.190711.020.C4-5928301.zip"
      },
      {
         "name":"GSI ARM64",
         "os_version":"10",
         "cpu_abi": "arm64-v8a",
         "details":"exp-QP1A.190711.020.C4-5928301",
         "vndk":[
            27,
            28,
            29
         ],
         "pubkey":"",
         "uri":"https://.../gsi/aosp_arm64-exp-QP1A.190711.020.C4-5928301.zip"
      },
      {
         "name":"GSI x86_64",
         "os_version":"10",
         "cpu_abi": "x86_64",
         "details":"exp-QP1A.190711.020.C4-5928301",
         "vndk":[
            27,
            28,
            29
         ],
         "pubkey":"",
         "uri":"https://.../gsi/aosp_x86_64-exp-QP1A.190711.020.C4-5928301.zip"
      }
   ]
}

Kompatibilitätsmanagement

Mehrere Attribute werden verwendet, um die Kompatibilität zwischen einem DSU-Paket und dem lokalen Gerät anzugeben:

  • cpu_api ist ein String, der die Gerätearchitektur beschreibt. Dieses Attribut ist obligatorisch und wird mit der Systemeigenschaft ro.product.cpu.abi verglichen. Die Werte müssen genau übereinstimmen.

  • os_version ist eine optionale Ganzzahl, die eine Android-Version angibt. Für Android 10 ist os_version beispielsweise 10 und für Android 11 ist os_version 11. Wenn dieses Attribut angegeben ist, muss es größer oder gleich der Systemeigenschaft ro.system.build.version.release sein. Mit dieser Prüfung soll verhindert werden, dass ein Android 10-GSI-Image auf einem Android 11-Gerät des Anbieters gestartet wird, was derzeit nicht unterstützt wird. Das Booten eines Android 11-GSI-Images auf einem Android 10-Gerät ist zulässig.

  • vndk ist ein optionales Array, das alle VNDKs angibt, die im DSU-Paket enthalten sind. Wenn es angegeben ist, prüft das DSU-Ladeprogramm, ob die aus der Systemeigenschaft ro.vndk.version extrahierte Zahl enthalten ist.

DSU-Schlüssel aus Sicherheitsgründen widerrufen

In dem äußerst seltenen Fall, dass das RSA-Schlüsselpaar, das zum Signieren der DSU-Images verwendet wird, kompromittiert wurde, sollte die Ramdisk so schnell wie möglich aktualisiert werden, um den kompromittierten Schlüssel zu entfernen. Neben der Aktualisierung der Bootpartition können Sie kompromittierte Schlüssel auch mit einer DSU-Schlüsselwiderrufsliste (Schlüssel-Blacklist) von einer HTTPS-URL blockieren.

Die DSU-Schlüsselwiderrufsliste enthält eine Liste der widerrufenen öffentlichen AVB-Schlüssel. Während der DSU-Installation werden die öffentlichen Schlüssel in den DSU-Images mit der Widerrufsliste validiert. Wenn die Images einen widerrufenen öffentlichen Schlüssel enthalten, wird die DSU-Installation beendet.

Die URL der Schlüsselwiderrufsliste sollte eine HTTPS-URL sein, um die Sicherheitsstärke zu gewährleisten. Sie wird in einem Ressourcenstring angegeben:

frameworks/base/packages/DynamicSystemInstallationService/res/values/strings.xml@key_revocation_list_url

Der Wert des Strings ist https://dl.google.com/developers/android/gsi/gsi-keyblacklist.json. Das ist eine Widerrufsliste für von Google veröffentlichte GSI-Schlüssel. Dieser Ressourcenstring kann überlagert und angepasst werden, sodass OEMs, die die DSU-Funktion übernehmen, ihre eigene Schlüssel-Blacklist bereitstellen und verwalten können. So kann der OEM bestimmte öffentliche Schlüssel blockieren, ohne das Ramdisk-Image des Geräts aktualisieren zu müssen.

Das Format der Widerrufsliste ist:

{
   "entries":[
      {
         "public_key":"bf14e439d1acf231095c4109f94f00fc473148e6",
         "status":"REVOKED",
         "reason":"Key revocation test key"
      },
      {
         "public_key":"d199b2f29f3dc224cca778a7544ea89470cbef46",
         "status":"REVOKED",
         "reason":"Key revocation test key"
      }
   ]
}
  • public_key ist der SHA-1-Digest des widerrufenen Schlüssels im Format, das im Abschnitt zum Generieren des öffentlichen AVB-Schlüssels beschrieben ist.
  • status gibt den Widerrufsstatus des Schlüssels an. Derzeit ist der einzige unterstützte Wert REVOKED.
  • reason ist ein optionaler String, der den Grund für den Widerruf beschreibt.

DSU-Verfahren

In diesem Abschnitt wird beschrieben, wie Sie verschiedene DSU-Konfigurationsverfahren ausführen.

Neues Schlüsselpaar generieren

Verwenden Sie den Befehl openssl, um ein privates/öffentliches RSA-Schlüsselpaar im .pem-Format zu generieren (z. B. mit einer Größe von 2048 Bit):

$ openssl genrsa -out oem_cert_pri.pem 2048
$ openssl rsa -in oem_cert_pri.pem -pubout -out oem_cert_pub.pem

Der private Schlüssel ist möglicherweise nicht zugänglich und wird nur in einem Hardware Security Module (HSM) gespeichert. In diesem Fall ist nach der Schlüsselgenerierung möglicherweise ein x509 Public-Key-Zertifikat verfügbar. Eine Anleitung zum Generieren des öffentlichen AVB-Schlüssels aus einem x509-Zertifikat finden Sie im Abschnitt Öffentlichen Schlüssel für das Pairing zur Ramdisk hinzufügen.

So konvertieren Sie ein x509-Zertifikat in das PEM-Format:

$ openssl x509 -pubkey -noout -in oem_cert_pub.x509.pem > oem_cert_pub.pem

Überspringen Sie diesen Schritt, wenn das Zertifikat bereits eine PEM-Datei ist.

Öffentlichen Schlüssel für das Pairing zur Ramdisk hinzufügen

Die Datei oem_cert.avbpubkey muss unter /avb/*.avbpubkey platziert werden, um das signierte DSU-Paket zu überprüfen. Konvertieren Sie zuerst den öffentlichen Schlüssel im PEM-Format in das öffentliche AVB-Schlüsselformat:

$ avbtool extract_public_key --key oem_cert_pub.pem --output oem_cert.avbpubkey

Fügen Sie dann den öffentlichen Schlüssel mit den folgenden Schritten in die Ramdisk der ersten Phase ein.

  1. Fügen Sie ein vorkompiliertes Modul hinzu, um avbpubkey zu kopieren. Fügen Sie beispielsweise device/<company>/<board>/oem_cert.avbpubkey und device/<company>/<board>/avb/Android.mk mit folgendem Inhalt hinzu:

    include $(CLEAR_VARS)
    
    LOCAL_MODULE := oem_cert.avbpubkey
    LOCAL_MODULE_CLASS := ETC
    LOCAL_SRC_FILES := $(LOCAL_MODULE)
    ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
    LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/first_stage_ramdisk/avb
    else
    LOCAL_MODULE_PATH := $(TARGET_RAMDISK_OUT)/avb
    endif
    
    include $(BUILD_PREBUILT)
    
  2. Machen Sie das Ziel „droidcore“ von der hinzugefügten Datei oem_cert.avbpubkey abhängig:

    droidcore: oem_cert.avbpubkey
    

Attribut für öffentlichen AVB-Schlüssel im JSON-Deskriptor generieren

Die Datei oem_cert.avbpubkey hat das binäre Format des öffentlichen AVB-Schlüssels. Verwenden Sie SHA-1, um sie lesbar zu machen, bevor Sie sie in den JSON-Deskriptor einfügen:

$ sha1sum oem_cert.avbpubkey | cut -f1 -d ' '
3e62f2be9d9d813ef5........866ac72a51fd20

Dies ist der Inhalt des Attributs pubkey des JSON-Deskriptors.

   "images":[
      {
         ...
         "pubkey":"3e62f2be9d9d813ef5........866ac72a51fd20",
         ...
      },

DSU-Paket signieren

Verwenden Sie eine der folgenden Methoden, um ein DSU-Paket zu signieren:

  • Methode 1: Verwenden Sie das Artefakt, das durch den ursprünglichen AVB-Signaturprozess erstellt wurde, um ein DSU-Paket zu erstellen. Alternativ können Sie die bereits signierten Images aus dem Release-Paket extrahieren und die extrahierten Images verwenden, um die ZIP-Datei direkt zu erstellen.

  • Methode 2: Verwenden Sie die folgenden Befehle, um DSU-Partitionen zu signieren, wenn der private Schlüssel verfügbar ist. Jedes img in einem DSU-Paket (der ZIP-Datei) wird separat signiert:

    $ key_len=$(openssl rsa -in oem_cert_pri.pem -text | grep Private-Key | sed -e 's/.*(\(.*\) bit.*/\1/')
    $ for partition in system product; do
        avbtool add_hashtree_footer \
            --image ${OUT}/${partition}.img \
            --partition_name ${partition} \
            --algorithm SHA256_RSA${key_len} \
            --key oem_cert_pri.pem
    done
    

Weitere Informationen zum Hinzufügen von add_hashtree_footer mit avbtool finden Sie unter avbtool verwenden.

DSU-Paket lokal überprüfen

Wir empfehlen, alle lokalen Images mit den folgenden Befehlen mit dem öffentlichen Schlüssel für das Pairing zu überprüfen:


for partition in system product; do
    avbtool verify_image --image ${OUT}/${partition}.img  --key oem_cert_pub.pem
done

Die erwartete Ausgabe sieht so aus:

Verifying image dsu/system.img using key at oem_cert_pub.pem
vbmeta: Successfully verified footer and SHA256_RSA2048 vbmeta struct in dsu/system.img
: Successfully verified sha1 hashtree of dsu/system.img for image of 898494464 bytes

Verifying image dsu/product.img using key at oem_cert_pub.pem
vbmeta: Successfully verified footer and SHA256_RSA2048 vbmeta struct in dsu/product.img
: Successfully verified sha1 hashtree of dsu/product.img for image of 905830400 bytes

DSU-Paket erstellen

Im folgenden Beispiel wird ein DSU-Paket erstellt, das system.img und product.img enthält:

dsu.zip {
    - system.img
    - product.img
}

Nachdem beide Images signiert wurden, verwenden Sie den folgenden Befehl, um die ZIP-Datei zu erstellen:

$ mkdir -p dsu
$ cp ${OUT}/system.img dsu
$ cp ${OUT}/product.img dsu
$ cd dsu && zip ../dsu.zip *.img && cd -

DSU mit einem Klick anpassen

Standardmäßig verweist das DSU-Ladeprogramm auf Metadaten von GSI-Images, nämlich https://...google.com/.../gsi-src.json.

OEMs können die Liste überschreiben, indem sie die Property persist.sys.fflag.override.settings_dynamic_system.list definieren, die auf ihren eigenen JSON-Deskriptor verweist. Ein OEM kann beispielsweise JSON-Metadaten bereitstellen, die sowohl GSI- als auch proprietäre OEM-Images enthalten, wie hier gezeigt:

{
    "include": ["https://dl.google.com/.../gsi-src.JSON"]
    "images":[
      {
         "name":"OEM image",
         "os_version":"10",
         "cpu_abi": "arm64-v8a",
         "details":"...",
         "vndk":[
            27,
            28,
            29
         ],
         "spl":"...",
         "pubkey":"",
         "uri":"https://.../....zip"
      },

}

Ein OEM kann veröffentlichte DSU-Metadaten verketten, wie in Abbildung 7 gezeigt.

Verketten von veröffentlichten DSU-Metadaten

Abbildung 7 : Verkettung von veröffentlichten DSU-Metadaten