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 の変更点をご覧ください。
- ベンダー ブートヘッダー バージョン v4 を使用(または uprev)する。
- bootconfig をカーネル コマンドラインに追加し、選択したパラメータを bootconfig に移す。
実装
パートナーはブートローダーにサポートを追加し、ビルド時の androidboot.* パラメータをカーネル コマンドラインから bootconfig ファイルに移動する必要があります。この変更を実装する最善の方法は、段階的に導入することです。段階的なプロセスの実施については、段階的な実装と検証をご覧ください。
/proc/cmdline ファイルを対象に androidboot.* パラメータを検索するような変更がある場合は、代わりに /proc/bootconfig ファイルを検索するように変更してください。ro.boot.* プロパティは新しい bootconfig 値を使用して設定されるため、このプロパティを使用してコードを変更する必要はありません。
ビルドの変更
まず、ブートヘッダー バージョンに対して uprev を行い、バージョン 4 に更新します。
- 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 レイアウト情報を取得します。
図 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 パラメータを追加している間は、カーネル コマンドライン パラメータはそのままにします。
以下では、段階的な実装と検証の手順について説明します。
- ブートローダーとビルドに変更を加え、次の手順を行います。
BOARD_BOOTCONFIG変数を使用して新しい bootconfig パラメータを追加します。- デバイスを引き続き正常に起動できるように、カーネル コマンドライン パラメータをそのまま使用します。これにより、デバッグと検証が簡単になります。
/proc/bootconfigの内容を確認して、処理を検証します。デバイスが起動した後、新しく追加されたパラメータが存在することを確認します。BOARD_BOOTCONFIG変数とブートローダーを使用して、androidboot.*パラメータをカーネル コマンドラインから bootconfig に移動します。- 各パラメータが
/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 を表示します。