OEM dan vendor SoC yang ingin mengimplementasikan pembaruan sistem A/B harus memastikan bootloader mereka mengimplementasikan boot_control HAL dan meneruskan parameter yang benar ke kernel.
Menerapkan kontrol boot HAL
Bootloader berkemampuan A/B harus mengimplementasikan boot_control
HAL di hardware/libhardware/include/hardware/boot_control.h
. Anda dapat menguji implementasi menggunakan utilitas system/extras/bootctl
dan system/extras/tests/bootloader/
.
Anda juga harus mengimplementasikan mesin negara yang ditunjukkan di bawah ini:

Siapkan kernelnya
Untuk menerapkan pembaruan sistem A/B:
- Cherrypick seri patch kernel berikut (jika diperlukan):
- Jika booting tanpa ramdisk dan menggunakan "boot as recovery", cherrypick android-review.googlesource.com/#/c/158491/ .
- Untuk menyiapkan dm-verity tanpa ramdisk, cherrypick android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18 .
- Pastikan argumen baris perintah kernel berisi argumen tambahan berikut:
skip_initramfs rootwait ro init=/init root="/dev/dm-0 dm=system none ro,0 1 android-verity <public-key-id> <path-to-system-partition>"
<public-key-id>
adalah ID kunci publik yang digunakan untuk memverifikasi tanda tangan tabel verity (untuk detailnya, lihat dm-verity ) . - Tambahkan sertifikat .X509 yang berisi kunci publik ke keyring sistem:
- Salin sertifikat .X509 yang diformat dalam format
.der
ke root direktorikernel
. Jika sertifikat .X509 diformat sebagai file.pem
, gunakan perintahopenssl
berikut untuk mengonversi dari format.pem
ke.der
:openssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate>
- Bangun
zImage
untuk menyertakan sertifikat sebagai bagian dari keyring sistem. Untuk memverifikasi, periksa entriprocfs
(memerlukanKEYS_CONFIG_DEBUG_PROC_KEYS
untuk diaktifkan):angler:/# cat /proc/keys 1c8a217e I------ 1 perm 1f010000 0 0 asymmetri Android: 7e4333f9bba00adfe0ede979e28ed1920492b40f: X509.RSA 0492b40f [] 2d454e3e I------ 1 perm 1f030000 0 0 keyring .system_keyring: 1/4
Penyertaan sertifikat .X509 yang berhasil menunjukkan adanya kunci publik dalam keyring sistem (highlight menunjukkan ID kunci publik). - Ganti spasi dengan
#
dan berikan sebagai<public-key-id>
di baris perintah kernel. Misalnya, teruskanAndroid:#7e4333f9bba00adfe0ede979e28ed1920492b40f
sebagai ganti<public-key-id>
.
- Salin sertifikat .X509 yang diformat dalam format
Tetapkan variabel build
Bootloader berkemampuan A/B harus memenuhi kriteria variabel build berikut:
Harus menentukan target A/B |
/device/google/marlin/+/android-7.1.0_r1/device-common.mk . Anda juga dapat melakukan langkah dex2oat pasca-instal (tetapi pra-reboot) yang dijelaskan dalam Kompilasi . |
---|---|
Sangat disarankan untuk target A/B |
|
Tidak dapat menentukan target A/B |
|
Opsional untuk build debug | PRODUCT_PACKAGES_DEBUG += update_engine_client |
Atur partisi (slot)
Perangkat A/B tidak memerlukan partisi pemulihan atau partisi cache karena Android tidak lagi menggunakan partisi tersebut. Partisi data sekarang digunakan untuk paket OTA yang diunduh, dan kode image pemulihan ada di partisi boot. Semua partisi A/B-ed harus diberi nama sebagai berikut (slot selalu diberi nama a
, b
, dll.): boot_a
, boot_b
, system_a
, system_b
, vendor_a
, vendor_b
.
Cache
Untuk pembaruan non-A/B, partisi cache digunakan untuk menyimpan paket OTA yang diunduh dan untuk menyimpan blok sementara saat menerapkan pembaruan. Tidak pernah ada cara yang baik untuk mengukur partisi cache: seberapa besar partisi tersebut bergantung pada pembaruan apa yang ingin Anda terapkan. Kasus terburuknya adalah partisi cache sebesar image sistem. Dengan pembaruan A/B, tidak perlu menyimpan blok (karena Anda selalu menulis ke partisi yang saat ini tidak digunakan) dan dengan streaming A/B tidak perlu mengunduh seluruh paket OTA sebelum menerapkannya.
Pemulihan
Disk RAM pemulihan sekarang terdapat dalam file boot.img
. Saat masuk ke pemulihan, bootloader tidak dapat menempatkan opsi skip_initramfs
pada baris perintah kernel.
Untuk pembaruan non-A/B, partisi pemulihan berisi kode yang digunakan untuk menerapkan pembaruan. Pembaruan A/B diterapkan oleh update_engine
yang berjalan pada image sistem booting biasa. Masih ada mode pemulihan yang digunakan untuk mengimplementasikan reset data pabrik dan melakukan sideload paket pembaruan (dari situlah nama "pemulihan" berasal). Kode dan data untuk mode pemulihan disimpan di partisi boot biasa di ramdisk; untuk boot ke image sistem, bootloader memberitahu kernel untuk melewati ramdisk (jika tidak, perangkat akan boot ke mode pemulihan. Mode pemulihan kecil (dan sebagian besar sudah ada di partisi boot), sehingga partisi boot tidak bertambah dalam ukuran.
Fstab
Argumen slotselect
harus ada pada baris untuk partisi A/B-ed. Misalnya:
<path-to-block-device>/vendor /vendor ext4 ro wait,verify=<path-to-block-device>/metadata,slotselect
Tidak ada partisi yang boleh diberi nama vendor
. Sebaliknya, partisi vendor_a
atau vendor_b
akan dipilih dan dipasang pada titik pemasangan /vendor
.
Argumen slot kernel
Akhiran slot saat ini harus diteruskan melalui node pohon perangkat (DT) tertentu ( /firmware/android/slot_suffix
) atau melalui baris perintah kernel androidboot.slot_suffix
atau argumen bootconfig.
Secara default, fastboot mem-flash slot saat ini pada perangkat A/B. Jika paket pembaruan juga berisi gambar untuk slot lain yang tidak terkini, fastboot juga akan mem-flash gambar tersebut. Opsi yang tersedia meliputi:
-
--slot SLOT
. Ganti perilaku default dan minta fastboot untuk mem-flash slot yang diteruskan sebagai argumen. -
--set-active [ SLOT ]
. Atur slot sebagai aktif. Jika tidak ada argumen opsional yang ditentukan, maka slot saat ini ditetapkan sebagai aktif. -
fastboot --help
. Dapatkan detail tentang perintah.
Jika bootloader mengimplementasikan fastboot, bootloader harus mendukung perintah set_active <slot>
yang menetapkan slot aktif saat ini ke slot tertentu (ini juga harus menghapus tanda unbootable untuk slot tersebut dan mengatur ulang jumlah percobaan ulang ke nilai default). Bootloader juga harus mendukung variabel berikut:
-
has-slot:<partition-base-name-without-suffix>
. Mengembalikan “yes” jika partisi tertentu mendukung slot, “tidak” sebaliknya. -
current-slot
. Mengembalikan akhiran slot yang akan di-boot berikutnya. -
slot-count
. Mengembalikan bilangan bulat yang mewakili jumlah slot yang tersedia. Saat ini, dua slot didukung sehingga nilainya adalah2
. -
slot-successful:<slot-suffix>
. Mengembalikan "ya" jika slot yang diberikan telah ditandai berhasil melakukan booting, "tidak" jika tidak. -
slot-unbootable:<slot-suffix>
. Mengembalikan “yes” jika slot yang diberikan ditandai sebagai tidak dapat di-boot, “tidak” jika tidak. -
slot-retry-count
. Jumlah percobaan ulang yang tersisa untuk mencoba mem-boot slot yang diberikan.
Untuk melihat semua variabel, jalankan fastboot getvar all
.
Hasilkan paket OTA
Alat paket OTA mengikuti perintah yang sama seperti perintah untuk perangkat non-A/B. File target_files.zip
harus dibuat dengan mendefinisikan variabel build untuk target A/B. Alat paket OTA secara otomatis mengidentifikasi dan menghasilkan paket dalam format untuk pembaru A/B.
Contoh:
- Untuk menghasilkan OTA penuh:
./build/make/tools/releasetools/ota_from_target_files \ dist_output/tardis-target_files.zip \ ota_update.zip
- Untuk menghasilkan OTA tambahan:
./build/make/tools/releasetools/ota_from_target_files \ -i PREVIOUS-tardis-target_files.zip \ dist_output/tardis-target_files.zip \ incremental_ota_update.zip
Konfigurasikan partisi
update_engine
dapat memperbarui pasangan partisi A/B mana pun yang ditentukan dalam disk yang sama. Sepasang partisi memiliki awalan umum (seperti system
atau boot
) dan akhiran per slot (seperti _a
). Daftar partisi yang pembaruannya ditentukan oleh generator payload dikonfigurasikan oleh variabel make AB_OTA_PARTITIONS
.
Misalnya, jika sepasang partisi bootloader_a
dan booloader_b
disertakan ( _a
dan _b
adalah akhiran slot), Anda dapat memperbarui partisi ini dengan menentukan hal berikut pada konfigurasi produk atau board:
AB_OTA_PARTITIONS := \ boot \ system \ bootloader
Semua partisi yang diperbarui oleh update_engine
tidak boleh diubah oleh seluruh sistem. Selama pembaruan inkremental atau delta , data biner dari slot saat ini digunakan untuk menghasilkan data di slot baru. Modifikasi apa pun dapat menyebabkan data slot baru gagal diverifikasi selama proses pembaruan, sehingga gagal dalam pembaruan.
Konfigurasi pasca instalasi
Anda dapat mengonfigurasi langkah pasca-instalasi secara berbeda untuk setiap partisi yang diperbarui menggunakan serangkaian pasangan nilai kunci. Untuk menjalankan program yang terletak di /system/usr/bin/postinst
pada image baru, tentukan path yang berhubungan dengan root sistem file di partisi sistem.
Misalnya usr/bin/postinst
adalah system/usr/bin/postinst
(jika tidak menggunakan RAM disk). Selain itu, tentukan tipe sistem file yang akan diteruskan ke panggilan sistem mount(2)
. Tambahkan yang berikut ini ke file .mk
produk atau perangkat (jika ada):
AB_OTA_POSTINSTALL_CONFIG += \ RUN_POSTINSTALL_system=true \ POSTINSTALL_PATH_system=usr/bin/postinst \ FILESYSTEM_TYPE_system=ext4
Kompilasi aplikasi
Aplikasi dapat dikompilasi di latar belakang sebelum reboot dengan image sistem baru. Untuk mengkompilasi aplikasi di latar belakang, tambahkan yang berikut ke konfigurasi perangkat produk (di device.mk produk):
- Sertakan komponen asli dalam build untuk memastikan skrip kompilasi dan biner dikompilasi dan disertakan dalam image sistem.
# A/B OTA dexopt package PRODUCT_PACKAGES += otapreopt_script
- Hubungkan skrip kompilasi ke
update_engine
sehingga berjalan sebagai langkah pasca-instalasi.# A/B OTA dexopt update_engine hookup AB_OTA_POSTINSTALL_CONFIG += \ RUN_POSTINSTALL_system=true \ POSTINSTALL_PATH_system=system/bin/otapreopt_script \ FILESYSTEM_TYPE_system=ext4 \ POSTINSTALL_OPTIONAL_system=true
Untuk bantuan menginstal file yang sudah dipilih sebelumnya di partisi sistem kedua yang tidak digunakan, lihat Instalasi boot pertama file DEX_PREOPT .