dynamisches Systemupdate

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

Kernel-Anforderungen

Informationen zu den Kernelanforderungen finden Sie unter Dynamische Partitionen implementieren.

Außerdem wird bei DSU die Kernel-Funktion „device-mapper-verity“ (dm-verity) verwendet, um das Android-System-Image zu überprüfen. Sie müssen also 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 F2FS- oder ext4-Dateisystem verwendet werden. F2FS bietet eine bessere Leistung und wird empfohlen, der Unterschied sollte jedoch gering sein.

Hier sind einige Beispiele dafür, wie lange ein dynamisches Systemupdate auf einem Pixel-Gerät dauert:

  • Verwendung von F2FS:
    • 109 s, 8 GB Nutzer, 867 MB System, Dateisystemtyp: F2FS: encryption=aes-256-xts:aes-256-cts
    • 104 s, 8 GB Nutzer, 867 MB System, Dateisystemtyp: F2FS: encryption=ice
  • Mit ext4:
    • 135 s, 8 GB Nutzer, 867 MB System, Dateisystemtyp: ext4: encryption=aes-256-xts:aes-256-cts

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

Die Partition metadata (mindestens 16 MB) ist zum Speichern von Daten im Zusammenhang mit den installierten Images erforderlich. Sie muss während der Bereitstellung 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 einfügen, die im Android Common Kernel verfügbar sind.

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

Verhalten der Anbieter-HAL

Weaver-HAL

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

Gatekeeper-HAL

Das Gatekeeper-HAL muss große USER_ID-Werte unterstützen, da das GSI UIDs um +1000000 zum HAL versetzt.

Bootvorgang überprüfen

Wenn Sie das Booten von Developer-GSI-Images im LOCKED-Status unterstützen möchten, ohne Verified Boot zu deaktivieren, fügen Sie die Developer-GSI-Schlüssel hinzu, indem Sie die folgende Zeile in die Datei device/<device_name>/device.mk einfügen:

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

Rollback-Schutz

Wenn Sie DSU verwenden, muss das heruntergeladene Android-System-Image neuer sein als das aktuelle System-Image auf dem Gerät. Dazu werden die Sicherheitspatch-Levels im AVB-Eigenschaftsdeskriptor von Android Verified Boot (AVB) beider System-Images verglichen: Prop: com.android.build.system.security_patch -> '2019-04-05'.

Bei Geräten, die AVB nicht verwenden, muss der Bootloader das Sicherheitspatch-Level des aktuellen System-Images 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 des 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 Unterstützung von SD-Karten ist für Geräte mit geringerer Leistung, die möglicherweise nicht über genügend internen Speicher verfügen, von entscheidender Bedeutung. Wenn eine SD-Karte vorhanden ist, muss sie als externes Speichermedium eingerichtet sein. DSU unterstützt keine als internen Speicher verwendeten SD-Karten.

Verfügbare Front-Ends

Sie können DSU über adb, eine OEM-App oder den DSU-Loader mit nur einem Klick (in Android 11 oder höher) starten.

DSU über 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 über eine App starten

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

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. Der Zweck dieser App ist:

  1. Eine Bildliste und die entsprechende URL mit einem vom Anbieter definierten Schema abrufen.
  2. Gleichen Sie die Bilder in der Liste mit dem Gerät ab und zeigen Sie dem Nutzer kompatible Bilder zur Auswahl an.
  3. So rufen Sie DynamicSystemClient.start auf:

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

Die URL verweist auf eine gezippte, 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

Mit Android 11 wird der DSU-Loader mit nur einem Klick eingeführt, der ein Frontend in den Entwicklereinstellungen ist.

DSU-Loader starten

Abbildung 1: DSU-Loader starten

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

Fortschritt der DSU-Image-Installation

Abbildung 2: Fortschritt der DSU-Image-Installation

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

Funktions-Flag

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

Aktivieren Sie das Funktions-Flag.

Abbildung 3: Funktions-Flag aktivieren

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

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

Anbieter-Hostsystem-Images auf GCE (optional)

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

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

Öffentlicher Zugriff in GCE

Abbildung 4: Öffentlicher Zugriff in GCE

Die Anleitung zum Veröffentlichen eines Elements finden Sie in der Google Cloud-Dokumentation.

DSU mit mehreren Partitionen in ZIP-Datei

Ab Android 11 kann eine dynamische Systemaktualisierung (Dynamic System Update, DSU) mehrere Partitionen haben. Sie kann beispielsweise zusätzlich zum system.img auch ein product.img enthalten. Beim Starten des Geräts erkennt die erste Phase init die installierten DSU-Partitionen und ersetzt die Partition auf dem Gerät vorübergehend, wenn die installierte DSU aktiviert ist. Das DSU-Paket enthält möglicherweise eine Partition, die auf dem Gerät nicht vorhanden ist.

DSU-Prozess mit mehreren Partitionen

Abbildung 5: DSU-Prozess mit mehreren Partitionen

