カーネル モジュールのサポート

汎用カーネル イメージ(GKI)には、デバイスでパーティションをマウントするために必要なドライバ サポートが含まれていない場合があります。デバイスがパーティションをマウントして起動を継続できるように、第 1 ステージの init が改良されて、RAM ディスクに存在するカーネル モジュールを読み込むようになりました。RAM ディスクは、汎用の RAM ディスクと、ベンダー RAM ディスクに分割されています。ベンダー カーネル モジュールは、ベンダー RAM ディスクに格納されます。カーネル モジュールを読み込む順序は設定可能です。

モジュールの場所

RAM ディスクは、第 1 ステージの init, と、A/B デバイスおよび仮想 A/B デバイスのリカバリ イメージまたは fastbootd イメージ用のファイル システムです。これは、ブートローダーによって連結される 2 つの cpio アーカイブからなる initramfs です。ベンダーブート パーティションにベンダー RAM ディスクとして格納される最初の cpio アーカイブには、次のコンポーネントが含まれています。

  • /lib/modules/ にある第 1 ステージの init ベンダー カーネル モジュール。
  • /lib/modules/ にある modprobe 構成ファイル modules.depmodules.softdepmodules.aliasmodules.options
  • 第 1 ステージの init で読み込むモジュールとその順序を示す modules.load ファイル(/lib/modules/ 内)。
  • A/B デバイスと仮想 A/B デバイスのベンダー リカバリ カーネル モジュール(/lib/modules/ 内)。
  • A/B デバイスと仮想 A/B デバイス用に読み込むモジュールとその順序を示す modules.load.recovery/lib/modules 内)。

2 番目の cpio アーカイブは、boot.img の RAM ディスクとして GKI で提供され、最初のアーカイブの先頭に適用されます。first_stage_init と、依存するライブラリが含まれます。

第 1 ステージの init でのモジュールの読み込み

第 1 ステージの init は、RAM ディスク上の /lib/modules/ から modprobe 構成ファイルを読み込むことから始まります。次に、/lib/modules/modules.load(リカバリの場合は /lib/modules/modules.load.recovery)で指定されたモジュールのリストを読み取り、前に読み込んだファイルで指定された構成に従って各モジュールを順に読み込もうとします。ハード依存関係またはソフト依存関係を満たすために、リクエストされた順序どおりにはならないことがあります。

ビルドサポート、第 1 ステージの init

ベンダー RAM ディスク cpio にコピーするカーネル モジュールを指定するには、BOARD_VENDOR_RAMDISK_KERNEL_MODULES にリストします。ビルドはこれらのモジュールに対して depmod を実行し、結果の modprobe 構成ファイルをベンダー RAM ディスク cpio に配置します。

また、ビルドによって modules.load ファイルも作成され、ベンダー RAM ディスク cpio に保存されます。デフォルトでは、BOARD_VENDOR_RAMDISK_KERNEL_MODULES にリストされているすべてのモジュールが含まれています。ファイルの内容をオーバーライドするには、次の例のように BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD を使用します。

BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD := \
    device/vendor/mydevice-kernel/first.ko \
    device/vendor/mydevice-kernel/second.ko \
    device/vendor/mydevice-kernel/third.ko

ビルドサポート、フル Android

Android 10 以前のリリースと同様に、BOARD_VENDOR_KERNEL_MODULES にリストされているカーネル モジュールは、Android プラットフォーム ビルドによって /vendor/lib/modules のベンダー パーティションにコピーされます。プラットフォーム ビルドは、これらのモジュールに対して depmod を実行し、depmod 出力ファイルを同じ場所にあるベンダー パーティションにコピーします。/vendor からカーネル モジュールを読み込むメカニズムは、以前の Android リリースの場合と同様です。モジュールを読み込む方法とタイミングは自由に決められますが、通常は init.rc スクリプトを使用します。

ワイルドカードと統合カーネルビルド

デバイス カーネルビルドと Android プラットフォーム ビルドを組み合わせるベンダーは、上記の BOARD マクロを使用してデバイスにコピーするカーネル モジュールを指定すると、問題が発生することがあります。デバイスのプラットフォーム ビルドファイルにカーネル モジュールをリストしない場合、ベンダーはワイルドカード($(wildcard device/vendor/mydevice/*.ko)を使用できます。なお、統合カーネルビルドの場合、ワイルドカードは機能しません。これは、make が呼び出され、マクロが makefile で展開されると、カーネル モジュールがビルドされず、マクロが空になるためです。

この問題を回避するために、ベンダーはカーネルビルドで、各パーティションにコピーされるカーネル モジュールを含む zip アーカイブを作成していることがあります。BOARD_*_KERNEL_MODULES_ARCHIVE で zip アーカイブのパスを設定します。ここで * は、パーティションの名前です(例: BOARD_VENDOR_KERNEL_MODULES_ARCHIVE)。Android プラットフォーム ビルドは、この zip アーカイブを適切な場所に解凍し、モジュールに対して depmod を実行します。

カーネル モジュールの zip アーカイブには、必要に応じてプラットフォーム ビルドがアーカイブを生成できるようにする make ルールが必要です。

リカバリ

以前の Android リリースでは、リカバリに必要なカーネル モジュールが BOARD_RECOVERY_KERNEL_MODULES で指定されていました。Android 12 でも、このマクロを使用してリカバリに必要なカーネル モジュールを指定します。ただし、リカバリ カーネル モジュールは、汎用の RAM ディスク cpio ではなく、ベンダー RAM ディスク cpio にコピーされます。デフォルトでは、BOARD_RECOVERY_KERNEL_MODULES にリストされているすべてのカーネル モジュールは、第 1 ステージの init で読み込まれます。これらのモジュールのサブセットのみを読み込む場合は、BOARD_RECOVERY_KERNEL_MODULES_LOAD でサブセットの内容を指定します。

ベンダー ブート パーティション(このページで述べたベンダー RAM ディスクを含む)の作成方法については、ブート パーティションをご覧ください。