AndroidでのシームレスなA / Bアップデート:それらの仕組み

画像



こんにちは。SberDevicesでは、私たちのチームはAOSPに基づいたさまざまなハードウェアとファームウェアの開発に取り組んでいます。



Android 8(7.1以降の一部のベンダー)以降、システムには、OTA更新をローリングするための新しいメカニズム(いわゆる)があります。シームレスなA / BOTAアップデート-シームレスなアップデート。この投稿では、その操作の一般的な原則を説明し、開発者の観点からメカニズムを検討し、更新を適用するための古い(リカバリベースと呼びます)アプローチと比較します。特定の実装はベンダーによって異なるため、以下のすべては純粋なAOSPにのみ当てはまります。



リカバリベースのOTA



Androidのアップデートは、ブロックベースのアップデートを含むzipアーカイブの形式で提供されます。KitKatの時代には、含まれているスクリプトによってデバイスにコピーされたのはファイルのセットにすぎませんでした。このモードについては詳しく説明しません。その操作の基本原則について簡単に説明します。



  • zipアーカイブはシステムによってデバイスにダウンロードされます。
  • システムはリカバリモードで再起動します
  • アップデートとデバイスの互換性、その署名を確認します。
  • すべてがOKの場合、zipアーカイブのアップデータスクリプトが実行されます。
  • 更新中に、デバイスが数回再起動する場合があります(たとえば、デバイスツリーを更新するため)。
  • すべてがうまくいった場合は、新しいファームウェアで起動します。


このスキームの欠点は何ですか?



  • OTAアーカイブ用に十分な量の内部メモリを予約する必要があります。/ cacheセクションはこれに使用されます一部のベンダーは/ dataを使用していますが、これはまれです。その結果、ユーザーに残されるスペースは少なくなります(はい、アプリケーションは/ cacheパーティションのスペースを引き続き使用できますが、いくつかの制限があります)。
  • アップデートの再起動と適用には時間がかかります。これは、スマートTVなど、一部のタイプのデバイスでは重要になる可能性があります。
  • 更新プロセスを中断すると、ブートループが発生する可能性があります
  • 古いファームウェアバージョンにロールバックする方法はありません。


この不便さにより、シームレスなアップグレード方法をバイパスできます。それがどのように機能するか見てみましょう。



シームレスA / B OTA



シームレスなA / B更新 を実装するために必要な主要なコンポーネントとメカニズム



  • フラッシュメモリのスロットマークアップ。 
  • ローダーとの相互作用、スロットの状態の管理;
  • システムデーモンupdate_engine ;
  • 更新を含むzipアーカイブを生成します。この側面は、この記事では考慮されません。


スロット



A / BOTAの基本原理は スロットです。更新する必要のあるすべてのパーティション(これらは、システムパーティションだけでなく、任意のパーティションにすることができます)は、2つのコピーにあるか、そうでない場合はスロットにある必要があります。 Androidの実装はそれぞれABという名前の2つのスロットをサポートします。システムは現在のスロットから起動して動作し、2番目は更新時にのみ使用されます。セクション名にスロット名のサフィックスが追加されます。



以下は、デバイス上のパーティションを整理するための2つのオプションを比較した表です。システムが正しいスロットを選択できるように、 すべてのスロットパーティションはslotselectマウントオプションでマークされています 。それらが記述されている場所に応じて、これはfstabである可能性があります

画像



またはdts



パーティションテーブルの変更



  • B /キャッシュは不要になりました。これで、更新を/ dataに保存するか、すぐに非アクティブなスロットにフラッシュすることができます(詳細は以下を参照)。 
  • リカバリセクションも使用されなくなりました。ただし、 リカバリモードは  まだ存在するため、たとえば、デバイスを工場出荷時の設定にリセットする必要があります(これにより、救助隊につながる可能性があります )。またはいわゆるのために。adbを介した手動更新(サイドロード。 リカバリramdiskがブートパーティション 内にあり 、カーネルが共有されています。
  • (android/recovery) cmdline ‑ skip_initramfs.


一見すると、システムに2倍のスペースを割り当てる必要があるため、このようなスキームは最適ではないように見えます。しかし、  / cacheを削除しました。これは、すでに多くのメモリを節約したことを意味します。したがって、システムはリカバリオプションよりも少し多くかかります



A / Bアップデートの主な利点はファームウェアストリーミングできること です。ユーザーにシームレスで透過的な更新を保証するのはそれです。デバイスを更新するには、新しいスロットで再起動するだけで十分です。このモードでは、事前にzipアーカイブをダウンロードする必要はなく、/ dataのスペースを占有します。代わりに、システムは特別に準備されたファイル(ペイロード)からデータブロックをすぐに書き込みます、以下を参照)非アクティブスロットの各セクションに。実装の観点からは、更新を事前にダウンロードするか、すぐにスロットにストリーミングするかは関係ありません。



スロットの状態は次のとおりです。



  • アクティブ-アクティブスロット。システムは次回の再起動時にそこからロードされます。
  • 起動可能-更新がスロットに正常にフラッシュされ、検証され、ハッシュの合計が一致したなど。
  • 成功-システムは新しいスロットで正常に起動できました。
  • 起動できません-スロットが破損しています。アップグレードプロセスを開始する前に、システムは常にスロットを起動不可としてマークします。


