Pembaruan A / B yang Mulus di Android: Cara Kerjanya

gambar



Halo. Di SberDevices, tim kami terlibat dalam pengembangan berbagai perangkat keras dan firmware untuk mereka berdasarkan AOSP.



Mulai dari Android 8 (beberapa vendor dari 7.1), sistem memiliki mekanisme baru untuk meluncurkan pembaruan OTA, yang disebut. Pembaruan A / B OTA Seamless - pembaruan tanpa batas. Dalam posting ini saya akan menjelaskan prinsip-prinsip umum operasinya, mempertimbangkan mekanisme dari sudut pandang pengembang, dan juga membandingkannya dengan pendekatan lama (kami akan menyebutnya berbasis pemulihan) untuk menerapkan pembaruan. Semua hal berikut ini hanya berlaku untuk AOSP murni, karena penerapan spesifik bergantung pada vendor.



OTA berbasis pemulihan



Pembaruan untuk Android dikirimkan dalam bentuk arsip zip dengan pembaruan berbasis blok. Di masa KitKat, itu hanya sekumpulan file yang disalin ke perangkat oleh skrip yang disertakan. Saya tidak akan membahas mode ini secara detail, saya akan menjelaskan secara singkat prinsip-prinsip dasar operasinya:



  • arsip zip diunduh oleh sistem ke perangkat;
  • sistem melakukan boot ulang ke mode pemulihan ;
  • memeriksa kompatibilitas pembaruan dengan perangkat, tanda tangannya;
  • jika semuanya baik-baik saja, script updater dari arsip zip dijalankan ;
  • selama pembaruan, perangkat mungkin melakukan boot ulang beberapa kali (misalnya, untuk memperbarui pohon perangkat );
  • jika semuanya berjalan dengan baik, boot ke firmware baru.


Apa kerugian dari skema ini?



  • Kebutuhan untuk mencadangkan memori internal yang cukup untuk arsip OTA. Bagian / cache digunakan untuk ini . Beberapa vendor menggunakan / data , tetapi ini jarang terjadi. Akibatnya, pengguna hanya memiliki sedikit ruang (ya, aplikasi masih dapat menggunakan ruang di partisi / cache , tetapi dengan beberapa batasan).
  • Mem-boot ulang dan menerapkan pembaruan membutuhkan waktu, yang dapat menjadi penting untuk beberapa jenis perangkat, misalnya, untuk Smart TV.
  • Mengganggu proses pembaruan dapat mengakibatkan boot loop .
  • Tidak ada cara untuk mengembalikan ke versi firmware lama.


Ketidaknyamanan ini memungkinkan Anda untuk melewati metode peningkatan yang mulus. Mari kita lihat cara kerjanya.



A / B OTA yang mulus



Komponen dan mekanisme utama yang diperlukan untuk mengimplementasikan pembaruan A / B yang mulus :



  • markup slot memori flash; 
  • interaksi dengan pemuat, mengelola status slot ;
  • daemon sistem update_engine ;
  • menghasilkan arsip zip dengan pembaruan. Aspek ini tidak akan dibahas dalam artikel ini.


Slot



Prinsip dasar A / B OTA adalah  slotting . Semua partisi yang perlu diperbarui (ini dapat berupa partisi apa pun, bukan hanya partisi sistem) harus dalam dua salinan atau, sebaliknya, dalam slot. Pelaksanaan Android mendukung 2 slot, yang diberi nama A dan B, masing-masing . Sistem melakukan booting dan bekerja dari slot saat ini, slot kedua hanya digunakan pada saat pembaruan. Akhiran dengan nama slot ditambahkan ke nama bagian.



Di bawah ini adalah tabel yang membandingkan dua opsi untuk mengatur partisi pada perangkat. Semua partisi berlubang ditandai dengan opsi slotpilih pemasangan  sehingga sistem dapat memilih slot yang benar. Bergantung di mana mereka dijelaskan, ini bisa menjadi fstab

gambar



atau dts .



Perubahan pada tabel partisi



  • B / cache tidak lagi dibutuhkan. Sekarang pembaruan dapat disimpan baik di / data , atau langsung di-flash ke slot yang tidak aktif (lebih lanjut tentang itu di bawah). 
  • Bagian pemulihan juga tidak lagi digunakan. Namun,  mode  pemulihan  masih ada, diperlukan, misalnya, untuk mengatur ulang perangkat ke pengaturan pabrik (ini dapat menyebabkan  pesta penyelamatan ). Atau untuk yang disebut. pembaruan manual ( sideload ) melalui adbRamdisk pemulihan  sekarang berada di dalam  partisi boot , kernel dibagikan.
  • (android/recovery) cmdline ‑ skip_initramfs.


