Menerapkan update A/B

OEM dan vendor SoC yang ingin mengimplementasikan update sistem A/B harus memastikan bootloader mereka mengimplementasikan HAL boot_control dan meneruskan parameter yang benar ke {i>kernel<i}.

Mengimplementasikan HAL kontrol booting

Bootloader yang mendukung A/B harus mengimplementasikan HAL boot_control hardware/libhardware/include/hardware/boot_control.h. Anda dapat menguji implementasi menggunakan system/extras/bootctl utilitas dan system/extras/tests/bootloader/.

Anda juga harus mengimplementasikan mesin status yang ditunjukkan di bawah:

Gambar 1. Mesin status bootloader

Menyiapkan kernel

Untuk menerapkan update sistem A/B:

  1. Pilihlah seri patch kernel berikut (jika perlu):
  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 verifikasi (untuk detailnya, lihat kebenaran dm).
  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 .pem, gunakan perintah openssl berikut untuk melakukan konversi dari Format .pem ke .der:
      openssl x509 -in <x509-pem-certificate> {i>-outform der -out<i} <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 akan diaktifkan):
      angler:/# cat /proc/keys
      
      1c8a217e I------ 1 perm 1f010000 0 0 asimetri
      Android: 7e4333f9bba00adfe0ede979e28ed1920492b40f: X509.RSA 0492b40f []
      2d454e3e I------     1 perm 1f030000     0     0 keyring
      .system_keyring: 1/4
      Penyertaan sertifikat .X509 berhasil menunjukkan adanya kunci publik di keyring sistem (sorot menunjukkan ID kunci publik).
    3. Ganti ruang dengan # dan teruskan sebagai <public-key-id> di command line kernel. Misalnya, teruskan Android:#7e4333f9bba00adfe0ede979e28ed1920492b40f menggantikan <public-key-id>.

Menetapkan variabel build

Bootloader yang mendukung 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 lain yang diperbarui melalui update_engine (radio, bootloader, etc.)
  • PRODUCT_PACKAGES += \
      update_engine \
      update_verifier
Lihat contoh /device/google/marlin/+/android-7.1.0_r1/device-common.mk. Anda dapat memilih untuk melakukan langkah dex2oat pasca-penginstalan (tetapi juga sebelum memulai ulang) yang dijelaskan di Kompilasi.
Sangat disarankan untuk target A/B
  • Tentukan TARGET_NO_RECOVERY := true
  • Tentukan 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

Menyetel partisi (slot)

Perangkat A/B tidak memerlukan partisi pemulihan atau partisi cache karena Android tidak lagi menggunakan partisi-partisi ini. Partisi data sekarang digunakan untuk paket OTA yang diunduh, dan yang ada di partisi {i>boot<i}. Semua partisi yang 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 {i>cache<i} digunakan untuk menyimpan paket OTA yang diunduh dan penyembunyian blok untuk sementara saat menerapkan pembaruan. Tidak pernah ada cara yang tepat untuk mengukur cache partisi: seberapa besar ukuran yang diperlukan, bergantung pada pembaruan yang ingin Anda terapkan. Terburuk contohnya adalah partisi {i>cache<i} sebesar {i>image<i} sistem. Dengan pembaruan A/B, Anda tidak perlu untuk menyembunyikan 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 kini dimuat dalam file boot.img. Saat masuk ke pemulihan, bootloader tidak dapat mengaktifkan opsi skip_initramfs baris perintah {i>kernel<i}.

