Bản cập nhật hệ thống động

Bản cập nhật hệ thống động (DSU) cho phép bạn tạo một hình ảnh hệ thống Android mà người dùng có thể tải xuống từ Internet và dùng thử mà không gặp rủi ro làm hỏng hình ảnh hệ thống hiện tại. Tài liệu này mô tả cách hỗ trợ DSU.

Yêu cầu về kernel

Hãy xem phần Triển khai phân vùng động để biết các yêu cầu về nhân.

Ngoài ra, DSU dựa vào tính năng kernel device-mapper-verity (dm-verity) để xác minh hình ảnh hệ thống Android. Vì vậy, bạn phải bật các cấu hình kernel sau:

  • CONFIG_DM_VERITY=y
  • CONFIG_DM_VERITY_FEC=y

Yêu cầu về phân vùng

Kể từ Android 11, DSU yêu cầu phân vùng /data sử dụng hệ thống tệp F2FS hoặc ext4. F2FS mang lại hiệu suất tốt hơn và được khuyến nghị, nhưng sự khác biệt không đáng kể.

Sau đây là một số ví dụ về thời gian cần thiết để cập nhật hệ thống động trên thiết bị Pixel:

  • Sử dụng F2FS:
    • 109 giây, người dùng 8G, hệ thống 867M, loại hệ thống tệp: F2FS: encryption=aes-256-xts:aes-256-cts
    • 104 giây, người dùng 8G, hệ thống 867M, loại hệ thống tệp: F2FS: encryption=ice
  • Sử dụng ext4:
    • 135 giây, người dùng 8G, hệ thống 867M, loại hệ thống tệp: ext4: encryption=aes-256-xts:aes-256-cts

Nếu mất nhiều thời gian hơn trên nền tảng của bạn, bạn có thể kiểm tra xem cờ gắn kết có chứa cờ nào khiến thao tác ghi "sync" hay không, hoặc bạn có thể chỉ định rõ ràng cờ "async" để có hiệu suất tốt hơn.

Bạn phải có phân vùng metadata (từ 16 MB trở lên) để lưu trữ dữ liệu liên quan đến hình ảnh đã cài đặt. Bạn phải gắn ổ đĩa trong quá trình gắn giai đoạn đầu.

Phân vùng userdata phải sử dụng hệ thống tệp F2FS hoặc ext4. Khi sử dụng F2FS, hãy thêm tất cả các bản vá liên quan đến F2FS có trong nhân chung của Android.

DSU được phát triển và kiểm thử bằng kernel/common 4.9. Bạn nên sử dụng nhân 4.9 trở lên cho tính năng này.

Hành vi của HAL nhà cung cấp

HAL của Weaver

HAL của Weaver cung cấp một số lượng cố định các khe cắm để lưu trữ khoá người dùng. DSU sử dụng thêm 2 khe cắm khoá. Nếu có một HAL weaver, thì OEM cần có đủ các khe cắm cho một hình ảnh hệ thống chung (GSI) và một hình ảnh máy chủ.

Gatekeeper HAL

Gatekeeper HAL cần hỗ trợ các giá trị USER_ID lớn, vì GSI bù UID cho HAL thêm 1000000.

Xác minh quy trình khởi động

Nếu bạn muốn hỗ trợ khởi động Hình ảnh GSI dành cho nhà phát triểnTRẠNG THÁI BỊ KHOÁ mà không cần tắt quy trình khởi động đã xác minh, hãy thêm các khoá GSI dành cho nhà phát triển bằng cách thêm dòng sau vào tệp device/<device_name>/device.mk:

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

Bảo vệ chống khôi phục

Khi sử dụng DSU, hình ảnh hệ thống Android đã tải xuống phải mới hơn hình ảnh hệ thống hiện tại trên thiết bị. Việc này được thực hiện bằng cách so sánh các cấp bản vá bảo mật trong Quy trình khởi động được xác minh của Android (AVB) trình mô tả thuộc tính AVB của cả hai hình ảnh hệ thống: Prop: com.android.build.system.security_patch -> '2019-04-05'.