Sekilas, tampaknya skema seperti itu tidak optimal, karena perlu mengalokasikan ruang dua kali lebih banyak untuk sistem. Tapi kami menghapus  / cache , yang berarti kami telah menghemat banyak memori. Dengan demikian, sistem akan mengambil sedikit lebih banyak daripada opsi pemulihan .



Keuntungan utama pembaruan A / B adalah kemampuan untuk melakukan  streaming firmware. Itu yang memastikan pembaruan yang mulus dan transparan bagi pengguna: untuk memperbarui perangkat, cukup dengan melakukan boot ulang ke slot baru. Dalam mode ini, tidak perlu mengunduh arsip zip terlebih dahulu, menghabiskan ruang di / data . Sebaliknya, sistem segera menulis blok data dari file yang disiapkan khusus ( payload, lihat di bawah) ke dalam setiap bagian dari slot yang tidak aktif. Dari sudut pandang implementasi, tidak ada bedanya apakah kita mengunduh pembaruan terlebih dahulu atau segera mengalirkannya ke slot.



Slot memiliki status berikut:



  • aktif - slot aktif, sistem akan dimuat darinya pada booting ulang berikutnya;
  • bootable - pembaruan berhasil di-flash ke slot, divalidasi, jumlah hash dicocokkan, dll.;
  • berhasil - sistem berhasil melakukan boot ke slot baru;
  • unbootable - slotnya rusak. Sistem selalu menandai slot sebagai tidak dapat di - boot sebelum memulai proses peningkatan.


Kedua slot dapat di-  boot  dan  berhasil , tetapi hanya satu yang aktif .



Algoritme bootloader saat memilih slot:

gambar

  • Bootloader mendeteksi bahwa ada satu atau lebih  slot yang dapat di-boot .
  • Slot aktif (atau slot dengan prioritas tertinggi) dipilih darinya.
  • Jika sistem berhasil melakukan booting, slot tersebut ditandai sebagai  berhasil  dan  aktif .
  • Jika tidak, slot akan ditandai sebagai tidak dapat di - boot dan sistem akan melakukan boot ulang.




Mengubah status slot selama pembaruan:

gambar



Komponen yang diperlukan untuk bekerja dengan A / B Seamless



boot_control



Untuk mendukung pembaruan A / B, vendor harus menerapkan antarmuka HAL khusus - boot_control . Ini memungkinkan Anda untuk mengubah status slot dan mendapatkan informasi tentangnya. Untuk pekerjaan eksternal (misalnya, melalui adb shell ), utilitas digunakan - bootctl . Antarmuka digunakan sebagai alat komunikasi antara OS dan bootloader.



update_engine



Komponen utama dari seluruh rangkaian A / B. Menangani pengunduhan, streaming pembaruan, verifikasi tanda tangan, dan banyak lagi. Mengubah status slot melalui boot_control . Memungkinkan Anda mengontrol proses pembaruan perangkat: jeda, lanjutkan, batalkan.

Komponen datang ke Android dari ChromeOS, yang telah digunakan untuk sementara waktu. AOSP mempertahankan update_engine sebagai rakitan sideload statis . Dialah yang digunakan dalam pemulihan , karena mode ini tidak mendukung tautan dinamis.



Proses komponen ini dapat dibagi menjadi langkah-langkah berikut:



  • memuat pembaruan ke dalam slot. Anda dapat mengunduh keduanya dari paket yang diunduh sebelumnya dengan pembaruan, atau langsung melalui Internet melalui http / https. Selama pengunduhan, tanda tangan diperiksa, kunci publik sudah ada di perangkat (/system/etc/update_engine/update-payload-key.pub.pem);
  • verifikasi pembaruan yang diunduh dan perbandingan jumlah hash;
  • eksekusi skrip pasca-pemasangan


Struktur paket layanan:



