Google berkomitmen untuk mendorong terwujudnya keadilan ras bagi komunitas Kulit Hitam. Lihat caranya.

Menerapkan A/B Virtual

Untuk menerapkan A/B virtual pada perangkat baru, atau untuk retrofit perangkat yang diluncurkan, Anda harus membuat perubahan pada kode khusus perangkat.

Membangun 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 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 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 atau sama dengan sum(size of partitions) + 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)

Ini mengaktifkan snapshot userspace dengan Virtual A/B saat menggunakan metode kompresi tanpa operasi. Anda kemudian dapat mengonfigurasi metode kompresi ke salah satu metode yang didukung, gz dan brotli .

PRODUCT_VIRTUAL_AB_COMPRESSION_METHOD := gz

Untuk Android 12, untuk mengaktifkan snapshot terkompresi dengan A/B Virtual, 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 ditingkatkan ke Android 13 dan lebih tinggi, fitur kompresi XOR tidak diaktifkan secara default. Untuk mengaktifkan kompresi XOR, tambahkan 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 dari android_t_baseline.mk .

Penggabungan ruang pengguna

Untuk perangkat yang diupgrade ke Android 13 dan yang lebih tinggi, proses penggabungan ruang pengguna seperti yang dijelaskan dalam lapisan Pemetaan perangkat tidak diaktifkan secara default. Untuk mengaktifkan penggabungan userspace, 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 13 dan lebih tinggi.

Kontrol boot HAL

HAL kontrol boot menyediakan antarmuka bagi klien OTA untuk mengontrol slot boot. A/B virtual memerlukan peningkatan versi kecil dari HAL kontrol boot karena API tambahan diperlukan untuk memastikan bootloader terlindungi selama flashing/reset pabrik. Lihat IBootControl.hal dan types.hal untuk definisi HAL versi terbaru.

// 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 fstab

Integritas partisi metadata sangat penting untuk proses boot, 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 memberikan contoh:

/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 bendera f2fs: export FS_NOCOW_FL ke patch kernel pengguna untuk memperbaiki penyematan file. Sertakan f2fs: juga mendukung tambalan kernel file yang disematkan .

A/B virtual bergantung pada fitur yang ditambahkan dalam kernel versi 4.3: bit status luapan dalam snapshot dan target snapshot-merge . Semua perangkat yang diluncurkan dengan Android 9 dan yang lebih baru seharusnya sudah memiliki kernel versi 4.4 atau yang lebih baru.

Untuk mengaktifkan snapshot terkompresi, versi kernel minimum yang didukung adalah 4.19. Tetapkan CONFIG_DM_USER=m atau CONFIG_DM_USER=y . Jika menggunakan yang pertama (modul), modul harus dimuat di ramdisk tahap pertama. 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 secara opsional dapat melakukan retrofit A/B virtual. 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 .

  • Bendera fitur build-time — Untuk perangkat yang melakukan retrofit A/B virtual, PRODUCT_VIRTUAL_AB_OTA dan PRODUCT_VIRTUAL_AB_OTA_RETROFIT disetel ke true , 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 retrofit A/B virtual mempertahankan ukuran partisi super lama, jadi BOARD_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 partitions) + atas kepala .

Perubahan bootloader

Selama langkah penggabungan pembaruan, /data menyimpan satu-satunya instance keseluruhan dari OS Android. Setelah migrasi dimulai, partisi system , vendor , dan product tidak lengkap hingga penyalinan selesai. Jika perangkat direset ke setelan pabrik selama proses ini, baik dengan pemulihan atau melalui dialog pengaturan Sistem, maka perangkat tidak dapat di-boot.

Sebelum menghapus /data , selesaikan penggabungan dalam pemulihan atau kembalikan tergantung pada status perangkat:

  • Jika build baru berhasil di-boot sebelumnya, selesaikan migrasi.
  • Jika tidak, kembalikan ke slot lama:
    • Untuk partisi dinamis, putar kembali ke keadaan sebelumnya.
    • Untuk partisi statis, atur slot aktif ke slot lama.

