フラッシュ、起動、アップデート

画像のフラッシュ

flash コマンドでパーティションを消去しないようにする必要があります。ただし、ホストの fastboot ツールが最初に erase コマンドを送信する場合を除きます。これにより、「スキップ」ブロックで始まる複数のスパース イメージを使用して、複数の小さなチャンクで非常に大きなパーティションをフラッシュし、書き込み済みの領域での検索を実行できるようになります。これらのイメージのリアルタイム作成は、ホスト側の fastboot ツールですでに処理されています。

ロック解除モードでフラッシュする前に、無線イメージとブートローダー イメージでサニティ チェックを行う必要があります。たとえば、ビルドから作成した android-info.txt と比較し、バージョンの一致を確認します。また、ブートローダー イメージの署名をフラッシュ時に確認して、ブート中に検証を通過することを確認します(アンチ ロールバック機能が含まれる場合があります)。

Google ブランドのデバイスでは、最初の商用ブートローダー(理想的にはさらに早期に)をはじめ、古いバージョンのブートローダーへのフラッシュは正常に機能します。

ブート: カーネル コマンドライン

カーネル コマンドラインは次の場所から連結できます。

  • ブートローダー コマンドライン: ブートローダーにより決定される静的パラメータと動的パラメータのセット
  • デバイスツリー: 選択したノードまたは bootargs ノードから
  • defconfig: CONFIG_CMDLINE から
  • boot.img: cmdline から(オフセットとサイズについては system/core/mkbootimg/bootimg.h をご覧ください)
  • Android Compatibility Definition Document に準拠する、正規の再起動またはシャットダウンの理由。PMIC(電力管理集積回路)、その他のハードウェア リソース、再起動マジック引数(LINUX_REBOOT_CMD_RESTART2)メッセージングにより決定され、androidboot.bootreason=<reason> という形式で表されます。

起動: デバイスツリー/デバイスツリー オーバーレイ

複数の構成をサポートできるようにするため、ブートローダーは実行元のハードウェア/製品のリビジョンを特定し、適切なデバイスツリー オーバーレイのセットを読み込むことができます。

カーネル アドレス空間レイアウトのランダム化のサポート

カーネル イメージを読み込む仮想アドレスのランダム化(カーネル構成 RANDOMIZE_BASE により有効化)をサポートするには、ブートローダーがランダムな u64 値を DT ノード /chosen/kaslr-seed に渡してエントロピーを指定する必要があります。

確認済みの起動の実装

ブートの検証をご覧ください。

アップデートのサポート

Google Over The Air(GOTA)アップデート プロセスをサポートするには、リカバリ RAM ディスクがなければなりません。

標準の AOSP リカバリ イメージが使用されている場合、ブートローダーは起動時に misc パーティションの最初の 32 バイトを読み取る必要があり、リカバリ イメージのデータが「boot-recovery」と一致する場合はリカバリ イメージで起動する必要があります。これにより、保留中のリカバリ作業(OTA の適用、データ削除の実行など)を再開して正常に完了させることができます。

リカバリに使用するフラッシュのブロックの内容と、通信するブートローダーの詳細については、bootable/recovery/bootloader_message/bootloader_message.h をご覧ください。

A/B アップデート

