עדכוני מערכת דינמיים

עדכוני מערכת דינמיים (DSU) מאפשרים לך ליצור תמונת מערכת אנדרואיד שמשתמשים יכולים להוריד מהאינטרנט ולנסות ללא סיכון של השחתת תמונת המערכת הנוכחית. מסמך זה מתאר כיצד לתמוך ב-DSU.

דרישות הליבה

ראה הטמעת מחיצות דינמיות לדרישות הליבה.

בנוסף, DSU מסתמך על תכונת ליבת ה-device-mapper-verity (dm-verity) כדי לאמת את תמונת מערכת אנדרואיד. אז עליך להפעיל את תצורות הליבה הבאות:

  • CONFIG_DM_VERITY=y
  • CONFIG_DM_VERITY_FEC=y

דרישות החלוקה

החל ב-Android 11, DSU מחייב את מחיצת /data כדי להשתמש במערכת הקבצים F2FS או ext4. F2FS נותן ביצועים טובים יותר ומומלץ, אבל ההבדל אמור להיות לא משמעותי.

הנה כמה דוגמאות לכמה זמן לוקח עדכון מערכת דינמי עם מכשיר Pixel:

  • באמצעות F2FS:
    • 109s, משתמש 8G, מערכת 867M, סוג מערכת קבצים: F2FS: encryption=aes-256-xts:aes-256-cts
    • 104s, משתמש 8G, מערכת 867M, סוג מערכת קבצים: F2FS: הצפנה=קרח
  • באמצעות ext4:
    • 135s, משתמש 8G, מערכת 867M, סוג מערכת קבצים: ext4: encryption=aes-256-xts:aes-256-cts

אם זה לוקח הרבה יותר זמן בפלטפורמה שלך, אולי תרצה לבדוק אם דגל ההרכבה מכיל דגל כלשהו שגורם לכתוב "סינכרון", או שאתה יכול לציין דגל "אסינכרון" במפורש כדי לקבל ביצועים טובים יותר.

מחיצת metadata (16 MB ומעלה) נדרשת לאחסון נתונים הקשורים לתמונות המותקנות. יש להרכיב אותו במהלך ההרכבה בשלב הראשון.

מחיצת userdata חייבת להשתמש במערכת הקבצים F2FS או ext4. בעת שימוש ב-F2FS, כלול את כל התיקונים הקשורים ל-F2FS הזמינים בקרנל הנפוץ של אנדרואיד .

DSU פותח ונבדק עם kernel/common 4.9. מומלץ להשתמש בגרעין 4.9 ומעלה עבור תכונה זו.

התנהגות HAL של הספק

וויבר HAL

ה-Weaver HAL מספק מספר קבוע של חריצים לאחסון מפתחות משתמש. ה-DSU צורך שני חריצי מפתח נוספים. אם ל-OEM יש HAL אורג, הוא צריך שיהיו לו מספיק חריצים עבור תמונת מערכת גנרית (GSI) ותמונת מארח.

שומר סף HAL

ה- Gatekeeper HAL צריך לתמוך בערכי USER_ID גדולים, מכיוון שה-GSI מקזז את ה-UIDs ל-HAL ב-+1000000.

ודא אתחול

אם ברצונך לתמוך באתחול של תמונות GSI של מפתחים במצב נעול מבלי לבטל אתחול מאומת, כלול מפתחות GSI למפתחים על ידי הוספת השורה הבאה להתקן הקובץ device/<device_name>/device.mk :

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

הגנה לאחור

בעת שימוש ב-DSU, תמונת מערכת האנדרואיד שהורדת חייבת להיות חדשה יותר מתמונת המערכת הנוכחית במכשיר. זה נעשה על ידי השוואת רמות תיקון האבטחה במתאר ה-AVB של Android Verified Boot (AVB) של שתי תמונות המערכת: Prop: com.android.build.system.security_patch -> '2019-04-05' .

