GKI 和 GKI 模块可以独立于分区的其余部分进行更新,因为 GKI 模块位于超级镜像中名为 system_dlkm
的单独动态分区上。GKI 模块由 Google 使用内核构建时密钥对进行签名,并且仅与构建它们的 GKI 兼容。GKI 和 GKI 模块之间没有 ABI 稳定性;为了使模块在运行时正确加载,GKI 和 GKI 模块必须一起构建和更新。
实现 system_dlkm 分区支持
system_dlkm
分区位于超级分区中,作为另一个动态分区。此分区可以包含
- Google 构建时签名的内核模块
depmod
工件
构建 system_dlkm
构建 system_dlkm
与构建其他动态分区类似。执行以下步骤以将 system_dlkm
添加到您的构建
在
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
在分区列表中,添加
system_dlkm
:BOARD_GOOGLE_SYSTEM_DYNAMIC_PARTITIONS_PARTITION_LIST := system_dlkm
(可选)对于 A/B 和 Virtual A/B 设备,在设备的
device.mk
文件中添加以下行AB_OTA_PARTITIONS += system_dlkm
确定要复制到 system_dlkm
中的内核模块
为了使模块在运行时成功加载,GKI 和 GKI 模块必须一起构建。因此,您必须在 GKI 构建中为目标架构确定内核模块,并在平台构建期间将其作为 system_dlkm
分区的源提供。
对于 Android 13
将 BOARD_SYSTEM_DLKM_SRC
指向一个文件夹,该文件夹包含设备所需的 GKI 模块内核目标文件,作为构建系统的输入,以生成 system_dlkm
分区。例如
在文件夹中提供 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
我们使用宏 (BOARD_*_KERNEL_MODULES
) 精简了实现,这些宏也用于其他 *_dlkm
分区。设备所需的 GKI 模块列表应由 BOARD_SYSTEM_KERNEL_MODULES
宏引用。在构建时,这些模块会安装在 $ANDROID_PRODUCT_OUT/system_dlkm
中。vendor_dlkm
分区中任何依赖于 system_dlkm
分区中模块的模块都会在 vendor_dlkm
分区的 modules.dep
文件中生成正确的引用。由于 modules.dep
表示的跨分区依赖关系,当加载供应商模块时,任何所需的 GKI 模块都会自动加载。
例如,要从预构建版本在 system_dlkm
分区上为 GKI arm64
内核 5.15
安装所有 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 使用的 dlkm_loader
加载 GKI 模块在 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 提供了一个 GKI VTS 测试用例来验证 system_dlkm
分区。要手动调用测试,请使用以下 atest
命令
atest -c vts_dlkm_partition_test