Untuk update non-A/B, partisi pemulihan berisi kode yang digunakan untuk menerapkan update. A/B update diterapkan oleh update_engine yang berjalan di image sistem yang di-booting biasa. Masih ada mode pemulihan yang digunakan untuk menerapkan reset data pabrik dan sideload update paket (yang merupakan asal nama "recovery"). Kode dan data untuk mode pemulihan disimpan di partisi {i>booting<i} biasa dalam sebuah {i>ramdisk<i}; untuk melakukan booting ke image sistem, bootloader memberi tahu kernel untuk melewati ramdisk (jika tidak, perangkat akan melakukan booting ke proses pemulihan mode. Mode pemulihan kecil (dan sebagian besar sudah ada di partisi {i>boot<i}), jadi proses {i>booting<i} partisi tidak bertambah besar.

Fstab

Argumen slotselect harus berada pada baris untuk A/B-ed partisi. Contoh:

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

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

Argumen slot kernel

Akhiran slot saat ini harus diteruskan melalui node hierarki perangkat (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 gambar untuk slot lama yang lain, {i> fastboot<i} juga mem-flash gambar tersebut. Opsi yang tersedia meliputi:

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

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

  • has-slot:<partition-base-name-without-suffix>. Menampilkan “yes” jika diberikan partisi mendukung slot, “tidak” jika sebaliknya.
  • 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 booting, "tidak" sebaliknya.
  • slot-unbootable:<slot-suffix>. Menampilkan “yes” jika slot yang diberikan ditandai sebagai tidak dapat di-booting, "tidak" sebaliknya.
  • slot-retry-count:<slot-suffix>. Jumlah percobaan ulang yang tersisa untuk dicoba mem-{i>boot<i} slot yang diberikan.

Untuk melihat semua variabel, jalankan fastboot getvar all.

Membuat paket OTA

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

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<i}
        dist_output/tardis-target_files.zip \
        inkremental_ota_update.zip
    

Mengonfigurasi partisi

update_engine dapat mengupdate pasangan partisi A/B yang ditentukan dalam disk yang sama. Sepasang partisi memiliki awalan yang sama (seperti system atau boot) dan akhiran per slot (seperti _a). Daftar partisi dengan payload generator menentukan update dikonfigurasi oleh variabel make AB_OTA_PARTITIONS.

Misalnya, jika sepasang partisi bootloader_a dan booloader_b disertakan (_a dan _b adalah slotnya akhiran), Anda dapat memperbarui partisi ini dengan menentukan hal berikut pada produk atau board konfigurasi:

AB_OTA_PARTITIONS := \
  sepatu \
  sistem \
  {i>bootloader<i}

Semua partisi yang diupdate oleh update_engine tidak boleh diubah oleh bagian lainnya sistem file. Selama update inkremental atau delta, data biner dari slot saat ini yang digunakan untuk menghasilkan data di slot baru. Modifikasi apa pun dapat menyebabkan data slot baru gagal dalam verifikasi selama proses pembaruan, sehingga pembaruan gagal.

Mengonfigurasi pasca-penginstalan

Anda dapat mengkonfigurasi langkah pasca-penginstalan secara berbeda untuk setiap partisi yang diupdate menggunakan serangkaian pasangan nilai kunci. Untuk menjalankan program yang berlokasi di /system/usr/bin/postinst dalam {i>image<i}, menentukan jalur yang sesuai dengan {i>root<i} sistem file dalam partisi sistem.

Misalnya, usr/bin/postinst adalah system/usr/bin/postinst (jika bukan menggunakan disk RAM). Selain itu, tentukan jenis sistem file yang akan diteruskan ke Panggilan sistem mount(2). Tambahkan hal berikut ke produk atau perangkat File .mk (jika ada):

AB_OTA_POSTINSTALL_CONFIG += \
  RUN_POSTINSTALL_system=true \
  POST_PATH_system=usr/bin/postinst \
  FILESYSTEM_TYPE_system=ext4

Kompilasi 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. Menyertakan komponen native dalam build untuk memastikan skrip kompilasi dan biner dikompilasi dan dimasukkan ke dalam image sistem.
      # paket dexopt OTA A/B
      PRODUCT_PACKAGES += otapreopt_script
    
  2. Hubungkan skrip kompilasi ke update_engine seperti yang dijalankan sebagai langkah pasca-penginstalan.
      # hookup update_engine OTA A/B
      AB_OTA_POSTINSTALL_CONFIG += \
        RUN_POSTINSTALL_system=true \
        POST_PATH_system=system/bin/otapreopt_script \
        FILESYSTEM_TYPE_system=ext4 \
        POST_OPTIONAL_system=true
    

Untuk mendapatkan bantuan dalam menginstal file yang telah dipilih di partisi sistem kedua yang tidak digunakan, lihat Penginstalan pertama file DEX_PREOPT.