Menerapkan update A/B

OEM dan vendor SoC yang ingin menerapkan update sistem A/B harus memastikan bootloader mereka menerapkan HAL boot_control dan meneruskan parameter yang benar ke kernel.

Mengimplementasikan HAL kontrol booting

Bootloader yang kompatibel dengan A/B harus menerapkan HAL boot_control 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 menerapkan mesin status yang ditampilkan di bawah:

Gambar 1. Mesin status bootloader

Menyiapkan kernel

Untuk menerapkan update sistem A/B:

  1. Pilih seri patch kernel berikut (jika diperlukan):
  2. Pastikan argumen command line 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 mengetahui detailnya, lihat dm-verity).
  3. Tambahkan sertifikat .X509 yang berisi kunci publik ke keychain 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. Build 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 keberadaan kunci publik di keychain sistem (sorot menunjukkan ID kunci publik).
    3. Ganti spasi dengan # dan teruskan sebagai <public-key-id> di command line kernel. Misalnya, teruskan Android:#7e4333f9bba00adfe0ede979e28ed1920492b40f, bukan <public-key-id>.

Menetapkan variabel build

Bootloader yang kompatibel dengan A/B harus memenuhi kriteria variabel build berikut:

Harus ditentukan untuk target A/B
  • AB_OTA_UPDATER := true
  • AB_OTA_PARTITIONS := \
      boot \
      system \
      vendor
    dan partisi lainnya yang diupdate melalui update_engine (radio, bootloader, dll.)
  • PRODUCT_PACKAGES += \
      update_engine \
      update_verifier
Untuk contoh, lihat /device/google/marlin/+/android-7.1.0_r1/device-common.mk. Anda dapat melakukan langkah dex2oat pasca-penginstalan (tetapi pra-mulai ulang) secara opsional yang dijelaskan dalam Mengompilasi.
Sangat direkomendasikan untuk target A/B
  • Menentukan TARGET_NO_RECOVERY := true
  • Menentukan BOARD_USES_RECOVERY_AS_BOOT := true
  • Jangan tentukan BOARD_RECOVERYIMAGE_PARTITION_SIZE
Tidak dapat menentukan untuk target A/B
  • BOARD_CACHEIMAGE_PARTITION_SIZE
  • BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE
Opsional untuk build debug PRODUCT_PACKAGES_DEBUG += update_engine_client

Menetapkan partisi (slot)

Perangkat A/B tidak memerlukan partisi pemulihan atau partisi cache karena Android tidak lagi menggunakan partisi ini. Partisi data kini digunakan untuk paket OTA yang didownload, dan kode image pemulihan berada di partisi booting. Semua partisi yang di-A/B-kan 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 update non-A/B, partisi cache digunakan untuk menyimpan paket OTA yang didownload dan untuk menyimpan blok sementara saat menerapkan update. Tidak pernah ada cara yang baik untuk menentukan ukuran partisi cache: seberapa besar ukurannya bergantung pada update yang ingin Anda terapkan. Kasus terburuk adalah partisi cache yang berukuran sama dengan image sistem. Dengan update A/B, Anda tidak perlu menyimpan blok (karena Anda selalu menulis ke partisi yang saat ini tidak digunakan) dan dengan streaming A/B, Anda tidak perlu mendownload seluruh paket OTA sebelum menerapkannya.

Pemulihan

Disk RAM pemulihan kini terdapat dalam file boot.img. Saat masuk ke pemulihan, bootloader tidak dapat menempatkan opsi skip_initramfs di command line kernel.