OEM が A/B アップデートをサポートすることを選択した場合、ブートローダーは次の条件を満たす必要があります。

  • OTA によってアップデートされるすべてのパーティションは、リカバリではなくメインシステムの起動時にアップデート可能にする必要があります。
  • A/B アップデートの場合、アップデータはブート コントロール HALをクエリし、現在使用されていないブートスロットをアップデートし、アクティブなスロットを HAL で変更し、アップデート後のオペレーティング システムで再起動します。ブート コントロール HAL の実装をご覧ください
  • A/B をサポートするすべてのパーティションの名前に接尾辞が追加されます。 これにより、ブートローダーの特定のスロットに属するパーティションが区別されます。パーティションごとに、対応する変数 has-slot: があり、値が「yes」になっています。
  • スロットはアルファベット順に a、b、c のように名前がつけられます。これらはパーティションの接尾辞 _a、_b、_c などに対応しています。
  • ブートローダーは、次のいずれかの方法でオペレーティング システムにどのスロットが起動済みであるかを通知します。
    • DT プロパティ: /firmware/android/slot_suffix または
    • コマンドライン プロパティ: androidboot.slot_suffix
  • ブートローダーは、boot_control HAL(hardware/libhardware/include/hardware/boot_control.h)をサポートする必要があります。
  • /system を A/B で起動するには、ブートローダーはコマンド ro root=/dev/[node] rootwait skip_initramfs init=/init をカーネルラインで渡す必要があります。 skip_initramfs を渡さない場合、リカバリで起動します。
  • slot-retry-count は、setActiveBootSlot コールバックまたは fastboot set_active コマンドによるブート コントロール HAL により、プラスの値(通常は「3」)にリセットされます。
  • スロットの一部であるパーティションを変更する場合、ブートローダーは「successfully booted」を消去して、当該のスロットの retry_count をリセットします。
  • また、ブートローダーは、読み込むスロットを決定する必要があります。決定フローの図については、このセクションの図をご覧ください。一般的な手順は次のとおりです。
    1. 試行するスロットを決定します。「slot-unbootable」とマークされているスロットは読み込まないでください。このスロットは、fastboot から返された値と一致しているはずです。以下、このスロットを「現在のスロット」と呼びます。
    2. 現在のスロットが slot-successful とマークされてなく、かつ slot-retry-count = 0 ですか?
      現在のスロットを「slot-unbootable」とマークし、「unbootable」とマークされてなく「slot-successful」とマークされている別のスロットを選択します。このスロットが選択されたスロットになりました。使用可能な現在のスロットがない場合は、リカバリで起動するか、ユーザーにわかりやすいエラー メッセージが表示されます。
    3. 適切な boot.img を選択し、カーネルのコマンドラインで正しいシステム パーティションのパスを指定します。
    4. リカバリを起動しない場合は、kernel コマンドラインに skip_initramfs を追加します。
    5. DT またはコマンドライン slot_suffix パラメータに値を入力します。
    6. 起動します。「slot-successful」とマークされていない場合は、slot-retry-count の値を減らします。
      ブートローダーのスロットフロー
      図 1 ブートローダーのスロットフロー
  • fastboot ユーティリティは、フラッシュ コマンドの実行時にフラッシュするパーティションを決定します。たとえば、 fastboot flash system system.img はまず current-slot 変数をクエリして、その結果をシステムに連結し、フラッシュするパーティションの名前を生成します(例: system_a、system_b など)。
  • 現在のスロットを fastboot set_active またはブート コントロール HAL の setActiveBootSlot から設定する場合、ブートローダーは現在のスロットをアップデートし、slot-unbootable を消去し、slot-successful を消去して、retry-count をリセットします。slot-unbootable を消去するための方法はこれらの方法のみです。
  • HAL から markBootSuccessful を呼び出すのは Android フレームワークの役割です。ブートローダーはパーティションを「正常に起動」としてマークしないようにする必要があります。

非 A/B アップデート

A/B アップデートができないデバイスでアップデートをサポートするには、次の条件を満たす必要があります。

  • リカバリ パーティションには、サポートされているパーティション(cache、userdata)からシステム イメージを読み取り、システム パーティションに書き込むことができるイメージが含まれている必要があります。
  • ブートローダーは直接リカバリモードで再起動する必要があります。
  • 無線イメージのアップデートがサポートされている場合、リカバリ パーティションも無線をフラッシュできるようにする必要があります。 これには、2 通りの方法があります。:
    • ブートローダーで無線をフラッシュします。 この場合、アップデートを完了するには、リカバリ パーティションからブートローダーに再起動できる必要があります。
    • リカバリ イメージで無線をフラッシュします。 この機能は、バイナリ ライブラリやユーティリティとして提供される場合があります。