עבור מכשירים שאינם משתמשים ב-AVB, הכנס את רמת תיקון האבטחה של תמונת המערכת הנוכחית לתוך הליבה cmdline או bootconfig עם טוען האתחול: androidboot.system.security_patch=2019-04-05 .

דרישות חומרה

כאשר אתה מפעיל מופע DSU, שני קבצים זמניים מוקצים:

  • מחיצה לוגית לאחסון GSI.img (1~1.5 G)
  • מחיצת /data ריקה בנפח 8 GB כארגז החול להפעלת ה-GSI

אנו ממליצים לשמור לפחות 10 GB של מקום פנוי לפני השקת מופע DSU. DSU תומך גם בהקצאה מכרטיס SD. כאשר קיים כרטיס SD, יש לו את העדיפות הגבוהה ביותר להקצאה. תמיכה בכרטיסי SD היא קריטית עבור מכשירים בעלי הספק נמוך שאולי אין להם מספיק אחסון פנימי. כאשר קיים כרטיס SD, ודא שהוא לא מאומץ. DSU אינו תומך בכרטיסי SD מאומצים .

חזיתות זמינות

אתה יכול להפעיל את DSU באמצעות adb , אפליקציית OEM או מטעין DSU בלחיצה אחת (באנדרואיד 11 ומעלה).

הפעל את DSU באמצעות adb

כדי להפעיל את DSU באמצעות adb, הזן את הפקודות הבאות:

$ 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 באמצעות אפליקציה

נקודת הכניסה העיקרית ל-DSU היא ה-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);
    }

עליך לאגד/להתקין מראש את האפליקציה הזו במכשיר. מכיוון ש- DynamicSystemClient הוא ממשק API של מערכת, אינך יכול לבנות את האפליקציה עם ה-API הרגיל של SDK ואי אפשר לפרסם אותה ב-Google Play. מטרת האפליקציה הזו היא:

  1. אחזר רשימת תמונות ואת כתובת האתר המתאימה עם סכימה המוגדרת על ידי הספק.
  2. התאם את התמונות ברשימה למכשיר והצג תמונות תואמות לבחירת המשתמש.
  3. הפעל את DynamicSystemClient.start כך:

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

כתובת ה-URL מצביעה על קובץ תמונת מערכת ב-gzip, לא דל, שתוכל ליצור באמצעות הפקודות הבאות:

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

שם הקובץ צריך להיות בפורמט הזה:

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

דוגמאות:

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

מטעין DSU בלחיצה אחת

אנדרואיד 11 מציגה את מטעין DSU בלחיצה אחת, המהווה חזית בהגדרות המפתחים.

הפעלת מטעין ה-DSU

איור 1. הפעלת מטעין ה-DSU

כאשר המפתח לוחץ על הלחצן DSU Loader , הוא מביא מתאר DSU JSON מוגדר מראש מהאינטרנט ומציג את כל התמונות הרלוונטיות בתפריט הצף. בחר תמונה כדי להתחיל את התקנת ה-DSU, וההתקדמות מוצגת בסרגל ההתראות.

התקדמות התקנת תמונת DSU

איור 2. התקדמות התקנת תמונת DSU

כברירת מחדל, טוען ה-DSU טוען מתאר JSON המכיל את תמונות ה-GSI. הסעיפים הבאים מדגימים כיצד ליצור חבילות DSU חתומות על ידי OEM ולטעון אותן ממטען ה-DSU.

דגל תכונה

תכונת ה-DSU נמצאת תחת דגל התכונה settings_dynamic_android . לפני השימוש ב-DSU, ודא שדגל התכונה המתאים מופעל.

הפעלת דגל התכונה.

איור 3. הפעלת דגל התכונה

ייתכן שממשק המשתמש של דגל התכונה אינו זמין במכשיר המריץ בניית משתמש. במקרה זה, השתמש בפקודה adb במקום זאת:

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

תמונות מערכת מארח ספק ב-GCE (אופציונלי)

