Dynamic System Updates

{i>Dynamic System Updates<i} (DSU) memungkinkan Anda membuat {i>image<i} sistem Android yang pengguna dapat mengunduh dari internet dan mencoba tanpa risiko merusak image sistem saat ini. Dokumen ini menjelaskan cara mendukung DSU.

Persyaratan kernel

Lihat Mengimplementasikan Partisi Dinamis untuk persyaratan {i>kernel<i}.

Selain itu, DSU bergantung pada fitur kernel device-mapper-verity (dm-verity) untuk memverifikasi image sistem Android. Jadi, Anda harus mengaktifkan konfigurasi kernel berikut:

  • CONFIG_DM_VERITY=y
  • CONFIG_DM_VERITY_FEC=y

Persyaratan partisi

Mulai Android 11, DSU memerlukan /data partisi untuk menggunakan sistem file F2FS atau ext4. F2FS memberikan performa yang lebih baik dan direkomendasikan, tetapi perbedaannya tidak signifikan.

Berikut adalah beberapa contoh durasi update sistem dinamis dengan perangkat Pixel:

  • Menggunakan F2FS:
    • 109s, pengguna 8G, sistem 867M, tipe sistem file: F2FS: enkripsi=aes-256-xts:aes-256-cts
    • 104s, pengguna 8G, sistem 867M, tipe sistem file: F2FS: encryption=es
  • Menggunakan ext4:
    • 135 detik, pengguna 8 G, sistem 867 M, jenis sistem file: ext4: encryption=aes-256-xts:aes-256-cts

Jika memerlukan waktu yang jauh lebih lama di platform Anda, sebaiknya periksa apakah flag mount berisi flag yang membuat penulisan “sinkron”, atau Anda dapat menentukan flag “asinkron” secara eksplisit untuk mendapatkan performa yang lebih baik.

Partisi metadata (16 MB atau lebih besar) diperlukan untuk menyimpan data terkait ke image yang diinstal. Kunci ini harus dipasang selama pemasangan tahap pertama.

Partisi userdata harus menggunakan sistem file F2FS atau ext4. Saat menggunakan F2FS, sertakan semua patch terkait F2FS yang tersedia di kernel umum Android.

DSU dikembangkan dan diuji dengan {i>kernel<i}/umum 4.9. Disarankan untuk menggunakan {i>kernel<i} 4.9 dan yang lebih tinggi untuk fitur ini.

Perilaku HAL vendor

Weaver HAL

Weaver HAL menyediakan slot dalam jumlah tetap untuk menyimpan kunci pengguna. DSU menggunakan dua slot kunci tambahan. Jika OEM memiliki HAL penenun, ia harus memiliki slot yang cukup untuk {i>Generic System Image<i} (GSI) dan {i>host image<i}.

Penjaga Gerbang HAL

Gatekeeper HAL perlu mendukung nilai USER_ID yang besar, karena GSI mengimbangi UID ke HAL dengan +1000000.

Memverifikasi booting

Jika Anda ingin mendukung booting Image GSI Developer dalam status TERKUNCI tanpa menonaktifkan booting terverifikasi, termasuk kunci GSI Developer dengan menambahkan baris berikut ke file device/<device_name>/device.mk:

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

Perlindungan rollback

Saat menggunakan DSU, image sistem Android yang didownload harus lebih baru dari image sistem saat ini di perangkat. Hal ini dilakukan dengan membandingkan patch keamanan level di Booting Terverifikasi Android (AVB) Deskripsi properti AVB dari kedua image sistem: Prop: com.android.build.system.security_patch -> '2019-04-05'.

Untuk perangkat yang tidak menggunakan AVB, masukkan level patch keamanan image sistem saat ini ke cmdline kernel atau bootconfig dengan bootloader: androidboot.system.security_patch=2019-04-05.

Persyaratan hardware

Saat Anda meluncurkan instance DSU, dua file sementara akan dialokasikan:

  • Partisi logis untuk menyimpan GSI.img (1~1,5 G)
  • Partisi /data kosong 8 GB sebagai sandbox untuk menjalankan GSI

Sebaiknya kosongkan setidaknya 10 GB ruang kosong sebelum meluncurkan DSU di instance Compute Engine. DSU juga mendukung alokasi dari kartu SD. Jika ada, kartu SD memiliki prioritas tertinggi untuk alokasi. Dukungan kartu SD adalah sangat penting untuk perangkat berdaya rendah yang mungkin tidak memiliki penyimpanan internal yang cukup. Jika ada kartu SD, pastikan kartu tersebut tidak diadopsi. DSU tidak mendukung kartu SD yang diadopsi.

