GKI 和 GKI 模块可独立于分区的其余部分进行更新,因为 GKI 模块位于超级映像中名为 system_dlkm
的单独动态分区中。GKI 模块由 Google 使用内核构建时密钥对进行签名,并且仅与其构建时使用的 GKI 兼容。GKI 和 GKI 模块之间不具有 ABI 稳定性;为使模块在运行时能够正确加载,必须一同构建和更新 GKI 和 GKI 模块。
实现 system_dklm 分区支持
system_dlkm
分区作为另一个动态分区位于超级分区中。此分区可能包含:
- Google 构建时签名内核模块
depmod
工件
构建 system_dlkm
构建 system_dlkm
过程与构建其他动态分区类似。如需将 system_dlkm
添加到您的 build 中,请执行以下步骤:
在
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 设备和虚拟 A/B 设备,请在设备的
device.mk
文件中添加以下代码行:AB_OTA_PARTITIONS += system_dlkm
确定要复制到 system_dlkm
中的内核模块
为了让模块在运行时成功加载,必须同时构建 GKI 和 GKI 模块。因此,您必须为目标架构确定 GKI build 中的内核模块,并在平台构建期间将这些模块作为 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
分区中的模块的任何模块都会在 modules.dep
文件中为 vendor_dlkm
分区生成正确的引用。由于 modules.dep
表示的此跨分区依赖关系,因此在加载供应商模块时,系统会自动加载任何所需的 GKI 模块。
例如,如需为预构建的 GKI arm64
内核 5.15
在 system_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/lib/modules
中指向 /system_dlkm/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 提供一个 GKI VTS 测试用例,以验证 system_dlkm
分区。如需手动调用测试,请使用以下 atest
命令:
atest -c vts_dlkm_partition_test