Pembaruan Sistem Dinamis (DSU) memungkinkan Anda membuat citra sistem Android yang dapat diunduh pengguna dari internet dan mencobanya tanpa risiko merusak citra sistem saat ini. Dokumen ini menjelaskan cara mendukung DSU.
Persyaratan kernel
Lihat Menerapkan Partisi Dinamis untuk persyaratan kernel.
Selain itu, DSU mengandalkan fitur kernel device-mapper-verity (dm-verity) untuk memverifikasi citra 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 partisi /data
untuk menggunakan sistem file F2FS atau ext4. F2FS memberikan kinerja yang lebih baik dan direkomendasikan, tetapi perbedaannya seharusnya tidak signifikan.
Berikut adalah beberapa contoh waktu yang dibutuhkan pembaruan sistem dinamis dengan perangkat Pixel:
- Menggunakan F2FS:
- 109s, pengguna 8G, sistem 867M, jenis 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, jenis sistem file: ext4: enkripsi=aes-256-xts:aes-256-cts
Jika membutuhkan waktu lebih lama pada platform Anda, Anda mungkin ingin memeriksa apakah flag mount berisi flag yang membuat penulisan “sync”, atau Anda dapat menentukan flag “async” secara eksplisit untuk mendapatkan kinerja yang lebih baik.
Partisi metadata
(16 MB atau lebih besar) diperlukan untuk menyimpan data yang terkait dengan gambar yang diinstal. Itu 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 kernel/common 4.9. Disarankan untuk menggunakan kernel 4.9 dan yang lebih tinggi untuk fitur ini.
Perilaku vendor HAL
Penenun HAL
HAL penenun menyediakan sejumlah slot untuk menyimpan kunci pengguna. DSU menggunakan dua slot kunci tambahan. Jika OEM memiliki HAL penenun, ia harus memiliki slot yang cukup untuk citra sistem generik (GSI) dan citra host.
Penjaga gerbang HAL
Gatekeeper HAL perlu mendukung nilai USER_ID
yang besar, karena GSI mengimbangi UID ke HAL sebesar +1000000.
Verifikasi boot
Jika Anda ingin mendukung booting Gambar GSI Pengembang dalam keadaan TERKUNCI tanpa menonaktifkan boot yang diverifikasi, sertakan kunci GSI Pengembang 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, citra sistem Android yang diunduh harus lebih baru dari citra sistem saat ini di perangkat. Ini dilakukan dengan membandingkan tingkat patch keamanan di deskriptor properti Android Verified Boot (AVB) AVB dari kedua citra sistem: Prop: com.android.build.system.security_patch -> '2019-04-05'
.
Untuk perangkat yang tidak menggunakan AVB, masukkan tingkat patch keamanan dari citra sistem saat ini ke dalam cmdline kernel atau bootconfig dengan bootloader: androidboot.system.security_patch=2019-04-05
.
Persyaratan perangkat keras
Saat Anda meluncurkan instans DSU, dua file sementara dialokasikan:
- Partisi logis untuk menyimpan
GSI.img
(1~1,5 G) - Partisi
/data
kosong 8 GB sebagai kotak pasir untuk menjalankan GSI
Kami merekomendasikan untuk memesan setidaknya 10 GB ruang kosong sebelum meluncurkan instans DSU. DSU juga mendukung alokasi dari kartu SD. Ketika kartu SD hadir, itu memiliki prioritas tertinggi untuk alokasi. Dukungan kartu SD sangat penting untuk perangkat berdaya rendah yang mungkin tidak memiliki cukup penyimpanan internal. Saat kartu SD ada, pastikan itu tidak diadopsi. DSU tidak mendukung kartu SD yang diadopsi .
Frontend yang tersedia
Anda dapat meluncurkan DSU menggunakan adb
, aplikasi OEM, atau pemuat DSU sekali klik (di Android 11 atau lebih tinggi).
Meluncurkan DSU menggunakan adb
Untuk meluncurkan DSU menggunakan adb, masukkan perintah ini:
$ 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 masuk 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 membundel/memprainstal aplikasi ini di perangkat. Karena DynamicSystemClient
adalah API sistem, Anda tidak dapat membuat aplikasi dengan API SDK biasa dan tidak dapat memublikasikannya di Google Play. Tujuan dari 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.
Aktifkan
DynamicSystemClient.start
seperti ini:DynamicSystemClient aot = new DynamicSystemClient(...) aot.start( ...URL of the selected image..., ...uncompressed size of the selected image...);
URL menunjuk ke file gambar sistem yang di-gzip, 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 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
Pemuat DSU sekali klik
Android 11 memperkenalkan pemuat DSU sekali klik, yang merupakan antarmuka di setelan pengembang.
Gambar 1. Meluncurkan pemuat DSU
Saat pengembang mengeklik tombol DSU Loader , ia mengambil deskriptor DSU JSON yang telah dikonfigurasi sebelumnya dari web dan menampilkan semua gambar yang berlaku di menu mengambang. Pilih gambar untuk memulai instalasi DSU, dan kemajuan ditampilkan di bilah notifikasi.
Gambar 2. Kemajuan instalasi gambar DSU
Secara default, pemuat DSU memuat deskriptor JSON yang berisi gambar GSI. Bagian berikut menunjukkan cara membuat paket DSU yang ditandatangani OEM dan memuatnya dari pemuat DSU.
Bendera fitur
Fitur DSU berada di bawah bendera fitur settings_dynamic_android
. Sebelum menggunakan DSU, pastikan tanda fitur yang sesuai diaktifkan.
Gambar 3. Mengaktifkan flag fitur
UI flag fitur mungkin tidak tersedia di perangkat yang menjalankan build pengguna. Dalam hal ini, gunakan perintah adb
sebagai gantinya:
$ adb shell setprop persist.sys.fflag.override.settings_dynamic_system 1
Gambar 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 akses publik, seperti yang ditunjukkan di sini:
Gambar 4. Akses publik di GCE
Prosedur untuk membuat item menjadi publik tersedia di dokumentasi Google Cloud .
DSU multi-partisi dalam file ZIP
Mulai Android 11, DSU dapat memiliki lebih dari satu partisi. Misalnya, dapat berisi product.img
selain system.img
. Saat perangkat melakukan booting, init
tahap pertama mendeteksi partisi DSU yang terinstal dan mengganti partisi di perangkat untuk sementara, saat DSU yang diinstal diaktifkan. Paket DSU mungkin berisi partisi yang tidak memiliki partisi yang sesuai pada perangkat.
Gambar 5. Proses DSU dengan banyak partisi
DSU yang ditandatangani OEM
Untuk memastikan semua gambar yang berjalan pada perangkat diotorisasi oleh produsen perangkat, 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
}
Baik system.img
dan product.img
harus ditandatangani oleh kunci OEM sebelum dimasukkan ke dalam file ZIP. Praktik umum adalah menggunakan algoritma asimetris, misalnya RSA, di mana kunci rahasia digunakan untuk menandatangani paket dan kunci publik digunakan untuk memverifikasinya. Ramdisk tahap pertama harus menyertakan kunci publik pengupas, misalnya /avb/*.avbpubkey
. Jika perangkat sudah mengadopsi AVB, prosedur penandatanganan yang ada sudah cukup. Bagian berikut mengilustrasikan proses penandatanganan dan menyoroti penempatan kunci pub AVB yang digunakan untuk memverifikasi gambar dalam paket DSU.
Deskriptor DSU JSON
Deskriptor DSU JSON menjelaskan paket DSU. Ini mendukung dua primitif. Pertama, include
primitif menyertakan deskriptor JSON tambahan atau mengalihkan pemuat DSU ke lokasi baru. Sebagai contoh:
{
"include": ["https://.../gsi-release/gsi-src.json"]
}
Kedua, image
primitif digunakan untuk menggambarkan paket DSU yang dirilis. Di dalam gambar primitif ada beberapa atribut:
Atribut
name
dandetails
adalah string yang ditampilkan pada dialog untuk dipilih pengguna.cpu_api
,vndk
, danos_version
digunakan untuk pemeriksaan kompatibilitas, yang akan dijelaskan di bagian berikutnya.Atribut
pubkey
opsional menjelaskan kunci 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. 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 menunjuk ke file teks yang menjelaskan persyaratan layanan untuk paket DSU terkait. Ketika pengembang memilih paket DSU dengan persyaratan atribut layanan yang ditentukan, kotak dialog yang ditunjukkan pada Gambar 6 terbuka, meminta pengembang untuk menerima persyaratan layanan sebelum menginstal paket DSU.Gambar 6. Kotak dialog persyaratan layanan
Untuk referensi, inilah deskriptor DSU JSON 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"
}
]
}
Manajemen kompatibilitas
Beberapa atribut digunakan untuk menentukan kompatibilitas antara paket DSU dan perangkat lokal:
cpu_api
adalah string yang menjelaskan arsitektur perangkat. Atribut ini wajib dan dibandingkan dengan properti sistemro.product.cpu.abi
. Nilai-nilai mereka harus sama persis.os_version
adalah bilangan bulat opsional yang menentukan rilis Android. Misalnya, untuk Android 10,os_version
adalah10
dan untuk Android 11,os_version
adalah11
. Ketika atribut ini ditentukan, itu harus sama dengan atau lebih besar dari properti sistemro.system.build.version.release
. Pemeriksaan ini digunakan untuk mencegah booting image Android 10 GSI pada perangkat vendor Android 11, yang saat ini tidak didukung. Mem-boot image Android 11 GSI pada perangkat Android 10 diperbolehkan.vndk
adalah larik opsional yang menentukan semua VNDK yang disertakan dalam paket DSU. Saat ditentukan, pemuat DSU memeriksa apakah nomor yang diekstrak dari properti sistemro.vndk.version
disertakan.
Mencabut kunci DSU untuk keamanan
Dalam kasus yang sangat jarang terjadi ketika pasangan kunci RSA yang digunakan untuk menandatangani gambar DSU disusupi, ramdisk harus diperbarui sesegera mungkin untuk menghapus kunci yang disusupi. Selain memperbarui partisi boot, Anda dapat memblokir kunci yang disusupi menggunakan daftar pencabutan kunci DSU (daftar hitam kunci) dari URL HTTPS.
Daftar pencabutan kunci DSU berisi daftar kunci publik AVB yang dicabut. Selama instalasi DSU, kunci publik di dalam gambar DSU divalidasi dengan daftar pencabutan. Jika gambar ditemukan berisi kunci publik yang dicabut, proses penginstalan DSU berhenti.
URL daftar pencabutan kunci harus berupa URL HTTPS untuk memastikan kekuatan keamanan, dan ditentukan dalam string sumber daya:
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 Google. String sumber daya ini dapat dilapis dan dikustomisasi, sehingga OEM yang mengadopsi fitur DSU dapat menyediakan dan memelihara daftar hitam kunci mereka sendiri. Ini menyediakan cara bagi OEM untuk memblokir kunci publik tertentu tanpa memperbarui gambar ramdisk 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 intisari SHA-1 dari kunci yang dicabut, dalam format yang dijelaskan di bagian pembuatan pubkey AVB . -
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.
Menghasilkan pasangan kunci baru
Gunakan perintah openssl
untuk menghasilkan pasangan kunci privat/publik 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 dalam modul keamanan perangkat keras (HSM) . Dalam hal ini, mungkin ada sertifikat kunci publik x509 yang tersedia setelah pembuatan kunci. Lihat bagian Menambahkan pubkey pasangan ke ramdisk untuk petunjuk membuat 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 menjadi file PEM.
Menambahkan pubkey pasangan ke ramdisk
oem_cert.avbpubkey
harus diletakkan di bawah /avb/*.avbpubkey
untuk memverifikasi paket DSU yang ditandatangani. Pertama, konversi kunci publik dalam format PEM ke format kunci publik AVB:
$ avbtool extract_public_key --key oem_cert_pub.pem --output oem_cert.avbpubkey
Kemudian masukkan kunci publik di 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)
Jadikan target droidcore bergantung pada
oem_cert.avbpubkey
yang ditambahkan:droidcore: oem_cert.avbpubkey
Membuat atribut pubkey AVB di deskriptor JSON
oem_cert.avbpubkey
dalam format biner kunci publik AVB. Gunakan SHA-1 untuk membuatnya dapat dibaca sebelum memasukkannya ke dalam deskriptor JSON:
$ sha1sum oem_cert.avbpubkey | cut -f1 -d ' '
3e62f2be9d9d813ef5........866ac72a51fd20
Ini akan menjadi konten atribut pubkey
dari deskriptor 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 alternatif adalah mengekstrak gambar yang sudah ditandatangani dari paket rilis dan menggunakan gambar yang diekstraksi untuk membuat file ZIP secara langsung.
Metode 2: Gunakan perintah berikut untuk menandatangani partisi DSU jika kunci pribadi 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
Disarankan untuk memverifikasi semua gambar lokal terhadap kunci publik yang dipasangkan dengan perintah berikut:
for partition in system product; do
avbtool verify_image --image ${OUT}/${partition}.img --key oem_cert_pub.pem
done
Output yang diharapkan 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, pemuat DSU menunjuk ke metadata gambar GSI yaitu https://...google.com/.../gsi-src.json
.
OEM dapat menimpa daftar dengan mendefinisikan properti persist.sys.fflag.override.settings_dynamic_system.list
yang menunjuk ke deskriptor JSON mereka sendiri. Misalnya, OEM dapat menyediakan metadata JSON yang menyertakan GSI serta gambar milik 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"
},
}
Mungkin bagi OEM untuk merantai metadata DSU yang dipublikasikan seperti yang ditunjukkan pada Gambar 7.
Gambar 7. Merangkai metadata DSU yang diterbitkan