Đối với những thiết bị không dùng AVB, hãy đặt cấp bản vá bảo mật của hình ảnh hệ thống hiện tại vào cmdline hoặc bootconfig của nhân bằng trình tải khởi động: androidboot.system.security_patch=2019-04-05.

Yêu cầu về phần cứng

Khi bạn khởi chạy một phiên bản DSU, hai tệp tạm thời sẽ được phân bổ:

  • Một phân vùng logic để lưu trữ GSI.img (1~1,5 G)
  • Phân vùng /data trống 8 GB làm hộp cát để chạy GSI

Bạn nên dành ít nhất 10 GB dung lượng trống trước khi chạy một phiên bản DSU. DSU cũng hỗ trợ việc phân bổ từ thẻ SD. Khi có thẻ nhớ, thẻ nhớ sẽ có mức độ ưu tiên cao nhất để phân bổ. Hỗ trợ thẻ SD là yếu tố quan trọng đối với các thiết bị có công suất thấp vì có thể không đủ bộ nhớ trong. Khi có thẻ SD, hãy đảm bảo thẻ đó không được dùng làm bộ nhớ chính. DSU không hỗ trợ thẻ SD được chấp nhận.

Các giao diện người dùng có sẵn

Bạn có thể khởi chạy DSU bằng adb, một ứng dụng OEM hoặc trình tải DSU một lần nhấp (trong Android 11 trở lên).

Khởi chạy DSU bằng adb

Để chạy DSU bằng adb, hãy nhập các lệnh sau:

$ 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

Khởi chạy DSU bằng một ứng dụng

Điểm truy cập chính vào DSU là 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);
    }

Bạn phải gói/cài đặt sẵn ứng dụng này trên thiết bị. Vì DynamicSystemClient là một API hệ thống, nên bạn không thể tạo ứng dụng bằng API SDK thông thường và không thể xuất bản ứng dụng đó trên Google Play. Mục đích của ứng dụng này là:

  1. Tìm nạp danh sách hình ảnh và URL tương ứng bằng một lược đồ do nhà cung cấp xác định.
  2. So khớp các hình ảnh trong danh sách với thiết bị và cho người dùng thấy những hình ảnh tương thích để họ chọn.
  3. Gọi DynamicSystemClient.start như sau:

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

URL này trỏ đến một tệp hình ảnh hệ thống không thưa thớt, được nén bằng gzip mà bạn có thể tạo bằng các lệnh sau:

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

Tên tệp phải tuân theo định dạng sau:

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

Ví dụ:

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

Trình tải DSU một lần nhấp

Android 11 giới thiệu trình tải DSU một lần nhấp, đây là một giao diện người dùng trong phần cài đặt của nhà phát triển.

Khởi chạy trình tải DSU

Hình 1. Khởi chạy trình tải DSU

Khi nhà phát triển nhấp vào nút DSU Loader (Trình tải DSU), nút này sẽ tìm nạp một bộ mô tả JSON DSU được định cấu hình sẵn từ web và hiển thị tất cả hình ảnh có thể áp dụng trong trình đơn nổi. Chọn một hình ảnh để bắt đầu cài đặt DSU và tiến trình sẽ xuất hiện trên thanh thông báo.

Tiến trình cài đặt hình ảnh DSU

Hình 2. Tiến trình cài đặt hình ảnh DSU

Theo mặc định, trình tải DSU sẽ tải một trình mô tả JSON chứa các hình ảnh GSI. Các phần sau đây minh hoạ cách tạo các gói DSU có chữ ký của OEM và tải các gói đó từ trình tải DSU.

Cờ tính năng

Tính năng DSU nằm trong cờ tính năng settings_dynamic_android. Trước khi sử dụng DSU, hãy đảm bảo bạn đã bật cờ tính năng tương ứng.

Bật cờ tính năng.

Hình 3. Bật cờ tính năng

Giao diện người dùng cờ tính năng có thể không hoạt động trên thiết bị chạy bản dựng người dùng. Trong trường hợp này, hãy sử dụng lệnh adb:

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