Frontend yang tersedia

Anda dapat meluncurkan DSU menggunakan adb, aplikasi OEM, atau loader DSU sekali klik (di Android 11 atau yang lebih tinggi).

Meluncurkan DSU menggunakan adb

Untuk meluncurkan DSU menggunakan adb, masukkan perintah berikut:

$ 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

Meluncurkan DSU menggunakan aplikasi

Titik entri utama ke DSU adalah 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);
    }

Anda harus memaketkan/pramenginstal aplikasi ini di perangkat. Karena DynamicSystemClient adalah API sistem, Anda tidak dapat mem-build aplikasi dengan SDK API reguler dan tidak dapat memublikasikannya di Google Play. Tujuan aplikasi ini adalah:

  1. Mengambil daftar gambar dan URL yang sesuai dengan skema yang ditentukan vendor.
  2. Cocokkan gambar dalam daftar dengan perangkat dan tampilkan gambar yang kompatibel untuk dipilih pengguna.
  3. Panggil DynamicSystemClient.start seperti ini:

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

URL mengarah ke file image sistem yang di-gzip dan tidak jarang, yang dapat Anda buat dengan perintah berikut:

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

Nama file harus mengikuti format berikut:

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

Contoh:

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

Loader DSU sekali klik

Android 11 memperkenalkan loader DSU sekali klik, yang adalah frontend di setelan developer.

Meluncurkan loader DSU

Gambar 1. Meluncurkan loader DSU

Saat developer mengklik tombol DSU Loader, tombol tersebut akan mengambil deskripsi JSON DSU yang telah dikonfigurasi sebelumnya dari web dan menampilkan semua gambar yang berlaku di menu mengambang. Pilih image untuk memulai penginstalan DSU, dan progres akan ditampilkan di panel notifikasi.

Progres penginstalan image DSU

Gambar 2. Progres penginstalan image DSU

Secara default, loader DSU memuat deskriptor JSON yang berisi image GSI. Bagian berikut menunjukkan cara membuat paket DSU yang ditandatangani OEM dan memuatnya dari loader DSU.

Tombol fitur

Fitur DSU berada di bawah tombol fitur settings_dynamic_android. Sebelum menggunakan DSU, pastikan tombol fitur yang sesuai telah diaktifkan.

Mengaktifkan tombol fitur.

Gambar 3. Mengaktifkan tombol fitur

UI tombol fitur mungkin tidak tersedia di perangkat yang menjalankan build pengguna. Dalam hal ini, gunakan perintah adb:

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

Image sistem host vendor di GCE (opsional)

Salah satu kemungkinan lokasi penyimpanan untuk image sistem adalah bucket Google Compute Engine (GCE). Administrator rilis menggunakan konsol penyimpanan GCP untuk menambahkan/menghapus/mengubah image sistem yang dirilis.

Gambar harus memiliki akses publik, seperti yang ditunjukkan di sini:

Akses publik di GCE

Gambar 4. Akses publik di GCE

Prosedur untuk membuat item menjadi publik tersedia di Dokumentasi Google Cloud.

DSU beberapa partisi dalam file ZIP

Mulai Android 11, DSU dapat memiliki lebih dari satu partisi. Misalnya, class ini dapat berisi product.img selain system.img. Saat perangkat melakukan booting, tahap pertama init mendeteksi menginstal partisi DSU dan menggantikan partisi pada perangkat untuk sementara, ketika DSU yang diinstal diaktifkan. Paket DSU mungkin berisi partisi yang tidak memiliki partisi yang sesuai di perangkat.

Proses DSU dengan beberapa partisi

Gambar 5. Proses DSU dengan beberapa partisi

DSU yang ditandatangani OEM

Untuk memastikan semua image yang berjalan di perangkat diizinkan oleh perangkat produsen, semua gambar dalam paket DSU harus ditandatangani. Misalnya, asumsikan ada paket DSU yang berisi dua gambar partisi seperti di bawah ini:

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