2009-01-01 00:00:00 .....          360          360  META-INF/com/android/metadata
2009-01-01 00:00:00 .....          107          107  care_map.txt
2009-01-01 00:00:00 .....    384690699    384690699  payload.bin
2009-01-01 00:00:00 .....          154          154  payload_properties.txt
2009-01-01 00:00:00 .....         1675          943  META-INF/com/android/otacert


  • care_map.txt - digunakan oleh update_verifier (lihat di bawah);
  • payload_properties.txt - berisi hash dan ukuran data di dalam payload ;
  • payload.bin - perbarui paket, berisi blok semua bagian, metadata , tanda tangan.


update_engine_client



Klien untuk mengelola daemon update_engine . Bisa dipanggil langsung oleh vendor untuk menerapkan update.



update_verifier



Utilitas untuk memeriksa integritas sistem di awal pertama (slot dengan flag  aktif , tetapi belum  berhasil ). Kontrol integritas diimplementasikan menggunakan modul kernel dm-verity . Jika pemeriksaan berhasil, utilitas menandai slot saat ini sebagai  berhasil . Jika tidak, sistem akan melakukan boot ulang ke slot lama. Hanya blok yang ditentukan dalam file care_map.txt yang diverifikasi .



UpdateEngineApi



Ada API Java untuk mengimplementasikan layanan pembaruan vendor . Ada juga contoh implementasi layanan seperti itu.



Mari kita lihat contoh pembaruan A / B yang dibangun di AOSP. Untuk melakukan ini, edit Makefile dari platform target:



#  A/B
AB_OTA_UPDATER := true
#    :
AB_OTA_PARTITIONS := boot system vendor
#  
PRODUCT_PACKAGES := update_engine update_engine_client update_verifier
#  recovery
TARGET_NO_RECOVERY := true
#,       cache:
#BOARD_CACHEIMAGE_PARTITION_SIZE := ...
#BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ...


Setelah memanggil make otapackage, kami mendapatkan arsip zip dengan pembaruan. Dalam bentuk ini, itu sudah cocok untuk mode sideload . Kita bisa reboot ke recovery dan memanggil adb sideload ota.zip . Metode ini nyaman untuk debugging.



Penerapan pembaruan dari dalam sistem produksi biasanya khusus vendor. Cara termudah adalah dengan mengunggah payload.bin ke server http dan langsung memanggil update_engine_client .



Contoh panggilan:



update_engine_client \
--payload=http://path/to/payload.bin \
--update \
--headers=" \
FILE_HASH=ozGgyQEddkI5Zax+Wbjo6I/PCR8PEZka9gGd0nWa+oY= \
FILE_SIZE=282344983 \
METADATA_HASH=GLIKfE6KRwylWMHsNadG/Q8iy5f786WTatvMdBlpOPg= \
METADATA_SIZE=26723"


Konten file payload_properties.txt diteruskan ke parameter headers . Di logcat, Anda dapat melihat kemajuan pembaruan. Jika Anda melewati tombol --follow , kemajuannya akan diduplikasi di stdout .



Kesimpulan



Keuntungan dari mekanisme pembaruan baru sangat jelas:



  • pembaruan sistem berlangsung di latar belakang tanpa mengganggu pekerjaan pengguna. Ya, Anda masih perlu reboot (ke slot baru), tetapi akan  jauh  lebih cepat daripada reboot dalam pemulihan untuk menerapkan pembaruan;
  • probabilitas boot loop diminimalkan (tidak ada yang kebal dari kesalahan dalam implementasi). Proses pembaruan dapat terputus, ini tidak akan memengaruhi slot aktif dengan cara apa pun;
  • menjadi mungkin untuk melakukan rollback ke versi firmware sebelumnya. Meskipun karena alasan tertentu pembaruan tidak berhasil, sistem akan kembali ke versi lama;
  • berkat streaming, perangkat akan diperbarui lebih cepat;
  • bergantung pada implementasinya, Anda dapat sepenuhnya mengecualikan pengguna dari proses pembaruan.


Dari minusnya, saya akan memilih dua poin:



  • A / B OTA menjadi tergantung pada tata letak disk saat ini, karena pembaruan terjadi saat sistem berjalan. Artinya, mustahil untuk menggulung pembaruan dengan partisi yang diubah;
  • kompleksitas relatif dari implementasi.


Namun, menurut saya, yang pro lebih penting. Omong-omong, di perangkat yang baru-baru ini kami umumkan, kami menggunakan pembaruan A / B OTA.



All Articles