Hình ảnh hệ thống máy chủ của nhà cung cấp trên GCE (không bắt buộc)

Một trong những vị trí lưu trữ có thể có cho hình ảnh hệ thống là vùng chứa Google Compute Engine (GCE). Quản trị viên phát hành sử dụng bảng điều khiển bộ nhớ GCP để thêm/xoá/thay đổi hình ảnh hệ thống đã phát hành.

Hình ảnh phải có thể truy cập công khai, như minh hoạ ở đây:

Quyền truy cập công khai trong GCE

Hình 4. Quyền truy cập công khai trong GCE

Quy trình công khai một mục có trong tài liệu của Google Cloud.

DSU nhiều phân vùng trong tệp ZIP

Kể từ Android 11, DSU có thể có nhiều phân vùng. Ví dụ: ngoài system.img, nó có thể chứa một product.img. Khi thiết bị khởi động, giai đoạn đầu tiên init sẽ phát hiện các phân vùng DSU đã cài đặt và tạm thời thay thế phân vùng trên thiết bị khi DSU đã cài đặt được bật. Gói DSU có thể chứa một phân vùng không có phân vùng tương ứng trên thiết bị.

Quy trình DSU có nhiều phân vùng

Hình 5. Quy trình DSU có nhiều phân vùng

DSU có chữ ký của OEM

Để đảm bảo tất cả hình ảnh chạy trên thiết bị đều được nhà sản xuất thiết bị cho phép, tất cả hình ảnh trong gói DSU phải được ký. Ví dụ: giả sử có một gói DSU chứa 2 hình ảnh phân vùng như bên dưới:

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