Baik bootloader maupun fastbootd dapat menghapus partisi /data jika perangkat tidak terkunci. Sementara fastbootd dapat memaksa migrasi selesai, bootloader tidak bisa. Bootloader tidak tahu apakah penggabungan sedang berlangsung atau tidak, atau blok apa di /data yang merupakan partisi OS. Perangkat harus mencegah pengguna tanpa sadar membuat perangkat tidak dapat dioperasikan (bricking) dengan melakukan hal berikut:

  1. Implementasikan HAL kontrol boot agar bootloader dapat membaca nilai yang ditetapkan oleh metode setSnapshotMergeStatus() .
  2. Jika status penggabungan adalah MERGING , atau jika status penggabungan adalah SNAPSHOTTED dan slot telah berubah ke slot yang baru diperbarui, maka permintaan untuk menghapus userdata , metadata , atau partisi yang menyimpan status penggabungan harus ditolak di bootloader.
  3. Terapkan perintah fastboot snapshot-update cancel sehingga pengguna dapat memberi sinyal ke bootloader bahwa mereka ingin melewati mekanisme perlindungan ini.
  4. Ubah alat atau skrip flash khusus untuk mengeluarkan fastboot snapshot-update cancel saat mem-flash seluruh perangkat. Ini aman untuk dikeluarkan karena mem-flash seluruh perangkat akan menghapus OTA. Tooling dapat mendeteksi perintah ini saat runtime dengan mengimplementasikan fastboot getvar snapshot-update-status . Perintah ini membantu membedakan antara 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 membuat perubahan berikut pada protokol fastboot:

  • getvar snapshot-update-status — Mengembalikan nilai yang dikomunikasikan HAL kontrol boot ke bootloader:
    • Jika statusnya MERGING , bootloader harus mengembalikan merging .
    • Jika statusnya adalah SNAPSHOTTED , bootloader harus mengembalikan snapshotted .
    • Jika tidak, bootloader harus mengembalikan none .
  • snapshot-update merge — Menyelesaikan operasi penggabungan, mem-boot ke recovery/fastbootd jika perlu. Perintah ini hanya berlaku jika snapshot-update-status merging , dan hanya didukung di fastbootd.
  • snapshot-update cancel — Mengatur status gabungan HAL kontrol boot ke CANCELLED . Perintah ini tidak valid saat perangkat terkunci.
  • erase or wipeerase atau wipe metadata , userdata , atau partisi yang menyimpan status penggabungan untuk kontrol boot HAL harus memeriksa status penggabungan snapshot. Jika statusnya MERGING atau SNAPSHOTTED , perangkat harus membatalkan operasi.
  • set_active — Perintah set_active yang mengubah slot aktif harus memeriksa status penggabungan snapshot. Jika statusnya MERGING , perangkat harus membatalkan operasi. Slot dapat diubah dengan aman dalam status SNAPSHOTTED .

Perubahan ini dirancang untuk mencegah secara tidak sengaja membuat perangkat tidak dapat di-boot, tetapi dapat mengganggu perkakas otomatis. Saat perintah digunakan sebagai komponen untuk mem-flash semua partisi, seperti menjalankan fastboot flashall , disarankan untuk menggunakan alur berikut:

  1. Kueri getvar snapshot-update-status .
  2. Jika merging atau snapshotted , terbitkan snapshot-update cancel .
  3. Lanjutkan dengan langkah-langkah flashing.

Mengurangi persyaratan penyimpanan

Perangkat yang tidak memiliki penyimpanan A/B penuh yang dialokasikan di super, dan berharap untuk menggunakan /data seperlunya, sangat disarankan untuk menggunakan alat pemetaan blok. Alat pemetaan blok menjaga konsistensi alokasi blok di antara build, mengurangi penulisan yang tidak perlu ke snapshot. Ini didokumentasikan di bawah Mengurangi Ukuran OTA .

Metode Kompresi OTA

Paket Ota dapat disetel untuk metrik kinerja yang berbeda. Android saat ini menyediakan beberapa metode kompresi yang didukung ( gz , lz4 , dan none ) yang memiliki kompromi antara waktu penginstalan, penggunaan ruang sapi, 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 booting. Ukuran partisi dinamis total dari ota penuh tanpa kompresi adalah 4.81GB )

1. OTA tambahan pada Pixel 6 Pro

Waktu Instal tanpa Fase Postinstall Penggunaan Ruang Sapi Posting waktu boot OTA Waktu Penggabungan Snapshot
gz 24 mnt 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,90 GB 37,6 detik 40,7 detik

2. OTA penuh pada Pixel 6 Pro

Waktu Instal tanpa Fase Postinstall Penggunaan Ruang Sapi Posting waktu boot OTA Waktu Penggabungan Snapshot
gz 23 mnt 2,79 GB 24,9 detik 41,7 detik
lz4 12 menit 3,46 GB 20,0 detik 25,3 detik
tidak ada 10 menit 4,85 GB 20,6 detik 29,8 dtk