אחד ממיקומי האחסון האפשריים לתמונות המערכת הוא דלי Google Compute Engine (GCE). מנהל ההפצה משתמש במסוף האחסון של GCP כדי להוסיף/למחוק/לשנות את תמונת המערכת שפורסמה.

התמונות חייבות להיות גישה לציבור, כפי שמוצג כאן:

גישה ציבורית ב-GCE

איור 4. גישה לציבור ב-GCE

ההליך להפיכת פריט לציבורי זמין בתיעוד של Google Cloud .

DSU עם מספר מחיצות בקובץ ZIP

החל מאנדרואיד 11, ל-DSU יכולה להיות יותר ממחיצה אחת. לדוגמה, הוא יכול להכיל את product.img בנוסף ל- system.img . כאשר המכשיר מאתחל, השלב הראשון init מזהה את מחיצות ה-DSU המותקנות ומחליף את המחיצה במכשיר באופן זמני, כאשר ה-DSU המותקן מופעל. חבילת DSU עשויה להכיל מחיצה שאין לה מחיצה מתאימה במכשיר.

תהליך DSU עם מספר מחיצות

איור 5. תהליך DSU עם מחיצות מרובות

DSU חתום על ידי OEM

כדי לוודא שכל התמונות הפועלות במכשיר מאושרות על ידי יצרן המכשיר, יש לחתום על כל התמונות בחבילת DSU. לדוגמה, נניח שיש חבילת DSU המכילה שתי תמונות מחיצה כמו להלן:

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

