Menerapkan pembaruan A/B

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:

Gambar 1. Mesin status bootloader

Siapkan kernelnya

Untuk menerapkan pembaruan sistem A/B:

  1. Cherrypick seri patch kernel berikut (jika diperlukan):
  2. 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>"
    ... dengan nilai <public-key-id> adalah ID kunci publik yang digunakan untuk memverifikasi tanda tangan tabel verity (untuk detailnya, lihat dm-verity ) .
  3. Tambahkan sertifikat .X509 yang berisi kunci publik ke keyring sistem:
    1. Salin sertifikat .X509 yang diformat dalam format .der ke root direktori kernel . Jika sertifikat .X509 diformat sebagai file .pem , gunakan perintah openssl berikut untuk mengonversi dari format .pem ke .der :
      openssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate>
    2. Bangun zImage untuk menyertakan sertifikat sebagai bagian dari keyring sistem. Untuk memverifikasi, periksa entri procfs (memerlukan KEYS_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).
    3. Ganti spasi dengan # dan berikan sebagai <public-key-id> di baris perintah kernel. Misalnya, teruskan Android:#7e4333f9bba00adfe0ede979e28ed1920492b40f sebagai ganti <public-key-id> .

Tetapkan variabel build

Bootloader berkemampuan A/B harus memenuhi kriteria variabel build berikut:

Harus menentukan target A/B
  • AB_OTA_UPDATER := true
  • AB_OTA_PARTITIONS := \
    boot \
    system \
    vendor
    dan partisi lain diperbarui melalui update_engine (radio, bootloader, dll.)
  • PRODUCT_PACKAGES += \
    update_engine \
    update_verifier
Misalnya, lihat /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
  • Definisikan TARGET_NO_RECOVERY := true
  • Definisikan BOARD_USES_RECOVERY_AS_BOOT := true
  • Jangan tentukan BOARD_RECOVERYIMAGE_PARTITION_SIZE
Tidak dapat menentukan target A/B
  • BOARD_CACHEIMAGE_PARTITION_SIZE
  • BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE
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 adalah 2 .
  • 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 (bila 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):

  1. 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
    
  2. 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 .