どちらのスロットも起動可能 で成功する可能性があり ますが アクティブなのは1つだけです。



スロットを選択するときのブートローダーのアルゴリズム:

画像

  • ブートローダーは、1つ以上の起動可能なスロットがあることを検出し ます
  • それらからアクティブなスロット(または優先度が最も高いスロット)が選択されます。
  • システムが正常に起動すると、スロットは成功 および アクティブとしてマークされ ます。
  • それ以外の場合、スロットは起動不可としてマークされ、システムが再起動します。




更新中のスロット状態の変更:

画像



シームレスA / Bの前提条件。



boot_control



A / B更新をサポートするには、ベンダーは特別なHALインターフェイス(boot_control)を実装する必要がありますスロットの状態を変更して、スロットに関する情報を取得できます。外部作業(たとえば、adbシェルを介して)の場合、ユーティリティが使用されます-bootctlインターフェイスは、OSとブートローダー間の通信手段として使用されます。



update_engine



メインの成分全体のA / B回路。ダウンロード、更新のストリーミング、署名の検証などを処理します。boot_controlを介してスロットの状態を変更します。デバイスの更新プロセス(一時停止、再開、キャンセル)を制御できます。

このコンポーネントは、ChromeOSからAndroidに導入され、しばらくの間使用されてきました。 AOSPは、静的サイドロードアセンブリとしてupdate_engineサポートします。このモードは動的リンクをサポートしていないため、これリカバリ使用されるものです。 このコンポーネントのプロセスは、次のステップに分けることができます。







  • 更新をスロットにロードします。以前にダウンロードしたパッケージからアップデートをダウンロードするか、http / httpsを介してインターネット経由で直接ダウンロードできます。ダウンロード中に、署名がチェックされ、公開キーはすでにデバイス上にあります(/system/etc/update_engine/update-payload-key.pub.pem)。
  • ダウンロードしたアップデートの検証とハッシュ合計の比較。
  • インストール後のスクリプトの実行。 


サービスパックの構造:



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-update_verifierによって使用されます(以下を参照)。
  • payload_properties.txt-ペイロード内にハッシュとデータサイズが含まれています
  • payload.bin-パッケージを更新し、すべてのセクション、メタデータ、署名のブロックを含みます


update_engine_client



update_engine デーモンを管理するためのクライアントベンダーから直接呼び出して、更新を適用できます。



update_verifier



最初の起動時にシステムの整合性をチェックするユーティリティ(アクティブフラグのあるスロットですが、 まだ成功していません )。整合性制御は、dm-verityカーネルモジュールを使用して実装されますチェックが成功すると、ユーティリティは現在のスロットを成功としてマーク ます。それ以外の場合、システムは古いスロットで再起動します。care_map.txtファイルで指定されたブロックのみが検証されます。



UpdateEngineApi



ベンダー更新サービスを実装するためのJavaAPIがありますこのようなサービス実装の例もあります



AOSPでビルドされたA / Bアップデートの例を見てみましょう。これを行うには、ターゲットプラットフォームのMakefileを編集します。



#  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 := ...


make otapackageを 呼び出した後、更新を含むzipアーカイブを取得します。この形式では、サイドロードモードにすでに適しています。再起動してリカバリを実行しadb sideloadota.zipを呼び出すことができます。この方法はデバッグに便利です。



実稼働システム内からの更新の適用は、通常、ベンダー固有です。最も簡単な方法は、アップロードすることですpayload.binをhttpサーバとコールにupdate_engine_client直接



呼び出し例:



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"


payload_properties.txtファイル内容は、headersパラメーターに渡されますlogcat、あなたはアップデートの進行状況を確認することができます。--followスイッチを渡すと、進行状況がstdoutに複製されます。



結論



新しい更新メカニズムの利点は明らかです。



  • システムの更新は、ユーザーの作業を中断することなくバックグラウンドで実行されます。はい、(新しいスロットに対して)再起動する必要があり  ますが、更新を適用するためにリカバリで再起動するよりもはるかに高速です。
  • ブートループの可能性最小限に抑えられます(実装のエラーの影響を受けない人は誰もいません)。更新プロセスは中断される可能性があり、アクティブなスロットにはまったく影響しません。
  • 以前のファームウェアバージョンにロールバックすることが可能になります。何らかの理由で更新が失敗した場合でも、システムは単に古いバージョンに戻ります。
  • ストリーミングのおかげで、デバイスはより速く更新されます。
  • 実装によっては、更新プロセスからユーザーを完全に除外できます。


マイナス点のうち、私は2つのポイントを選び出します。



  • A / B OTAは、システムの実行中に更新が行われるため、現在のディスクレイアウトに依存します。つまり、変更されたパーティションで更新をロールすることができなくなります。
  • 実装の相対的な複雑さ。


それでも、私の意見では、長所が勝っています。ちなみに、最近発表されたデバイスでは、A / BOTAアップデートを使用しています。



All Articles