Cả system.imgproduct.img đều phải được khoá OEM ký trước khi được đưa vào tệp ZIP. Thông thường, người ta sẽ dùng một thuật toán bất đối xứng, chẳng hạn như RSA, trong đó khoá bí mật được dùng để ký gói và khoá công khai được dùng để xác minh gói. Ramdisk giai đoạn đầu tiên phải bao gồm khoá công khai ghép nối, ví dụ: /avb/*.avbpubkey. Nếu thiết bị đã áp dụng AVB, thì quy trình ký hiện tại sẽ đủ. Các phần sau đây minh hoạ quy trình ký và làm nổi bật vị trí của khoá công khai AVB dùng để xác minh hình ảnh trong gói DSU.

Trình mô tả JSON DSU

Trình mô tả JSON DSU mô tả các gói DSU. Nền tảng này hỗ trợ 2 nguyên tắc cơ bản. Trước tiên, nguyên tắc cơ bản include bao gồm các nội dung mô tả JSON bổ sung hoặc chuyển hướng trình tải DSU đến một vị trí mới. Ví dụ:

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

Thứ hai, nguyên tắc cơ bản image được dùng để mô tả các gói DSU đã phát hành. Trong phần tử hình ảnh gốc có một số thuộc tính:

  • Thuộc tính namedetails là các chuỗi xuất hiện trên hộp thoại để người dùng chọn.

  • Các thuộc tính cpu_api, vndkos_version được dùng để kiểm tra khả năng tương thích, được mô tả trong phần tiếp theo.

  • Thuộc tính pubkey không bắt buộc mô tả khoá công khai ghép nối với khoá bí mật dùng để ký gói DSU. Khi được chỉ định, dịch vụ DSU có thể kiểm tra xem thiết bị có khoá dùng để xác minh gói DSU hay không. Điều này giúp tránh cài đặt một gói DSU không được nhận dạng, ví dụ: cài đặt một DSU do OEM-A ký vào một thiết bị do OEM-B sản xuất.

  • Thuộc tính tos không bắt buộc trỏ đến một tệp văn bản mô tả các điều khoản dịch vụ cho gói DSU tương ứng. Khi nhà phát triển chọn một gói DSU có thuộc tính điều khoản dịch vụ được chỉ định, hộp thoại xuất hiện trong Hình 6 sẽ mở ra, yêu cầu nhà phát triển chấp nhận điều khoản dịch vụ trước khi cài đặt gói DSU.

    Hộp thoại điều khoản dịch vụ

    Hình 6. Hộp thoại điều khoản dịch vụ

Để tham khảo, sau đây là một bộ mô tả JSON DSU cho 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"
      }
   ]
}

Quản lý khả năng tương thích

Một số thuộc tính được dùng để chỉ định khả năng tương thích giữa gói DSU và thiết bị cục bộ:

  • cpu_api là một chuỗi mô tả cấu trúc thiết bị. Đây là thuộc tính bắt buộc và được so sánh với thuộc tính hệ thống ro.product.cpu.abi. Giá trị của chúng phải khớp chính xác.

  • os_version là một số nguyên không bắt buộc, chỉ định một bản phát hành Android. Ví dụ: đối với Android 10, os_version10 và đối với Android 11, os_version11. Khi được chỉ định, thuộc tính này phải bằng hoặc lớn hơn thuộc tính hệ thống ro.system.build.version.release. Quy trình kiểm tra này được dùng để ngăn việc khởi động hình ảnh GSI Android 10 trên thiết bị của nhà cung cấp Android 11. Hiện tại, quy trình này không được hỗ trợ. Bạn có thể khởi động hình ảnh GSI Android 11 trên thiết bị Android 10.

  • vndk là một mảng không bắt buộc, chỉ định tất cả VNDK có trong gói DSU. Khi được chỉ định, trình tải DSU sẽ kiểm tra xem số được trích xuất từ thuộc tính hệ thống ro.vndk.version có được đưa vào hay không.

Thu hồi khoá DSU để đảm bảo an toàn

Trong trường hợp cực kỳ hiếm khi cặp khoá RSA dùng để ký hình ảnh DSU bị xâm phạm, ramdisk cần được cập nhật càng sớm càng tốt để xoá khoá bị xâm phạm. Ngoài việc cập nhật phân vùng khởi động, bạn có thể chặn các khoá bị xâm nhập bằng danh sách thu hồi khoá DSU (danh sách đen khoá) từ một URL HTTPS.

Danh sách thu hồi khoá DSU chứa danh sách các khoá công khai AVB đã bị thu hồi. Trong quá trình cài đặt DSU, các khoá công khai bên trong hình ảnh DSU sẽ được xác thực bằng danh sách thu hồi. Nếu phát hiện thấy hình ảnh chứa khoá công khai đã thu hồi, quy trình cài đặt DSU sẽ dừng lại.

URL danh sách thu hồi khoá phải là URL HTTPS để đảm bảo độ bảo mật và được chỉ định trong một chuỗi tài nguyên:

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

Giá trị của chuỗi là https://dl.google.com/developers/android/gsi/gsi-keyblacklist.json, đây là danh sách thu hồi cho các khoá GSI do Google phát hành. Chuỗi tài nguyên này có thể được phủ lên và tuỳ chỉnh, để các OEM áp dụng tính năng DSU có thể cung cấp và duy trì danh sách khoá chặn của riêng họ. Điều này giúp OEM chặn một số khoá công khai mà không cần cập nhật hình ảnh ramdisk của thiết bị.

Định dạng của danh sách thu hồi là:

{
   "entries":[
      {
         "public_key":"bf14e439d1acf231095c4109f94f00fc473148e6",
         "status":"REVOKED",
         "reason":"Key revocation test key"
      },
      {
         "public_key":"d199b2f29f3dc224cca778a7544ea89470cbef46",
         "status":"REVOKED",
         "reason":"Key revocation test key"
      }
   ]
}
  • public_key là thuật toán SHA-1 của khoá đã thu hồi, ở định dạng được mô tả trong phần tạo khoá công khai AVB.
  • status cho biết trạng thái thu hồi của khoá. Hiện tại, giá trị duy nhất được hỗ trợ là REVOKED.
  • reason là một chuỗi không bắt buộc, mô tả lý do thu hồi.

Quy trình DSU

Phần này mô tả cách thực hiện một số quy trình định cấu hình DSU.

Tạo một cặp khoá mới

Dùng lệnh openssl để tạo một cặp khoá riêng tư/công khai RSA ở định dạng .pem (ví dụ: có kích thước 2048 bit):

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

Khoá riêng tư có thể không truy cập được và chỉ được lưu trữ trong mô-đun bảo mật phần cứng (HSM). Trong trường hợp này, có thể có một chứng chỉ khoá công khai x509 sau khi tạo khoá. Hãy xem phần Thêm khoá công khai ghép nối vào ramdisk để biết hướng dẫn cách tạo khoá công khai AVB từ chứng chỉ x509.

Cách chuyển đổi chứng chỉ x509 sang định dạng PEM:

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

Bỏ qua bước này nếu chứng chỉ đã là tệp PEM.

Thêm khoá công khai ghép nối vào ramdisk

oem_cert.avbpubkey phải được đặt trong /avb/*.avbpubkey để xác minh gói DSU đã ký. Trước tiên, hãy chuyển đổi khoá công khai ở định dạng PEM sang định dạng khoá công khai AVB:

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

Sau đó, hãy thêm khoá công khai vào ramdisk giai đoạn đầu bằng các bước sau.

  1. Thêm một mô-đun dựng sẵn để sao chép avbpubkey. Ví dụ: thêm device/<company>/<board>/oem_cert.avbpubkeydevice/<company>/<board>/avb/Android.mk có nội dung như sau:

    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. Hãy để mục tiêu droidcore phụ thuộc vào oem_cert.avbpubkey đã thêm:

    droidcore: oem_cert.avbpubkey
    

Tạo thuộc tính khoá công khai AVB trong trình mô tả JSON

oem_cert.avbpubkey ở định dạng nhị phân khoá công khai AVB. Sử dụng SHA-1 để giúp bạn đọc được trước khi đưa vào bộ mô tả JSON:

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

Đây sẽ là nội dung của thuộc tính pubkey trong bộ mô tả JSON.

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

Ký gói DSU

Sử dụng một trong các phương thức sau để ký gói DSU:

  • Phương thức 1: Sử dụng lại cấu phần phần mềm do quy trình ký AVB ban đầu tạo ra để tạo gói DSU. Một cách khác là trích xuất các hình ảnh đã ký từ gói phát hành và dùng các hình ảnh đã trích xuất để tạo trực tiếp tệp ZIP.

  • Phương thức 2: Sử dụng các lệnh sau để ký các phân vùng DSU nếu có khoá riêng tư. Mỗi img trong gói DSU (tệp ZIP) được ký riêng:

    $ 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
    

Để biết thêm thông tin về cách thêm add_hashtree_footer bằng avbtool, hãy xem bài viết Sử dụng avbtool.

Xác minh gói DSU cục bộ

Bạn nên xác minh tất cả hình ảnh cục bộ dựa trên khoá công khai ghép nối bằng các lệnh sau:


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

Kết quả đầu ra dự kiến có dạng như sau:

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

Tạo gói DSU

Ví dụ sau đây tạo một gói DSU chứa system.imgproduct.img:

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

Sau khi cả hai hình ảnh được ký, hãy dùng lệnh sau để tạo tệp ZIP:

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

Tuỳ chỉnh DSU một lần nhấp

Theo mặc định, trình tải DSU sẽ trỏ đến siêu dữ liệu của hình ảnh GSI là https://...google.com/.../gsi-src.json.

Các OEM có thể ghi đè danh sách này bằng cách xác định thuộc tính persist.sys.fflag.override.settings_dynamic_system.list trỏ đến bộ mô tả JSON của riêng họ. Ví dụ: OEM có thể cung cấp siêu dữ liệu JSON bao gồm GSI cũng như hình ảnh độc quyền của OEM như sau:

{
    "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 có thể liên kết siêu dữ liệu DSU đã xuất bản như minh hoạ trong Hình 7.

Chuỗi siêu dữ liệu DSU đã xuất bản

Hình 7. Chuỗi siêu dữ liệu DSU đã xuất bản