Untuk menerapkan A/B virtual pada perangkat baru, atau untuk melakukan retrofit pada perangkat yang diluncurkan, Anda harus membuat perubahan pada kode khusus perangkat.
Bangun bendera
Perangkat yang menggunakan A/B virtual harus dikonfigurasi sebagai perangkat A/B dan harus diluncurkan dengan partisi dinamis .
Untuk perangkat yang diluncurkan dengan A/B virtual, atur perangkat agar mewarisi konfigurasi dasar perangkat A/B virtual:
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota.mk)
Perangkat yang diluncurkan dengan A/B virtual hanya memerlukan setengah ukuran papan untuk BOARD_SUPER_PARTITION_SIZE
karena slot B tidak lagi dalam ukuran super. Artinya, BOARD_SUPER_PARTITION_SIZE
harus lebih besar dari atau sama dengan sum(size of update groups) + overhead , yang, pada gilirannya, harus lebih besar dari atau sama dengan sum(size of parties) + overhead .
Untuk Android 13 dan lebih tinggi, untuk mengaktifkan snapshot terkompresi dengan Virtual A/B, warisi konfigurasi dasar berikut:
$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota/android_t_baseline.mk)
Hal ini memungkinkan snapshot ruang pengguna dengan Virtual A/B saat menggunakan metode kompresi tanpa pengoperasian. Anda kemudian dapat mengonfigurasi metode kompresi ke salah satu metode yang didukung, gz
, zstd
dan lz4
.
PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := lz4
Untuk Android 12, untuk mengaktifkan snapshot terkompresi dengan Virtual A/B, warisi konfigurasi dasar berikut:
$(call inherit-product, $(SRC_TARGET_DIR)/product/generic_ramdisk.mk)
$(call inherit-product, \
$(SRC_TARGET_DIR)/product/virtual_ab_ota/compression.mk)
kompresi XOR
Untuk perangkat yang diupgrade ke Android 13 dan lebih tinggi, fitur kompresi XOR tidak diaktifkan secara default. Untuk mengaktifkan kompresi XOR, tambahkan yang berikut ini ke file .mk
perangkat.
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.xor.enabled=true
Kompresi XOR diaktifkan secara default untuk perangkat yang mewarisi android_t_baseline.mk
.
Penggabungan ruang pengguna
Untuk perangkat yang diupgrade ke Android 13 dan lebih tinggi, proses penggabungan ruang pengguna seperti yang dijelaskan dalam Pelapisan pemetaan perangkat tidak diaktifkan secara default. Untuk mengaktifkan penggabungan ruang pengguna, tambahkan baris berikut ke file .mk
perangkat:
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.userspace.snapshots.enabled=true
Penggabungan ruang pengguna diaktifkan secara default pada perangkat yang diluncurkan dengan versi 13 dan lebih tinggi.
Kontrol boot HAL
Kontrol boot HAL menyediakan antarmuka bagi klien OTA untuk mengontrol slot boot. Virtual A/B memerlukan peningkatan versi kecil dari kontrol boot HAL karena API tambahan diperlukan untuk memastikan bootloader terlindungi selama flashing/reset pabrik. Lihat IBootControl.hal dan type.hal untuk versi terbaru definisi HAL.
// hardware/interfaces/boot/1.1/types.hal
enum MergeStatus : uint8_t {
NONE, UNKNOWN, SNAPSHOTTED, MERGING, CANCELLED };
// hardware/interfaces/boot/1.1/IBootControl.hal
package android.hardware.boot@1.1;
interface IBootControl extends @1.0::IBootControl {
setSnapshotMergeStatus(MergeStatus status)
generates (bool success);
getSnapshotMergeStatus()
generates (MergeStatus status);
}
// Recommended implementation
Return<bool> BootControl::setSnapshotMergeStatus(MergeStatus v) {
// Write value to persistent storage
// e.g. misc partition (using libbootloader_message)
// bootloader rejects wipe when status is SNAPSHOTTED
// or MERGING
}
Perubahan pada tab
Integritas partisi metadata sangat penting untuk proses booting, terutama setelah pembaruan OTA diterapkan. Jadi, partisi metadata harus diperiksa sebelum first_stage_init
memasangnya. Untuk memastikan hal ini terjadi, check
tanda centang fs_mgr ke entri untuk /metadata
. Berikut ini contohnya:
/dev/block/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard,sync wait,formattable,first_stage_mount,check
Persyaratan kernel
Untuk mengaktifkan snapshotting, setel CONFIG_DM_SNAPSHOT
ke true
.
Untuk perangkat yang menggunakan F2FS, sertakan tanda f2fs: ekspor FS_NOCOW_FL ke patch kernel pengguna untuk memperbaiki penyematan file. Sertakan f2fs: juga mendukung patch kernel file yang disematkan .
Virtual A/B mengandalkan fitur yang ditambahkan di kernel versi 4.3: bit status overflow dalam target snapshot
dan snapshot-merge
. Semua perangkat yang diluncurkan dengan Android 9 dan lebih baru seharusnya sudah memiliki kernel versi 4.4 atau lebih baru.
Untuk mengaktifkan snapshot terkompresi, versi kernel minimum yang didukung adalah 4.19. Setel CONFIG_DM_USER=m
atau CONFIG_DM_USER=y
. Jika menggunakan yang pertama (modul), modul harus dimuat di ramdisk tahap pertama. Hal ini dapat dicapai dengan menambahkan baris berikut ke perangkat Makefile:
BOARD_GENERIC_RAMDISK_KERNEL_MODULES_LOAD := dm-user.ko
Retrofit pada perangkat yang diupgrade ke Android 11
Saat mengupgrade ke Android 11, perangkat yang diluncurkan dengan partisi dinamis dapat melakukan retrofit A/B virtual secara opsional. Proses pembaruan sebagian besar sama dengan perangkat yang diluncurkan dengan A/B virtual, dengan beberapa perbedaan kecil:
Lokasi file COW — Untuk perangkat peluncuran, klien OTA menggunakan semua ruang kosong yang tersedia di partisi super sebelum menggunakan ruang di
/data
. Untuk perangkat retrofit, selalu ada cukup ruang di partisi super sehingga file COW tidak pernah dibuat di/data
.Tanda fitur waktu pembuatan — Untuk perangkat yang melakukan retrofit A/B virtual,
PRODUCT_VIRTUAL_AB_OTA
danPRODUCT_VIRTUAL_AB_OTA_RETROFIT
disetel ketrue
, seperti yang ditunjukkan di bawah ini:(call inherit-product, \
(SRC_TARGET_DIR)/product/virtual_ab_ota_retrofit.mk)
Ukuran partisi super — Perangkat yang diluncurkan dengan A/B virtual dapat memotong
BOARD_SUPER_PARTITION_SIZE
menjadi dua karena slot B tidak ada di partisi super. Perangkat yang melakukan retrofit A/B virtual mempertahankan ukuran partisi super lama, sehinggaBOARD_SUPER_PARTITION_SIZE
lebih besar dari atau sama dengan 2 * sum(size of update groups) + overhead , yang pada gilirannya lebih besar dari atau sama dengan 2 * sum(size of parties) + di atas kepala .
Perubahan bootloader
Selama langkah penggabungan pembaruan, /data
menampung satu-satunya instance OS Android secara keseluruhan. Setelah migrasi dimulai, system
asli, vendor
, dan partisi product
belum selesai hingga penyalinan selesai. Jika perangkat direset ke pabrik selama proses ini, baik melalui pemulihan atau melalui dialog Pengaturan sistem, maka perangkat tidak dapat di-boot.
Sebelum menghapus /data
, selesaikan penggabungan dalam pemulihan atau rollback tergantung pada status perangkat:
- Jika build baru berhasil di-boot sebelumnya, selesaikan migrasi.
- Jika tidak, kembalikan ke slot lama:
- Untuk partisi dinamis, kembalikan ke keadaan sebelumnya.
- Untuk partisi statis, atur slot aktif ke slot lama.
Bootloader dan fastbootd
dapat menghapus partisi /data
jika perangkat tidak terkunci. Meskipun fastbootd
dapat memaksa migrasi selesai, bootloader tidak bisa. Bootloader tidak mengetahui apakah penggabungan sedang berlangsung atau tidak, atau blok apa di /data
yang merupakan partisi OS. Perangkat harus mencegah pengguna secara tidak sadar membuat perangkat tidak dapat dioperasikan (brick) dengan melakukan hal berikut:
- Menerapkan HAL kontrol boot sehingga bootloader dapat membaca nilai yang ditetapkan oleh metode
setSnapshotMergeStatus()
. - Jika status penggabungan adalah
MERGING
, atau jika status penggabungan adalahSNAPSHOTTED
dan slot telah berubah menjadi slot yang baru diperbarui, maka permintaan untuk menghapususerdata
,metadata
, atau partisi yang menyimpan status penggabungan harus ditolak di bootloader. - Terapkan perintah
fastboot snapshot-update cancel
sehingga pengguna dapat memberi sinyal ke bootloader bahwa mereka ingin melewati mekanisme perlindungan ini. - Ubah alat atau skrip flashing khusus untuk membatalkan
fastboot snapshot-update cancel
saat mem-flash seluruh perangkat. Ini aman untuk dilakukan karena mem-flash seluruh perangkat akan menghapus OTA. Perkakas dapat mendeteksi perintah ini saat runtime dengan mengimplementasikanfastboot getvar snapshot-update-status
. Perintah ini membantu membedakan kondisi kesalahan.
Contoh
struct VirtualAbState {
uint8_t StructVersion;
uint8_t MergeStatus;
uint8_t SourceSlot;
};
bool ShouldPreventUserdataWipe() {
VirtualAbState state;
if (!ReadVirtualAbState(&state)) ...
return state.MergeStatus == MergeStatus::MERGING ||
(state.MergeStatus == MergeStatus::SNAPSHOTTED &&
state.SourceSlot != CurrentSlot()));
}
Perubahan perkakas fastboot
Android 11 melakukan perubahan berikut pada protokol fastboot:
-
getvar snapshot-update-status
— Mengembalikan nilai yang dikomunikasikan oleh kontrol boot HAL ke bootloader:- Jika keadaannya adalah
MERGING
, bootloader harus mengembalikanmerging
. - Jika statusnya adalah
SNAPSHOTTED
, bootloader harus mengembalikansnapshotted
. - Jika tidak, bootloader harus mengembalikan
none
.
- Jika keadaannya adalah
-
snapshot-update merge
— Menyelesaikan operasi penggabungan, mem-boot ke pemulihan/fastbootd jika perlu. Perintah ini hanya valid jikasnapshot-update-status
merging
, dan hanya didukung di fastbootd. -
snapshot-update cancel
— Menyetel status penggabungan HAL kontrol boot keCANCELLED
. Perintah ini tidak valid bila perangkat terkunci. -
erase
atauwipe
—erase
atauwipe
metadata
,userdata
, atau partisi yang memiliki status penggabungan untuk kontrol boot HAL harus memeriksa status penggabungan snapshot. Jika statusnya adalahMERGING
atauSNAPSHOTTED
, perangkat harus membatalkan operasi. -
set_active
— Perintahset_active
yang mengubah slot aktif harus memeriksa status penggabungan snapshot. Jika statusnya adalahMERGING
, perangkat harus membatalkan operasi. Slot dapat diubah dengan aman dalam statusSNAPSHOTTED
.
Perubahan ini dirancang untuk mencegah perangkat tidak dapat di-boot secara tidak sengaja, namun perubahan ini dapat mengganggu peralatan otomatis. Ketika perintah digunakan sebagai komponen untuk mem-flash semua partisi, seperti menjalankan fastboot flashall
, disarankan untuk menggunakan alur berikut:
- Kueri
getvar snapshot-update-status
. - Jika
merging
atausnapshotted
, keluarkansnapshot-update cancel
. - Lanjutkan dengan langkah flashing.
Mengurangi kebutuhan penyimpanan
Perangkat yang tidak memiliki penyimpanan A/B penuh yang dialokasikan di super, dan mengharapkan untuk menggunakan /data
seperlunya, sangat disarankan untuk menggunakan alat pemetaan blok. Alat pemetaan blok menjaga alokasi blok tetap konsisten antar build, sehingga mengurangi penulisan yang tidak diperlukan pada snapshot. Hal ini didokumentasikan dalam Mengurangi Ukuran OTA .
Metode kompresi OTA
Paket OTA dapat disesuaikan untuk metrik kinerja yang berbeda. Android menyediakan beberapa metode kompresi yang didukung ( gz
, lz4
, zstd
, dan none
) yang memiliki trade-off antara waktu instalasi, penggunaan ruang COW, waktu booting, dan waktu penggabungan snapshot. Opsi default yang diaktifkan untuk ab virtual dengan kompresi adalah gz compression method
. (Catatan: kinerja relatif antara metode kompresi bervariasi tergantung pada kecepatan CPU dan throughput penyimpanan yang dapat berubah tergantung pada perangkat. Semua paket OTA yang dihasilkan di bawah ini dengan PostInstall dinonaktifkan, yang akan sedikit memperlambat waktu boot. Total ukuran partisi dinamis dari ota penuh tanpa kompresi adalah 4,81 GB ).
OTA tambahan di Pixel 6 Pro
Waktu instalasi tanpa fase pasca instalasi | Penggunaan ruang SAPI | Posting waktu boot OTA | Waktu penggabungan cuplikan | |
---|---|---|---|---|
gz | 24 menit | 1,18 GB | 40,2 detik | 45,5 detik |
lz4 | 13 menit | 1,49 GB | 37,4 detik | 37,1 detik |
tidak ada | 13 menit | 2,90GB | 37,6 detik | 40,7 detik |
OTA penuh di Pixel 6 Pro
Waktu instalasi tanpa fase pasca instalasi | Penggunaan Ruang SAPI | Posting waktu boot OTA | Waktu penggabungan cuplikan | |
---|---|---|---|---|
gz | 23 menit | 2,79 GB | 24,9 detik | 41,7 detik |
lz4 | 12 menit | 3,46GB | 20,0 detik | 25,3 detik |
tidak ada | 10 menit | 4,85 GB | 20,6 detik | 29,8 detik |