Untuk update non-A/B, partisi pemulihan berisi kode yang digunakan untuk menerapkan update. Update A/B diterapkan oleh update_engine yang berjalan di image sistem yang di-booting secara reguler. Masih ada mode pemulihan yang digunakan untuk menerapkan reset data pabrik dan sideload paket update (yang menjadi asal nama "pemulihan"). Kode dan data untuk mode pemulihan disimpan di partisi booting reguler dalam ramdisk; untuk melakukan booting ke image sistem, bootloader memberi tahu kernel untuk melewati ramdisk (jika tidak, perangkat akan melakukan booting ke mode pemulihan. Mode pemulihan berukuran kecil (dan sebagian besar sudah ada di partisi booting), sehingga ukuran partisi booting tidak bertambah.

Fstab

Argumen slotselect harus berada di baris untuk partisi A/B. Contoh:

<path-to-block-device>/vendor  /vendor  ext4  ro
wait,verify=<path-to-block-device>/metadata,slotselect

Tidak ada partisi yang boleh diberi nama vendor. Sebagai gantinya, partisi vendor_a atau vendor_b akan dipilih dan dipasang di titik pemasangan /vendor.

Argumen slot kernel

Akhiran slot saat ini harus diteruskan melalui node device tree (DT) tertentu (/firmware/android/slot_suffix) atau melalui command line kernel androidboot.slot_suffix atau argumen bootconfig.

Secara default, fastboot mem-flash slot saat ini di perangkat A/B. Jika paket update juga berisi image untuk slot lain yang tidak saat ini, fastboot juga akan mem-flash image tersebut. Opsi yang tersedia mencakup:

  • --slot SLOT. Ganti perilaku default dan minta fastboot untuk mem-flash slot yang diteruskan sebagai argumen.
  • --set-active [SLOT]. Tetapkan slot sebagai aktif. Jika tidak ada argumen opsional yang ditentukan, slot saat ini akan ditetapkan sebagai aktif.
  • fastboot --help. Mendapatkan detail tentang perintah.

Jika bootloader menerapkan fastboot, bootloader harus mendukung perintah set_active <slot> yang menetapkan slot aktif saat ini ke slot yang ditentukan (tindakan ini juga harus menghapus tanda yang tidak dapat di-booting untuk slot tersebut dan mereset jumlah percobaan ulang ke nilai default). Bootloader juga harus mendukung variabel berikut:

  • has-slot:<partition-base-name-without-suffix>. Menampilkan “ya” jika partisi yang diberikan mendukung slot, “tidak” jika tidak.
  • current-slot. Menampilkan akhiran slot yang akan di-booting dari berikutnya.
  • slot-count. Menampilkan bilangan bulat yang mewakili jumlah slot yang tersedia. Saat ini, dua slot didukung sehingga nilai ini adalah 2.
  • slot-successful:<slot-suffix>. Menampilkan "yes" jika slot yang diberikan telah ditandai sebagai berhasil melakukan booting, "no" jika tidak.
  • slot-unbootable:<slot-suffix>. Menampilkan “ya” jika slot yang diberikan ditandai sebagai tidak dapat di-booting, "tidak" jika sebaliknya.
  • slot-retry-count:<slot-suffix>. Jumlah percobaan ulang yang tersisa untuk mencoba mem-booting slot yang ditentukan.

Untuk melihat semua variabel, jalankan fastboot getvar all.

Membuat paket OTA

Alat paket OTA mengikuti perintah yang sama dengan perintah untuk perangkat non-A/B. File target_files.zip harus dibuat dengan menentukan variabel build untuk target A/B. Alat paket OTA secara otomatis mengidentifikasi dan membuat paket dalam format untuk updater A/B.

Contoh:

  • Untuk membuat OTA lengkap:
    ./build/make/tools/releasetools/ota_from_target_files \
        dist_output/tardis-target_files.zip \
        ota_update.zip
    
  • Untuk membuat OTA inkremental:
    ./build/make/tools/releasetools/ota_from_target_files \
        -i PREVIOUS-tardis-target_files.zip \
        dist_output/tardis-target_files.zip \
        incremental_ota_update.zip
    

Mengonfigurasi partisi

update_engine dapat memperbarui pasangan partisi A/B apa pun yang ditentukan di disk yang sama. Sepasang partisi memiliki awalan umum (seperti system atau boot) dan akhiran per slot (seperti _a). Daftar partisi yang update-nya ditentukan oleh generator payload dikonfigurasi 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 papan:

AB_OTA_PARTITIONS := \
  boot \
  system \
  bootloader

Semua partisi yang diperbarui oleh update_engine tidak boleh diubah oleh sistem lainnya. Selama update inkremental atau delta, data biner dari slot saat ini digunakan untuk menghasilkan data di slot baru. Setiap modifikasi dapat menyebabkan data slot baru gagal diverifikasi selama proses update, sehingga update gagal.

Mengonfigurasi pasca-penginstalan

Anda dapat mengonfigurasi langkah pasca-penginstalan secara berbeda untuk setiap partisi yang diupdate menggunakan kumpulan pasangan nilai kunci. Untuk menjalankan program yang terletak di /system/usr/bin/postinst dalam image baru, tentukan jalur yang relatif terhadap root sistem file di partisi sistem.

Misalnya, usr/bin/postinst adalah system/usr/bin/postinst (jika tidak menggunakan disk RAM). Selain itu, tentukan jenis sistem file yang akan diteruskan ke panggilan sistem mount(2). Tambahkan kode berikut 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

Mengompilasi aplikasi

Aplikasi dapat dikompilasi di latar belakang sebelum dimulai ulang dengan image sistem baru. Untuk mengompilasi aplikasi di latar belakang, tambahkan kode berikut ke konfigurasi perangkat produk (di device.mk produk):

  1. Sertakan komponen native 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 pascapenginstalan.
      # 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 mendapatkan bantuan dalam menginstal file yang dipra-optimalkan di partisi sistem kedua yang tidak digunakan, lihat Penginstalan booting pertama file DEX_PREOPT.