通用内核映像 (GKI) 可能不包含使设备能够挂载分区所需的驱动程序支持。为了使设备能够挂载分区并继续启动,第一阶段 init
得到增强,可以加载 ramdisk 上存在的内核模块。ramdisk 分为通用 ramdisk 和供应商 ramdisk。供应商内核模块存储在供应商 ramdisk 中。内核模块的加载顺序是可配置的。
模块位置
ramdisk 是第一阶段 init
以及 A/B 和虚拟 A/B 设备上 recovery/fastbootd 映像的文件系统。它是一个 initramfs
,由两个 cpio 归档文件组成,这两个文件由引导加载程序连接而成。第一个 cpio 归档文件作为供应商 ramdisk 存储在 vendor-boot 分区中,包含以下组件
- 第一阶段
init
供应商内核模块,位于/lib/modules/
中。 modprobe
配置文件,位于/lib/modules/
中:modules.dep
、modules.softdep
、modules.alias
、modules.options
。modules.load
文件,指示在第一阶段 init 期间要加载哪些模块以及加载顺序,位于/lib/modules/
中。- 供应商 recovery-kernel 模块,适用于 A/B 和虚拟 A/B 设备,位于
/lib/modules/
中 modules.load.recovery
,指示要加载的模块以及加载顺序,适用于 A/B 和虚拟 A/B 设备,位于/lib/modules
中。
第二个 cpio 归档文件与 GKI 一起作为 boot.img 的 ramdisk 提供,并在第一个 cpio 归档文件之上应用,其中包含 first_stage_init
及其依赖的库。
第一阶段 init 中的模块加载
第一阶段 init
首先从 ramdisk 上的 /lib/modules/
读取 modprobe 配置文件。接下来,它读取 /lib/modules/modules.load
(如果是 recovery,则为 /lib/modules/modules.load.recovery
)中指定的模块列表,并尝试按照顺序加载每个模块,并遵循先前加载的文件中指定的配置。为了满足硬依赖或软依赖关系,请求的顺序可能会有所偏差。
构建支持,第一阶段 init
要指定要复制到供应商 ramdisk cpio 中的内核模块,请在 BOARD_VENDOR_RAMDISK_KERNEL_MODULES
中列出它们。构建过程会对这些模块运行 depmod
,并将生成的 modprobe 配置文件放入供应商 ramdisk cpio 中。
构建过程还会创建一个 modules.load
文件,并将其存储在供应商 ramdisk 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 及更低版本的情况一样,Android 平台构建会将 BOARD_VENDOR_KERNEL_MODULES
中列出的内核模块复制到供应商分区中的 /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 版本中,recovery 所需的内核模块在 BOARD_RECOVERY_KERNEL_MODULES
中指定。在 Android 12 中,recovery 所需的内核模块仍然使用此宏指定。但是,recovery 内核模块被复制到供应商 ramdisk cpio,而不是通用 ramdisk cpio。默认情况下,BOARD_RECOVERY_KERNEL_MODULES
中列出的所有内核模块都在第一阶段 init
期间加载。如果您只想加载这些模块的子集,请在 BOARD_RECOVERY_KERNEL_MODULES_LOAD
中指定该子集的内容。
相关文档
要了解有关创建供应商启动分区(其中包含本页提及的供应商 ramdisk)的信息,请参阅启动分区。