הן system.img והן product.img חייבים להיות חתומים על ידי מפתח OEM לפני הכנסתם לקובץ ה-ZIP. הנוהג המקובל הוא להשתמש באלגוריתם א-סימטרי, למשל, RSA, שבו המפתח הסודי משמש לחתימה על החבילה והמפתח הציבורי משמש לאימותה. ה-ramdisk של השלב הראשון חייב לכלול את המפתח הציבורי לקישור, לדוגמה, /avb/*.avbpubkey . אם המכשיר כבר אימץ את AVB, נוהל החתימה הקיים יספיק. הסעיפים הבאים ממחישים את תהליך החתימה ומדגישים את המיקום של AVB pubkey המשמש לאימות התמונות בחבילת DSU.

מתאר DSU JSON

מתאר DSU JSON מתאר חבילות DSU. זה תומך בשני פרימיטיבים. ראשית, ה- include primitive כולל מתארי JSON נוספים או מפנה מחדש את מטעין ה-DSU למיקום חדש. לדוגמה:

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

שנית, פרימיטיבי image משמש לתיאור חבילות DSU שפורסמו. בתוך פרימיטיבי התמונה יש כמה תכונות:

  • תכונות name details הן מחרוזות המוצגות בתיבת הדו-שיח לבחירת המשתמש.

  • התכונות cpu_api , vndk ו- os_version משמשות לבדיקות תאימות, המתוארות בסעיף הבא.

  • תכונת pubkey האופציונלית מתארת ​​את המפתח הציבורי שמתאים למפתח הסודי המשמש לחתימה על חבילת ה-DSU. כאשר זה מצוין, שירות DSU יכול לבדוק אם למכשיר יש את המפתח המשמש לאימות חבילת ה-DSU. כך נמנע התקנת חבילת DSU לא מזוהה, למשל התקנת DSU חתום על ידי OEM-A למכשיר מתוצרת OEM-B.

  • התכונה האופציונלית tos מצביעה על קובץ טקסט המתאר את תנאי השירות עבור חבילת ה-DSU המתאימה. כאשר מפתח בוחר חבילת DSU עם תכונת תנאי השירות שצוינה, תיבת הדו-שיח המוצגת באיור 6 נפתחת, ומבקשת מהמפתח לקבל את תנאי השירות לפני התקנת חבילת DSU.

    תיבת דו-שיח תנאי שירות

    איור 6. תיבת הדו-שיח תנאי השירות

לעיון, הנה מתאר DSU JSON עבור 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"
      }
   ]
}

ניהול תאימות

מספר מאפיינים משמשים לציון התאימות בין חבילת DSU למכשיר המקומי:

  • cpu_api היא מחרוזת המתארת ​​את ארכיטקטורת המכשיר. תכונה זו היא חובה והיא מושווה למאפיין המערכת ro.product.cpu.abi . הערכים שלהם חייבים להתאים בדיוק.

  • os_version הוא מספר שלם אופציונלי המציין גרסת אנדרואיד. לדוגמה, עבור Android 10, os_version הוא 10 ועבור Android 11, os_version הוא 11 . כאשר תכונה זו מצוינת, היא חייבת להיות שווה למאפיין המערכת ro.system.build.version.release או גדול ממנו. הסימון הזה משמש למניעת אתחול תמונת Android 10 GSI במכשיר של ספק אנדרואיד 11, שאינו נתמך כרגע. אתחול תמונת Android 11 GSI במכשיר Android 10 מותר.

  • vndk הוא מערך אופציונלי המציין את כל ה-VNDK הכלולים בחבילת DSU. כאשר זה מצוין, טוען DSU בודק אם המספר שחולץ ממאפיין המערכת ro.vndk.version כלול.

שלל מפתחות DSU לצורך אבטחה

במקרה הנדיר ביותר כאשר צמד מפתחות ה-RSA המשמשים לחתימה על תמונות ה-DSU נפגע, יש לעדכן את ה-ramdisk בהקדם האפשרי כדי להסיר את המפתח שנפרץ. בנוסף לעדכון מחיצת האתחול, אתה יכול לחסום מפתחות שנפרצו באמצעות רשימת ביטול מפתחות DSU (רשימה שחורה של מפתחות) מכתובת URL של HTTPS.

רשימת ביטול מפתחות DSU מכילה רשימה של מפתחות ציבוריים של AVB שבוטלו. במהלך התקנת DSU, המפתחות הציבוריים בתוך תמונות ה-DSU מאומתים עם רשימת הביטולים. אם נמצא שהתמונות מכילות מפתח ציבורי שבוטל, תהליך ההתקנה של DSU נעצר.

כתובת ה-URL של רשימת ביטולי המפתח צריכה להיות כתובת URL של HTTPS כדי להבטיח את עוצמת האבטחה, והיא מצוינת במחרוזת משאבים:

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

ערך המחרוזת הוא https://dl.google.com/developers/android/gsi/gsi-keyblacklist.json , שהיא רשימת ביטולים עבור מפתחות GSI שפורסמו ב-Google. מחרוזת משאבים זו ניתנת לכיסוי ולהתאים אישית, כך שיצרני OEM שמאמצים את תכונת ה-DSU יכולים לספק ולתחזק רשימה שחורה של מפתחות משלהם. זה מספק דרך ל-OEM לחסום מפתחות ציבוריים מסוימים מבלי לעדכן את תמונת ramdisk של ההתקן.

הפורמט של רשימת הביטולים הוא:

{
   "entries":[
      {
         "public_key":"bf14e439d1acf231095c4109f94f00fc473148e6",
         "status":"REVOKED",
         "reason":"Key revocation test key"
      },
      {
         "public_key":"d199b2f29f3dc224cca778a7544ea89470cbef46",
         "status":"REVOKED",
         "reason":"Key revocation test key"
      }
   ]
}
  • public_key הוא תקציר SHA-1 של המפתח שבוטל, בפורמט המתואר בקטע יצירת ה-AVB pubkey .
  • status מציין את מצב ביטול המפתח. נכון לעכשיו, הערך הנתמך היחיד הוא REVOKED .
  • reason היא מחרוזת אופציונלית המתארת ​​את הסיבה לביטול.

נהלי DSU

סעיף זה מתאר כיצד לבצע מספר הליכי תצורת DSU.

צור זוג מפתחות חדש

השתמש בפקודה openssl כדי ליצור זוג מפתחות RSA פרטי/ציבורי בפורמט .pem (לדוגמה, בגודל 2048 סיביות):

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

ייתכן שהמפתח הפרטי אינו נגיש והוא נשמר רק במודול אבטחת חומרה (HSM) . במקרה זה, ייתכן שיהיה אישור מפתח ציבורי x509 זמין לאחר יצירת המפתח. עיין בסעיף הוספת מפתח הצימוד ל-ramdisk לקבלת הוראות ליצירת המפתח הציבורי של AVB מתעודת x509.

כדי להמיר אישור x509 לפורמט PEM:

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

דלג על שלב זה אם האישור כבר קובץ PEM.

הוסף את מפתח הצימוד ל-ramdisk

יש לשים את ה- oem_cert.avbpubkey תחת /avb/*.avbpubkey כדי לאמת את חבילת ה-DSU החתומה. ראשית, המר את המפתח הציבורי בפורמט PEM לפורמט מפתח ציבורי AVB:

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

לאחר מכן כלול את המפתח הציבורי בשלב הראשון ramdisk עם השלבים הבאים.

  1. הוסף מודול בנוי מראש כדי להעתיק את avbpubkey . לדוגמה, הוסף device/<company>/<board>/oem_cert.avbpubkey ו- device/<company>/<board>/avb/Android.mk עם תוכן כזה:

    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. הפוך את יעד ה-droidcore תלוי ב- oem_cert.avbpubkey שנוסף:

    droidcore: oem_cert.avbpubkey
    

צור את התכונה AVB pubkey במתאר JSON

ה- oem_cert.avbpubkey הוא בפורמט הבינארי של המפתח הציבורי AVB. השתמש ב-SHA-1 כדי להפוך אותו לקריאה לפני הכנסתו ל-JSON מתאר:

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

זה יהיה התוכן של תכונת pubkey של מתאר JSON.

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

חתום על חבילת DSU

השתמש באחת מהשיטות הבאות כדי לחתום על חבילת DSU:

  • שיטה 1: השתמש מחדש בחפץ שנוצר בתהליך החתימה המקורי של AVB כדי ליצור חבילת DSU. גישה חלופית היא לחלץ את התמונות שכבר חתומות מחבילת השחרור ולהשתמש בתמונות שחולצו כדי ליצור את קובץ ה-ZIP ישירות.

  • שיטה 2: השתמש בפקודות הבאות כדי לחתום על מחיצות DSU אם המפתח הפרטי זמין. כל img בתוך חבילת DSU (קובץ ה-ZIP) חתום בנפרד:

    $ 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
    

למידע נוסף על הוספת add_hashtree_footer באמצעות avbtool , ראה שימוש ב-avbtool .

אמת את חבילת ה-DSU באופן מקומי

מומלץ לאמת את כל התמונות המקומיות מול המפתח הציבורי להתאמה באמצעות הפקודות הבאות:


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

הפלט הצפוי נראה כך:

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

הדוגמה הבאה מייצרת חבילת DSU המכילה system.img ו- product.img :

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

לאחר חתימת שתי התמונות, השתמש בפקודה הבאה כדי ליצור את קובץ ה-ZIP:

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

התאם אישית את ה-DSU בלחיצה אחת

כברירת מחדל, טוען ה-DSU מצביע על מטא נתונים של תמונות GSI שהם https://...google.com/.../gsi-src.json .

יצרני OEM יכולים להחליף את הרשימה על ידי הגדרת המאפיין persist.sys.fflag.override.settings_dynamic_system.list שמצביע על מתאר JSON משלהם. לדוגמה, יצרן OEM עשוי לספק מטא נתונים של JSON הכוללים GSI וכן תמונות קנייניות של OEM כמו זה:

{
    "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"
      },

}

זה אפשרי עבור יצרן OEM לשרשר מטא נתונים של DSU שפורסמו כפי שמוצג באיור 7.

שרשרת מטא נתונים של DSU שפורסמו

איור 7. שרשרת מטא נתונים של DSU שפורסמו