Implement a GKI module partition

GKI and GKI modules can be updated independently from the rest of the partition because GKI modules reside on a separate dynamic partition in the super image called system_dlkm. GKI modules are signed by Google using the kernel build-time key pair and are compatible only with the GKI they're built with. There's no ABI stability between GKI and GKI modules; for modules to load correctly during runtime, GKI and GKI modules must be built and updated together.

Implement system_dklm partition support

The system_dlkm partition is located in the super partition as another dynamic partition. This partition can contain:

  • Google build-time signed kernel modules
  • depmod artifacts

Build system_dlkm

Building system_dlkm is a similar process to building other dynamic partitions. Perform the following steps to add system_dlkm to your build:

  1. In BoardConfig.mk, add the following entries:

    BOARD_USES_SYSTEM_DLKMIMAGE := true
    BOARD_SYSTEM_DLKMIMAGE_FILE_SYSTEM_TYPE := $(TARGET_RO_FILE_SYSTEM_TYPE)
    TARGET_COPY_OUT_SYSTEM_DLKM := system_dlkm
    
  2. In the partition list, add system_dlkm: BOARD_GOOGLE_SYSTEM_DYNAMIC_PARTITIONS_PARTITION_LIST := system_dlkm

  3. (Optional) For A/B and virtual A/B devices, add the following line in the device.mk file for your device:

    AB_OTA_PARTITIONS += system_dlkm
    

Identify kernel modules to copy into system_dlkm

For modules to load successfully at runtime, GKI and GKI modules must be built together. Therefore you must identify kernel modules in the GKI build for the target architecture and provide that as source for the system_dlkm partition during platform build.

For Android 13

Point BOARD_SYSTEM_DLKM_SRC to a folder containing the required GKI modules kernel object files for the device as an input to the build system to generate the system_dlkm partition. For example:

Provide the GKI modules source in a folder and point BOARD_SYSTEM_DLKM_SRC to that folder. For example:

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

At build time, modules listed in BOARD_SYSTEM_DLKM_SRC are installed in $ANDROID_PRODUCT_OUT/system_dlkm.

For Android 14

We have streamlined the implementation with the macros (BOARD_*_KERNEL_MODULES) being used for other *_dlkm partitions. The list of required GKI modules for the device should be referenced by BOARD_SYSTEM_KERNEL_MODULES macro. At build time these modules are installed in the $ANDROID_PRODUCT_OUT/system_dlkm. Any module in vendor_dlkm partition which has dependencies on the modules in system_dlkm partition generates correct references in modules.dep file for the vendor_dlkm partition. Due to the cross-partition dependencies represented by modules.dep, when a vendor module gets loaded, any required GKI module is loaded automatically.

For example, to install all GKI modules on system_dlkm partition for GKI arm64 kernel 5.15 from prebuilts:

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

Mount system_dlkm at runtime

Depending on the file system being used as a read-only file system, add the following in your fstab to mount the system_dlkm partition at runtime:

ext4 as a read-only file system

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

erofs as read-only file system

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

Partition mounting and module loading

During first_stage_init, the system_dlkm partition is mounted in the /system_dlkm as a read-only file system. On a successful mount, symbolic links at /system/lib/modules pointing to /system_dlkm/lib/modules are available.

A vendor process, such as an .rc script, can then load the kernel modules based on the order specified in modules.load. The vendor process must use the symbolic link /system/lib/modules to load the modules. If necessary, the vendor process can also load the modules at a later time.

SELinux

Every file in the system_dlkm partition is labeled with the file context of system_dlkm_file. To load the GKI modules file in the system_dlkm partition, the vendor process responsible for loading the modules needs a sepolicy in the vendor domain.

For example, dlkm_loader used by Cuttlefish to load GKI modules has the following permissions in the policy file at 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;

Validate the system-dlkm partition

Google provides a GKI VTS test case to verify the system_dlkm partition. To manually invoke the test, use the following atest command:

  atest -c vts_dlkm_partition_test