{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 kernel berikut konfigurasi:
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 kinerja yang lebih baik dan
disarankan, namun selisihnya harus tidak signifikan.
Berikut beberapa contoh durasi update sistem dinamis dengan Pixel perangkat:
- 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: enkripsi=es
- Menggunakan ext4:
- 135s, pengguna 8G, sistem 867M, tipe sistem file: ext4: enkripsi=aes-256-xts:aes-256-cts
Jika memakan waktu lebih lama di platform Anda, sebaiknya periksa apakah dudukan berisi flag apa pun yang membuat penulisan "sync", atau Anda dapat menentukan penanda "async" secara eksplisit untuk mendapatkan kinerja 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,
mencakup semua {i>patch<i} 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 meng-offset UID ke HAL dengan
+1000000.
Verifikasi 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
{i>image<i} sistem saat ini
pada 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 sistem saat ini
ke kernel cmdline 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. Ketika kartu SD ada, instance tersebut memiliki prioritas tertinggi untuk alokasi. Dukungan kartu SD adalah sangat penting untuk perangkat dengan daya rendah yang mungkin tidak memiliki penyimpanan internal yang cukup. Jika kartu SD tersedia, pastikan kartu tersebut tidak digunakan. DSU tidak mendukung kartu SD yang digunakan.
Frontend yang tersedia
Anda dapat meluncurkan DSU menggunakan adb
, aplikasi OEM, atau loader DSU sekali klik (di
Android 11 atau yang lebih baru).
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/melakukan prainstal aplikasi ini di perangkat. Karena
DynamicSystemClient
adalah API sistem, Anda tidak dapat membangun aplikasi dengan
SDK API dan Anda tidak dapat memublikasikannya di Google Play. Tujuan aplikasi ini adalah:
- Ambil daftar gambar dan URL yang sesuai dengan skema yang ditentukan vendor.
- Cocokkan gambar dalam daftar dengan perangkat dan tampilkan gambar yang kompatibel untuk dipilih pengguna.
Panggil
DynamicSystemClient.start
seperti ini:DynamicSystemClient aot = new DynamicSystemClient(...) aot.start( ...URL of the selected image..., ...uncompressed size of the selected image...);
URL-nya mengarah ke file gambar sistem yang di-gzip, tidak tersebar, dan 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 ini:
<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.
Gambar 1. Meluncurkan loader DSU
Saat mengklik tombol DSU Loader, developer akan mengambil file DSU JSON dari web dan menampilkan semua gambar yang relevan menu mengambang. Pilih image untuk memulai penginstalan DSU, dan progresnya yang ditampilkan di bilah notifikasi.
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 memuat mereka dari loader DSU.
Tombol fitur
Fitur DSU berada di bawah tombol fitur settings_dynamic_android
. Sebelum pembaruan
menggunakan DSU, pastikan penanda fitur yang sesuai diaktifkan.
Gambar 3. Mengaktifkan tombol fitur
UI tombol fitur mungkin tidak tersedia di perangkat yang menjalankan build pengguna. Di beberapa
dalam hal ini, gunakan perintah adb
sebagai gantinya:
$ adb shell setprop persist.sys.fflag.override.settings_dynamic_system 1
Image sistem host vendor di GCE (opsional)
Salah satu kemungkinan lokasi penyimpanan image sistem adalah Google Bucket Compute Engine (GCE). Administrator rilis menggunakan GCP Storage Console untuk tambahkan/hapus/ubah image sistem yang dirilis.
Image harus dapat diakses oleh publik, seperti yang ditunjukkan di sini:
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 dapat berisi
partisi yang tidak
memiliki partisi yang
sesuai di perangkat.
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 yang umum adalah
menggunakan model asimetris
algoritma, misalnya RSA, di mana 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. Bagian berikut menggambarkan
proses penandatanganan dan menyoroti penempatan pubkey AVB yang digunakan untuk
memverifikasi image dalam paket DSU.
Deskripsi JSON DSU
Deskriptor 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 menjelaskan paket DSU yang dirilis. Di dalam
terdapat beberapa atribut dalam primitif gambar:
Atribut
name
dandetails
adalah string yang ditampilkan pada dialog yang dapat dipilih pengguna.Atribut
cpu_api
,vndk
, danos_version
digunakan untuk pemeriksaan kompatibilitas mundur, yang akan 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 akan menghindari penginstalan 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 mendeskripsikan persyaratan layanan untuk paket DSU yang sesuai. Ketika developer memilih paket DSU dengan atribut ketentuan layanan yang ditentukan, metode kotak dialog yang ditampilkan pada Gambar 6 akan terbuka, yang meminta developer untuk menyetujui persyaratan sebelum menginstal paket DSU.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 sistemro.product.cpu.abi
. Nilainya harus sama persis.os_version
adalah bilangan bulat opsional yang menentukan rilis Android. Sebagai misalnya, untuk Android 10,os_version
adalah10
dan untuk Android 11,os_version
adalah11
. Jika ditentukan, atribut ini harus sama dengan atau lebih besar dariro.system.build.version.release
properti sistem. Pemeriksaan ini digunakan untuk mencegah booting image GSI Android 10 di Android 11 vendor, 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 sistemro.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 gambar didapati berisi status publik yang dicabut kunci, proses instalasi 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
gambar {i>ramdisk<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 pembuatan pubkey AVB bagian.status
menunjukkan status pencabutan kunci. Saat ini, satu-satunya nilai yang didukung adalahREVOKED
.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 pribadi/publik RSA di .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 {i>public key certificate x509<i} yang tersedia setelah kunci pembuatan teks. 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 pubkey 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 menjadi publik AVB
format kunci:
$ 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.
Tambahkan modul bawaan untuk menyalin
avbpubkey
. Misalnya, tambahkandevice/<company>/<board>/oem_cert.avbpubkey
dandevice/<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)
Buat target droidcore bergantung pada
oem_cert.avbpubkey
yang ditambahkan:droidcore: oem_cert.avbpubkey
Membuat atribut pubkey AVB di deskripsi JSON
oem_cert.avbpubkey
dalam format biner kunci publik AVB. Gunakan SHA-1 untuk
membuatnya dapat dibaca sebelum memasukkannya ke deskriptor 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 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 informasi selengkapnya tentang menambahkan add_hashtree_footer
menggunakan avbtool
, lihat
Menggunakan avbtool.
Memverifikasi paket DSU secara lokal
Sebaiknya verifikasi semua {i> image <i}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 tersebut dengan menentukan persist.sys.fflag.override.settings_dynamic_system.list
yang mengarah ke deskriptor JSON-nya sendiri. Misalnya, OEM mungkin
menyediakan 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 merangkai metadata DSU yang dipublikasikan seperti yang ditunjukkan pada Gambar 7.
Gambar 7. Membuat rantai metadata DSU yang dipublikasikan