GKI モジュール パーティションの実装

GKI と GKI モジュールは、パーティションの残りの部分とは別に更新できます。これは、GKI モジュールが system_dlkm と呼ばれるスーパー イメージの別の動的パーティションに存在するためです。GKI モジュールは、カーネルビルド時間の鍵ペアを使用して Google によって署名され、ビルドされた GKI とのみ互換性があります。GKI と GKI モジュールの間に ABI の安定性はありません。ランタイム時にモジュールを正しく読み込むには、GKI と GKI モジュールを一緒にビルドして更新する必要があります。

system_dlkm パーティションのサポートを実装する

system_dlkm パーティションは、別の動的パーティションとして super パーティションに配置されています。このパーティションには次のものを含めることができます。

  • Google ビルド時の署名済みカーネル モジュール
  • depmod のアーティファクト

system_dlkm をビルドする

system_dlkm をビルドするプロセスは、他の動的パーティションをビルドするプロセスと同様です。ビルドに system_dlkm を追加する手順は次のとおりです。

  1. BoardConfig.mk に、次のエントリを追加します。

    BOARD_USES_SYSTEM_DLKMIMAGE := true
    BOARD_SYSTEM_DLKMIMAGE_FILE_SYSTEM_TYPE := $(TARGET_RO_FILE_SYSTEM_TYPE)
    TARGET_COPY_OUT_SYSTEM_DLKM := system_dlkm
    
  2. パーティション リストに system_dlkm: BOARD_GOOGLE_SYSTEM_DYNAMIC_PARTITIONS_PARTITION_LIST := system_dlkm を追加します。

  3. (省略可)A/B デバイスと仮想 A/B デバイスの場合は、デバイスの device.mk ファイルに次の行を追加します。

    AB_OTA_PARTITIONS += system_dlkm
    

system_dlkm にコピーするカーネル モジュールを特定する

ランタイムにモジュールを正常に読み込むには、GKI と GKI モジュールを一緒にビルドする必要があります。したがって、ターゲット アーキテクチャの GKI ビルド内のカーネル モジュールを特定し、プラットフォームのビルド中に system_dlkm パーティションのソースとして指定する必要があります。

Android 13 の場合

system_dlkm パーティションを生成するビルド システムへの入力として、デバイスに必要な GKI モジュール カーネル オブジェクト ファイルを含むフォルダを BOARD_SYSTEM_DLKM_SRC が指すようにします。次に例を示します。

GKI モジュールのソースをフォルダに追加し、そのフォルダを BOARD_SYSTEM_DLKM_SRC が指すようにします。次に例を示します。

  BOARD_SYSTEM_DLKM_SRC := kernel/prebuilts/5.10/arm64/system_dlkm_staging

ビルド時に、BOARD_SYSTEM_DLKM_SRC にリストされているモジュールが $ANDROID_PRODUCT_OUT/system_dlkm にインストールされます。

Android 14 の場合

他の *_dlkm パーティションに使用されているマクロ(BOARD_*_KERNEL_MODULES)により、実装を効率化しました。デバイスに必要な GKI モジュールのリストは、BOARD_SYSTEM_KERNEL_MODULES マクロで参照する必要があります。ビルド時に、これらのモジュールが $ANDROID_PRODUCT_OUT/system_dlkm にインストールされます。system_dlkm パーティション内のモジュールと依存関係を持つ vendor_dlkm パーティション内のモジュールはすべて、vendor_dlkm パーティションの modules.dep ファイル内に正しい参照を生成します。modules.dep で表されるこのクロス パーティションの依存関係により、ベンダー モジュールが読み込まれると、必要な GKI モジュールが自動的に読み込まれます。

たとえば、ビルド済みの GKI arm64 カーネル 5.15system_dlkm パーティションに、すべての GKI モジュールをインストールするには、次のようにします。

 BOARD_SYSTEM_KERNEL_MODULES := $(wildcard kernel/prebuilts/5.15/arm64/*.ko)

ランタイムに system_dlkm をマウントする

読み取り専用のファイル システムとして使用されているファイル システムに応じて、fstab に以下を追加して、ランタイムに system_dlkm パーティションをマウントします。

ext4 が読み取り専用のファイル システムの場合

  system_dlkm /system_dlkm ext4 noatime,ro,errors=panic wait,logical,first_stage_mount,slotselect,avb

erofs が読み取り専用のファイル システムの場合

  system_dlkm /system_dlkm erofs ro wait,logical,first_stage_mount,slotselect,avb

パーティションのマウントとモジュールの読み込み

first_stage_init の間に、system_dlkm パーティションが読み取り専用ファイル システムとして /system_dlkm にマウントされます。マウントが正常に完了すると、/system_dlkm/lib/modules を指す /system/lib/modules のシンボリック リンクが使用可能になります。

ベンダー プロセス(.rc スクリプトなど)は、その後、modules.load で指定された順序に基づいてカーネル モジュールを読み込むことができます。ベンダー プロセスでは、シンボリック リンク /system/lib/modules を使用してモジュールを読み込む必要があります。必要に応じて、ベンダー プロセスは後でモジュールを読み込むこともできます。

SELinux

system_dlkm パーティション内のすべてのファイルには、system_dlkm_file のファイル コンテキストでラベル付けされます。system_dlkm パーティションの GKI モジュール ファイルを読み込むには、モジュールの読み込みを担当するベンダー プロセスに、ベンダー ドメインの sepolicy が必要です。

たとえば、Cuttlefish が GKI モジュールを読み込むために使用する dlkm_loader には、shared/sepolicy/vendor/dlkm_loader.te のポリシー ファイルに次の権限があります。

allow dlkm_loader self:capability sys_module;
allow dlkm_loader system_dlkm_file:dir r_dir_perms;
allow dlkm_loader system_dlkm_file:file r_file_perms;
allow dlkm_loader system_dlkm_file:system module_load;

system_dlkm パーティションを検証する

Google では、system_dlkm パーティションを検証するための GKI VTS テストケースを用意しています。テストを手動で呼び出すには、次の atest コマンドを使用します。

  atest -c vts_dlkm_partition_test