Vom OEM signierte DSU

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

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 aufgenommen werden. Üblicherweise wird ein asymmetrischer Algorithmus wie RSA verwendet, bei dem der geheime Schlüssel zum Signieren des Pakets und der öffentliche Schlüssel zum Verifizieren des Pakets verwendet wird. Die Ramdisk der ersten Phase muss den öffentlichen Schlüssel für die Kopplung enthalten, z. B. /avb/*.avbpubkey. Wenn das Gerät bereits AVB verwendet, reicht das vorhandene Signaturverfahren aus. In den folgenden Abschnitten wird der Signierungsprozess veranschaulicht und die Platzierung des AVB-Pubkeys hervorgehoben, mit dem die Bilder im DSU-Paket überprüft werden.

DSU-JSON-Deskriptor

Der DSU-JSON-Deskriptor beschreibt DSU-Pakete. Es werden zwei Primitiven unterstützt. Zuerst enthält das include-Primitiv zusätzliche JSON-Deskriptoren oder leitet den DSU-Loader an einen neuen Speicherort weiter. Beispiel:

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

Zweitens wird das image-Primitive verwendet, um veröffentlichte DSU-Pakete zu beschreiben. Das Bild-Primitive enthält mehrere Attribute:

  • Die Attribute name und details sind Strings, die im Dialogfeld für den Nutzer zur Auswahl 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 übereinstimmt, der zum Signieren des DSU-Pakets verwendet wird. Wenn sie 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 werden. Wenn ein Entwickler ein DSU-Paket mit dem Attribut für die Nutzungsbedingungen auswählt, wird das in Abbildung 6 gezeigte Dialogfeld geöffnet, in dem der Entwickler aufgefordert wird, die Nutzungsbedingungen zu akzeptieren, bevor das DSU-Paket installiert wird.

    Dialogfeld „Nutzungsbedingungen“

    Abbildung 6 Dialogfeld „Nutzungsbedingungen“

Hier ist ein DSU-JSON-Deskriptor für das 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ätsverwaltung

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 System-Property ro.product.cpu.abi verglichen. Die Werte müssen genau übereinstimmen.

  • os_version ist eine optionale Ganzzahl, die eine Android-Version angibt. Bei Android 10 ist os_version beispielsweise 10 und bei Android 11 ist os_version 11. Wenn dieses Attribut angegeben wird, muss es größer oder gleich der System-Property ro.system.build.version.release sein. Mit dieser Prüfung soll verhindert werden, dass ein Android 10-GSI-Image auf einem Android 11-Anbietergerät gebootet 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 sie angegeben ist, prüft der DSU-Loader, ob die aus der System-Property ro.vndk.version extrahierte Nummer enthalten ist.

DSU-Schlüssel aus Sicherheitsgründen widerrufen

In dem äußerst seltenen Fall, dass das zum Signieren der DSU-Images verwendete RSA-Schlüsselpaar manipuliert wurde, sollte die Ramdisk so schnell wie möglich aktualisiert werden, um den manipulierten Schlüssel zu entfernen. Zusätzlich zum Aktualisieren der Bootpartition können Sie kompromittierte Schlüssel mithilfe einer DSU-Schlüsselwiderrufsliste (Schlüsselschwarze Liste) 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 anhand der Sperrliste validiert. Wenn die Bilder einen widerrufenen öffentlichen Schlüssel enthalten, wird die DSU-Installation beendet.

Die URL der Schlüsselwiderrufsliste sollte eine HTTPS-URL sein, um die Sicherheit 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, eine Sperrliste für von Google veröffentlichte GSI-Schlüssel. Dieser Ressourcenstring kann überlagert und angepasst werden, sodass OEMs, die das DSU-Feature verwenden, ihre eigene Schlüsselsperrliste 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 Sperrliste lautet:

{
   "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 AVB-Pubkey generieren beschrieben wird.
  • status gibt den Sperrstatus 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

Mit dem Befehl openssl können Sie ein privates/öffentliches RSA-Schlüsselpaar im .pem-Format generieren (z. B. mit einer Größe von 2.048 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 öffentliches x509-Schlüsselzertifikat verfügbar. Eine Anleitung zum Generieren des öffentlichen AVB-Schlüssels aus einem X.509-Zertifikat finden Sie im Abschnitt Pairing-Pubkey 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.

Pairing-Pubkey zur Ramdisk hinzufügen

Das oem_cert.avbpubkey muss unter /avb/*.avbpubkey platziert werden, um das signierte DSU-Paket zu bestätigen. Konvertieren Sie zuerst den öffentlichen Schlüssel im PEM-Format in das AVB-Format für öffentliche Schlüssel:

$ 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 vorgefertigtes 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 droidcore-Ziel vom hinzugefügten oem_cert.avbpubkey abhängig:

    droidcore: oem_cert.avbpubkey
    

AVB-Pubkey-Attribut im JSON-Deskriptor generieren

oem_cert.avbpubkey hat das binäre Format des öffentlichen AVB-Schlüssels. Verwenden Sie SHA-1, um den Fingerabdruck lesbar zu machen, bevor Sie ihn 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: Das vom ursprünglichen AVB-Signierungsprozess erstellte Artefakt zum Erstellen eines DSU-Pakets wiederverwenden. Alternativ können Sie die bereits signierten Bilder aus dem Release-Paket extrahieren und die ZIP-Datei direkt mit den extrahierten Bildern erstellen.

  • Methode 2: Verwenden Sie die folgenden Befehle, um DSU-Partitionen zu signieren, wenn der private Schlüssel verfügbar ist. Jede 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 prüfen

Es wird empfohlen, alle lokalen Bilder mit diesen Befehlen anhand des öffentlichen Pairing-Schlüssels zu prü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 eine system.img und eine product.img enthält:

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

Nachdem beide Bilder 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 nur einem Klick anpassen

Standardmäßig verweist der DSU-Loader auf Metadaten von GSI-Images, die https://...google.com/.../gsi-src.json sind.

OEMs können die Liste überschreiben, indem sie die persist.sys.fflag.override.settings_dynamic_system.list-Property 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 wie in Abbildung 7 verketten.

Verketten von veröffentlichten DSU-Metadaten

Abbildung 7. Verketten von veröffentlichten DSU-Metadaten