system.img dan product.img harus ditandatangani oleh kunci OEM sebelum yang dimasukkan ke dalam file ZIP. Praktik umum adalah menggunakan algoritma asimetris, misalnya, RSA, dengan kunci rahasia digunakan untuk menandatangani paket dan kunci publik digunakan untuk memverifikasinya. Ramdisk tahap pertama harus menyertakan proses paring kunci publik, misalnya, /avb/*.avbpubkey. Jika perangkat sudah mengadopsi AVB, prosedur penandatanganan yang ada sudah cukup. Bagian berikut mengilustrasikan proses penandatanganan dan menyoroti penempatan kunci publik AVB yang digunakan untuk memverifikasi image dalam paket DSU.

Deskripsi JSON DSU

Deskripsi JSON DSU menjelaskan paket DSU. Library ini mendukung dua primitif. Pertama, primitif include menyertakan deskripsi atau pengalihan JSON tambahan loader DSU ke lokasi baru. Contoh:

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

Kedua, primitif image digunakan untuk mendeskripsikan paket DSU yang dirilis. Di dalam primitif gambar, ada beberapa atribut:

  • Atribut name dan details adalah string yang ditampilkan di dialog untuk dipilih pengguna.

  • Atribut cpu_api, vndk, dan os_version digunakan untuk pemeriksaan kompatibilitas, yang dijelaskan di bagian berikutnya.

  • Atribut pubkey opsional mendeskripsikan informasi publik yang berpasangan dengan kunci rahasia yang digunakan untuk menandatangani paket DSU. Jika ditentukan, layanan DSU dapat memeriksa apakah perangkat memiliki kunci yang digunakan untuk memverifikasi paket DSU. Tindakan ini menghindari penginstalan paket DSU yang tidak dikenal, misalnya menginstal DSU yang ditandatangani oleh OEM-A ke perangkat yang dibuat oleh OEM-B.

  • Atribut tos opsional mengarah ke file teks yang menjelaskan persyaratan layanan untuk paket DSU yang sesuai. Saat developer memilih paket DSU dengan atribut persyaratan layanan yang ditentukan, kotak dialog yang ditampilkan pada Gambar 6 akan terbuka, meminta developer untuk menyetujui persyaratan layanan sebelum menginstal paket DSU.

    Kotak dialog persyaratan layanan

    Gambar 6. Kotak dialog persyaratan layanan

Sebagai referensi, berikut adalah deskriptor JSON DSU untuk 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"
      }
   ]
}

Pengelolaan kompatibilitas

Beberapa atribut digunakan untuk menentukan kompatibilitas antara paket DSU dan perangkat lokal:

  • cpu_api adalah string yang mendeskripsikan arsitektur perangkat. Atribut ini bersifat wajib dan dibandingkan dengan properti sistem ro.product.cpu.abi. Nilainya harus sama persis.

  • os_version adalah bilangan bulat opsional yang menentukan rilis Android. Misalnya, untuk Android 10, os_version adalah 10 dan untuk Android 11, os_version adalah 11. Jika ditentukan, atribut ini harus sama dengan atau lebih besar dari ro.system.build.version.release properti sistem. Pemeriksaan ini digunakan untuk mencegah booting image GSI Android 10 di perangkat vendor Android 11, yang saat ini tidak didukung. Mem-booting image GSI Android 11 di perangkat Android 10 diizinkan.

  • vndk adalah array opsional yang menentukan semua VNDK yang disertakan dalam paket DSU. Bila ditentukan, loader DSU akan memeriksa apakah nomor yang diekstrak dari properti sistem ro.vndk.version disertakan.

Cabut kunci DSU untuk keamanan

Dalam kasus yang sangat jarang terjadi, ketika pasangan kunci RSA yang digunakan untuk menandatangani image DSU disusupi, {i>ramdisk<i} harus segera diperbarui untuk menghapus kunci yang tersusupi. Selain memperbarui partisi {i>boot<i}, Anda dapat memblokir kunci yang disusupi menggunakan daftar pencabutan kunci DSU (daftar kunci yang tidak diizinkan) dari HTTPS .

Daftar pencabutan kunci DSU berisi daftar kunci publik AVB yang dicabut. Selama penginstalan DSU, kunci publik di dalam image DSU divalidasi dengan daftar pencabutan. Jika image ditemukan berisi kunci publik yang dicabut, proses penginstalan DSU akan berhenti.

URL daftar pencabutan kunci harus berupa URL HTTPS untuk memastikan keamanan kekuatannya, dan ditetapkan dalam string resource:

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

Nilai string adalah https://dl.google.com/developers/android/gsi/gsi-keyblacklist.json, yang merupakan daftar pencabutan untuk kunci GSI yang dirilis oleh Google. String resource ini dapat berupa dan disesuaikan, sehingga OEM yang mengadopsi fitur DSU dapat menyediakan dan mempertahankan daftar hitam kunci mereka sendiri. Hal ini memungkinkan OEM untuk memblokir kunci publik tertentu tanpa memperbarui {i>ramdisk image<i} perangkat.

Format daftar pencabutan adalah:

{
   "entries":[
      {
         "public_key":"bf14e439d1acf231095c4109f94f00fc473148e6",
         "status":"REVOKED",
         "reason":"Key revocation test key"
      },
      {
         "public_key":"d199b2f29f3dc224cca778a7544ea89470cbef46",
         "status":"REVOKED",
         "reason":"Key revocation test key"
      }
   ]
}
  • public_key adalah ringkasan SHA-1 dari kunci yang dicabut, dalam format yang dijelaskan di bagian membuat kunci publik AVB.
  • status menunjukkan status pencabutan kunci. Saat ini, satu-satunya nilai yang didukung adalah REVOKED.
  • reason adalah string opsional yang menjelaskan alasan pencabutan.

Prosedur DSU

Bagian ini menjelaskan cara melakukan beberapa prosedur konfigurasi DSU.

Membuat pasangan kunci baru

Gunakan perintah openssl untuk membuat pasangan kunci publik/pribadi RSA dalam format .pem (misalnya, dengan ukuran 2048 bit):

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

Kunci pribadi mungkin tidak dapat diakses dan hanya disimpan di modul keamanan hardware (HSM). Dalam hal ini, mungkin ada sertifikat kunci publik x509 yang tersedia setelah pembuatan kunci. Lihat Menambahkan pubkey penyambungan ke ramdisk untuk petunjuk cara menghasilkan kunci publik AVB dari sertifikat x509.

Untuk mengonversi sertifikat x509 ke format PEM:

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

Lewati langkah ini jika sertifikat sudah berupa file PEM.

Menambahkan kunci publik penyambungan ke ramdisk

oem_cert.avbpubkey harus ditempatkan di bawah /avb/*.avbpubkey untuk memverifikasi paket DSU yang ditandatangani. Pertama, konversikan kunci publik dalam format PEM ke format kunci publik AVB:

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

Kemudian sertakan kunci publik dalam ramdisk tahap pertama dengan langkah-langkah berikut.

  1. Tambahkan modul bawaan untuk menyalin avbpubkey. Misalnya, tambahkan device/<company>/<board>/oem_cert.avbpubkey dan device/<company>/<board>/avb/Android.mk dengan konten seperti ini:

    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. Buat target droidcore bergantung pada oem_cert.avbpubkey yang ditambahkan:

    droidcore: oem_cert.avbpubkey
    

Membuat atribut kunci publik AVB dalam deskripsi JSON

oem_cert.avbpubkey dalam format biner kunci publik AVB. Gunakan SHA-1 untuk membuatnya dapat dibaca sebelum memasukkannya ke dalam deskripsi JSON:

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

Ini akan menjadi konten atribut pubkey deskripsi JSON.

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

Menandatangani paket DSU

Gunakan salah satu metode berikut untuk menandatangani paket DSU:

  • Metode 1: Gunakan kembali artefak yang dibuat oleh proses penandatanganan AVB asli untuk membuat paket DSU. Pendekatan alternatifnya adalah dengan mengekstrak data yang sudah ditandatangani image dari paket rilis dan menggunakan image yang diekstrak untuk membuat ZIP file secara langsung.

  • Metode 2: Gunakan perintah berikut untuk menandatangani partisi DSU jika tersedia. Setiap img dalam paket DSU (file ZIP) ditandatangani secara terpisah:

    $ 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
    

Untuk mengetahui informasi selengkapnya tentang menambahkan add_hashtree_footer menggunakan avbtool, lihat Menggunakan avbtool.

Memverifikasi paket DSU secara lokal

Sebaiknya verifikasi semua image lokal terhadap pasangan kunci publik perintah berikut:


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

Output yang diinginkan akan terlihat seperti ini:

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

Membuat paket DSU

Contoh berikut membuat paket DSU yang berisi system.img dan product.img:

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

Setelah kedua gambar ditandatangani, gunakan perintah berikut untuk membuat file ZIP:

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

Menyesuaikan DSU sekali klik

Secara default, loader DSU mengarah ke metadata image GSI yang https://...google.com/.../gsi-src.json.

OEM dapat menimpa daftar dengan menentukan properti persist.sys.fflag.override.settings_dynamic_system.list yang mengarah ke deskripsi JSON mereka sendiri. Misalnya, OEM dapat memberikan metadata JSON yang menyertakan GSI serta image eksklusif OEM seperti ini:

{
    "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 dapat membuat rantai metadata DSU yang dipublikasikan seperti yang ditunjukkan pada Gambar 7.

Membuat rantai metadata DSU yang dipublikasikan

Gambar 7. Membuat rantai metadata DSU yang dipublikasikan