Android 12 で Bootconfig を実装する

Android 12 の bootconfig 機能は、Android 11 以前で使用されていた androidboot.* カーネル コマンドライン オプションに代わるものです。bootconfig 機能は、ビルドとブートローダーから設定の詳細を Android 12 に渡すメカニズムです。

この機能により、Android ユーザー空間の設定パラメータをカーネルの設定パラメータから分離できます。長い androidboot.* カーネル パラメータを bootconfig ファイルに移動すると、カーネル コマンドラインにスペースが作成され、それを利用して後で簡単に拡張できるようになります。

カーネルと Android ユーザー空間の両方が bootconfig をサポートしている必要があります。

  • bootconfig をサポートする最初のリリース: Android 12
  • bootconfig をサポートする最初のカーネル バージョン: 12-5.4.xx カーネル

12-5.10.xx カーネル バージョンでリリースされる新しいデバイスに bootconfig 機能を実装します。デバイスをアップグレードする場合、実装する必要はありません。

例とソース

このセクションの例とソースコードからわかるように、bootconfig コードの形式は、Android 11 以前で使用されているカーネル コマンドラインの形式とわずかしか異なりません。ただし、使用するうえでは次の変更点が重要となります。

  • パラメータは、スペースではなく、改行エスケープ シーケンス \n で区切る必要があります。

ブートローダーの例

ブートローダーの例については、Cuttlefish U-boot リファレンスのブートローダー実装を参照してください。このリファレンスの 2 つの commit を以下に示します。最初の commit は、ブートヘッダー バージョンのサポートに対して uprev を行い、最新バージョンに更新します。この例では、最初の commit によって、バージョン サポートが次のバージョンの v4 に更新(uprev)されます。2 つ目の commit では 2 つの処理を行います。まず bootconfig 処理を追加し、次にランタイム時にパラメータを追加する方法を示します。

ビルド例

ベンダー ブートヘッダー v4 で vendor_boot.img をビルドするための mkbootimg の変更を示すビルド例については、mkbootimg changes for bootconfig をご覧ください。 次の処理を行う方法については、Cuttlefish の変更点をご覧ください。

実装

パートナーはブートローダーにサポートを追加し、ビルド時の androidboot.* パラメータをカーネル コマンドラインから bootconfig ファイルに移動する必要があります。この変更を実装する最善の方法は、段階的に導入することです。段階的なプロセスの実施については、段階的な実装と検証をご覧ください。

/proc/cmdline ファイルを対象に androidboot.* パラメータを検索するような変更がある場合は、代わりに /proc/bootconfig ファイルを検索するように変更してください。ro.boot.* プロパティは新しい bootconfig 値を使用して設定されるため、このプロパティを使用してコードを変更する必要はありません。

ビルドの変更

まず、ブートヘッダー バージョンに対して uprev を行い、最新バージョンに更新します。

- BOARD_BOOT_HEADER_VERSION := 3

+ BOARD_BOOT_HEADER_VERSION := 4

bootconfig カーネル コマンドライン パラメータを追加します。これにより、カーネルが bootconfig セクションを検索します。

BOARD_KERNEL_CMDLINE += bootconfig

bootconfig パラメータが、BOARD\_KERNEL\_CMDLINE からカーネル コマンドラインが作成されるのと同様に、BOARD_BOOTCONFIG 変数のパラメータから作成されます。

次のように、どの androidboot.* パラメータもそのまま移動できます。

- BOARD_KERNEL_CMDLINE += androidboot..selinux=enforcing

+ BOARD_BOOTCONFIG += androidboot..selinux=enforcing

ブートローダーの変更

ブートローダーは、カーネルに移動する前に initramfs を設定します。カーネルブート設定は bootconfig セクションを検索し、このセクションが initramfs, の最後に配置されていて、想定されているトレーラーが存在することを確認します。

ブートローダーは、ベンダーのブートイメージ ヘッダーから vendor_boot.img レイアウト情報を取得します。

bootconfig メモリ割り当てレイアウトの図

図 1. Android 12 の bootconfig のメモリ割り当て

ブートローダーによってメモリ内に bootconfig セクションが作成されます。bootconfig セクションには、次のメモリ割り当てが含まれています。

  • パラメータ
  • 4 B サイズ parameters size
  • 4 B サイズ parameters checksum
  • 12 B bootconfig マジック文字列(#BOOTCONFIG\n

これらのパラメータは、ビルド時に判明しているパラメータと、ビルド時に不明なパラメータの 2 つのソースから取得されます。不明なパラメータは追加する必要があります。

ビルド時に判明しているパラメータは、bootconfig セクションの vendor_boot イメージの末尾にパッケージ化されます。このセクションのサイズは、ベンダーのブートヘッダー フィールド vendor_bootconfig_size にバイト単位で格納されます。

ビルド時に不明なパラメータは、ブートローダーのランタイム時にのみ確認されます。これらは、bootconfig トレーラーを適用する前に bootconfig パラメータ セクションの末尾に追加する必要があります。

bootconfig トレーラーを適用した後にパラメータを追加する必要がある場合は、トレーラーを上書きして再適用します。

段階的な実装と検証

このセクションの手順に沿って、bootconfig 機能を段階的に実装します。bootconfig パラメータを追加している間は、カーネル コマンドライン パラメータはそのままにします。

以下では、段階的な実装と検証の手順について説明します。

  1. ブートローダーとビルドに変更を加え、次の手順を行います。
    1. BOARD_BOOTCONFIG 変数を使用して新しい bootconfig パラメータを追加します。
    2. デバイスを引き続き正常に起動できるように、カーネル コマンドライン パラメータをそのまま使用します。これにより、デバッグと検証が簡単になります。
  2. /proc/bootconfig の内容を確認して、処理を検証します。デバイスが起動した後、新しく追加されたパラメータが存在することを確認します。
  3. BOARD_BOOTCONFIG 変数とブートローダーを使用して、androidboot.* パラメータをカーネル コマンドラインから bootconfig に移動します。
  4. 各パラメータが /proc/bootconfig に存在し、/proc/cmdline にはないことを確認します。これを確認できれば、実装が成功したことになります。

OTA のアップグレードとダウングレードに関する考慮事項

複数の Android バージョンや複数のカーネル バージョン間で OTA のアップグレードやダウングレードを管理する場合は、特に注意が必要です。

bootconfig をサポートする最初のバージョンは Android 12 です。それより前のバージョンにダウングレードする場合は、bootconfig の代わりにカーネル コマンドライン パラメータを使用する必要があります。

カーネル バージョン 12-5.4 以降では、bootconfig がサポートされています。これより前のバージョン(11-5.4 を含む)にダウングレードする場合は、カーネル コマンドライン パラメータを使用する必要があります。

Android 11 以前から Android 12 以降にアップグレードする場合は、カーネル コマンドライン パラメータを引き続き使用できます。カーネル バージョンのアップグレードについても同様です。

トラブルシューティング

検証の手順を実行する際に、/proc/bootconfig に想定されるパラメータが表示されない場合は、logcat のカーネルログを確認します。カーネルが bootconfig をサポートしている場合、bootconfig のログエントリが必ず存在します。

ログ出力の例

$ adb logcat | grep bootconfig
02-24 17:00:07.610     0     0 I Load bootconfig: 128 bytes 9 nodes

エラーログが返された場合は、bootconfig の読み込み中に問題が発生しています。各種のエラータイプを確認するには、init/main.c を表示します。