Pembaruan Sistem Dinamis (DSU) memungkinkan Anda membuat image sistem Android yang dapat diunduh pengguna dari internet dan dicoba tanpa risiko merusak image 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 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 partisi /data
untuk menggunakan sistem file F2FS atau ext4. F2FS memberikan kinerja yang lebih baik dan direkomendasikan, namun perbedaannya tidak signifikan.
Berikut ini beberapa contoh berapa lama waktu yang dibutuhkan untuk melakukan update sistem dinamis pada 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: enkripsi=ice
- Menggunakan ext4:
- 135s, pengguna 8G, sistem 867M, tipe sistem file: ext4: enkripsi=aes-256-xts:aes-256-cts
Jika platform Anda memerlukan waktu lebih lama, Anda mungkin ingin memeriksa apakah flag mount berisi flag yang membuat "sinkronisasi" ditulis, atau Anda dapat menentukan flag "async" secara eksplisit untuk mendapatkan performa yang lebih baik.
Partisi metadata
(16 MB atau lebih besar) diperlukan untuk menyimpan data terkait gambar yang diinstal. Itu harus dipasang pada tahap pertama pemasangan.
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 lebih tinggi untuk fitur ini.
Perilaku vendor HAL
Penenun HAL
Weaver HAL menyediakan sejumlah slot untuk menyimpan kunci pengguna. DSU menggunakan dua slot kunci tambahan. Jika OEM memiliki weaver HAL, OEM tersebut harus memiliki slot yang cukup untuk image sistem generik (GSI) dan image host.
Penjaga gerbang HAL
HAL Gatekeeper perlu mendukung nilai USER_ID
yang besar, karena GSI mengimbangi UID ke HAL sebesar +1000000.
Verifikasi booting
Jika Anda ingin mendukung booting Gambar GSI Pengembang dalam keadaan TERKUNCI tanpa menonaktifkan boot terverifikasi, 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 kemunduran
Saat menggunakan DSU, image sistem Android yang diunduh harus lebih baru dari image sistem saat ini di perangkat. Hal ini dilakukan dengan membandingkan tingkat patch keamanan di deskriptor properti AVB Boot Terverifikasi Android (AVB) dari kedua image sistem: Prop: com.android.build.system.security_patch -> '2019-04-05'
.
Untuk perangkat yang tidak menggunakan AVB, masukkan tingkat patch keamanan image sistem saat ini ke 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 sebesar 8 GB sebagai sandbox untuk menjalankan GSI
Kami merekomendasikan untuk mencadangkan setidaknya 10 GB ruang kosong sebelum meluncurkan instans DSU. DSU juga mendukung alokasi dari kartu SD. Jika ada kartu SD, maka kartu tersebut memiliki prioritas tertinggi untuk alokasinya. Dukungan kartu SD sangat penting untuk perangkat berdaya rendah yang mungkin tidak memiliki cukup penyimpanan internal. 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 pemuat DSU sekali klik (di Android 11 atau lebih tinggi).
Luncurkan 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
Luncurkan 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 menggabungkan/memasang awal aplikasi ini pada perangkat. Karena DynamicSystemClient
adalah API sistem, Anda tidak dapat membuat aplikasi dengan API SDK reguler 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.
Panggil
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 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 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 frontend dalam pengaturan pengembang.
Gambar 1. Meluncurkan pemuat DSU
Saat pengembang mengklik 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 kemajuannya ditampilkan di bilah notifikasi.
Gambar 2. Kemajuan instalasi image DSU
Secara default, pemuat DSU memuat deskriptor JSON yang berisi gambar GSI. Bagian berikut menunjukkan cara membuat paket DSU bertanda OEM dan memuatnya dari DSU loader.
Bendera fitur
Fitur DSU berada di bawah tanda fitur settings_dynamic_android
. Sebelum menggunakan DSU, pastikan tanda fitur terkait diaktifkan.
Gambar 3. Mengaktifkan fitur flag
UI tanda fitur mungkin tidak tersedia pada perangkat yang menjalankan build pengguna. 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 untuk citra sistem adalah bucket Google Compute Engine (GCE). Administrator rilis menggunakan konsol penyimpanan GCP untuk menambah/menghapus/mengubah image sistem yang dirilis.
Gambar harus dapat diakses publik, seperti yang ditunjukkan di sini:
Gambar 4. Akses publik di GCE
Prosedur untuk menjadikan suatu item bersifat 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, tahap pertama init
mendeteksi partisi DSU yang diinstal dan menggantikan partisi pada perangkat untuk sementara, ketika DSU yang diinstal diaktifkan. Paket DSU mungkin berisi partisi yang tidak memiliki partisi terkait pada perangkat.
Gambar 5. Proses DSU dengan banyak partisi
DSU bertanda tangan OEM
Untuk memastikan semua gambar yang berjalan di perangkat disahkan 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
}
system.img
dan product.img
harus ditandatangani dengan kunci OEM sebelum dimasukkan ke dalam file ZIP. Praktik yang 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. Misalnya:
{
"include": ["https://.../gsi-release/gsi-src.json"]
}
Kedua, image
primitif digunakan untuk mendeskripsikan paket DSU yang dirilis. Di dalam gambar primitif terdapat beberapa atribut:
Atribut
name
dandetails
adalah string yang ditampilkan pada dialog untuk dipilih pengguna.Atribut
cpu_api
,vndk
, danos_version
digunakan untuk pemeriksaan kompatibilitas, yang 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. Hal ini untuk menghindari pemasangan paket DSU yang tidak dikenal, misalnya memasang 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 yang sesuai. Ketika pengembang memilih paket DSU dengan atribut persyaratan 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 ketentuan layanan
Sebagai referensi, berikut 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 menggambarkan 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
. Jika atribut ini ditentukan, atribut tersebut 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 array opsional yang menentukan semua VNDK yang disertakan dalam paket DSU. Jika ditentukan, pemuat DSU akan memeriksa apakah nomor yang diekstraksi dari properti sistemro.vndk.version
disertakan.
Cabut kunci DSU demi 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 image DSU divalidasi dengan daftar pencabutan. Jika gambar ditemukan berisi kunci publik yang dicabut, proses instalasi DSU akan 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 stringnya adalah https://dl.google.com/developers/android/gsi/gsi-keyblacklist.json
, yang merupakan daftar pencabutan kunci GSI yang dirilis Google. String sumber daya ini dapat dilapis dan disesuaikan, sehingga OEM yang mengadopsi fitur DSU dapat menyediakan dan memelihara daftar hitam kunci mereka sendiri. Hal ini memberikan cara bagi OEM untuk memblokir kunci publik tertentu tanpa memperbarui image 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 kunci pub 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.
Hasilkan pasangan kunci baru
Gunakan perintah openssl
untuk menghasilkan pasangan kunci pribadi/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 kunci pub berpasangan ke ramdisk untuk instruksi 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 berupa file PEM.
Tambahkan kunci pub yang berpasangan ke ramdisk
oem_cert.avbpubkey
harus diletakkan di bawah /avb/*.avbpubkey
untuk memverifikasi paket DSU yang ditandatangani. Pertama, ubah 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 pada ramdisk tahap pertama dengan langkah sebagai 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
Hasilkan atribut pubkey AVB di deskriptor JSON
oem_cert.avbpubkey
ada dalam format biner kunci publik AVB. Gunakan SHA-1 agar 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",
...
},
Tanda tangani 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 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 .
Verifikasi paket DSU secara lokal
Disarankan untuk memverifikasi semua gambar lokal terhadap pasangan kunci publik 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
Buat 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 -
Sesuaikan 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 mencakup 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"
},
}
OEM mungkin saja merangkai metadata DSU yang dipublikasikan seperti yang ditunjukkan pada Gambar 7.
Gambar 7. Merangkai metadata DSU yang dipublikasikan