通用内核映像 (GKI) 可能不包含使设备能够装载分区所需的驱动程序支持。为了使设备能够装载分区并继续启动,增强了第一阶段 init
,用于加载 ramdisk 上的内核模块。ramdisk 被拆分为通用 ramdisk 和供应商 ramdisk。供应商内核模块存储在供应商 ramdisk 中。内核模块加载的顺序可以配置。
模块位置
ramdisk 是第一阶段 init,
的文件系统,也是 A/B 设备和虚拟 A/B 设备上的恢复/fastboot 映像的文件系统。这是一个 initramfs
,包含两个由引导加载程序串联的 cpio 归档。第一个 cpio 归档(作为供应商 ramdisk 存储在供应商启动分区中)包含以下组件:
- 第一阶段
init
供应商内核模块,位于/lib/modules/
。 modprobe
配置文件,位于/lib/modules/
:modules.dep
、modules.softdep
、modules.alias
、modules.options
。- 一个
modules.load
文件,用于指示在第一阶段 init 期间加载的模块及相应的加载顺序,位于/lib/modules/
。 - 供应商恢复内核模块,用于 A/B 和虚拟 A/B 设备,位于
/lib/modules/
。 modules.load.recovery
,用于指示要加载的模块及相应的加载顺序,用于 A/B 和虚拟 A/B 设备,位于/lib/modules
。
第二个 cpio 归档(作为 boot.img 的 ramdisk 随 GKI 提供,应用在第一个 cpio 归档之上)包含 first_stage_init
及其依赖的库。
在第一阶段 init 期间加载模块
第一阶段 init
首先从 ramdisk 上的 /lib/modules/
读取 modprobe 配置文件。接下来,读取 /lib/modules/modules.load
(在恢复过程中,则为 /lib/modules/modules.load.recovery
)中指定的模块列表,并尝试按照之前加载的文件中指定的配置,依次加载各个模块。为了满足硬依赖项或软依赖项的要求,实际执行顺序可以不同于请求的顺序。
build 支持,第一阶段 init
如需指定要复制到供应商 ramdisk cpio 的内核模块,请在 BOARD_VENDOR_RAMDISK_KERNEL_MODULES
中将其列出。build 会对这些模块运行 depmod
,并将生成的 modprobe 配置文件放在供应商 ramdisk cpio 中。
build 还会创建一个 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
build 支持,所有 Android 版本
与在 Android 10 及更低版本中一样,BOARD_VENDOR_KERNEL_MODULES
中列出的内核模块会由 Android 平台 build 复制到 vendor 分区中的 /vendor/lib/modules
。平台 build 会对这些模块运行 depmod
,并将 depmod
输出文件复制到 vendor 分区中的相同位置。从 /vendor
加载内核模块的机制与以前的 Android 版本相同。您可以决定如何以及何时加载这些模块,尽管这通常是使用 init.rc
脚本来完成的。
通配符和集成的内核 build
如果供应商将设备内核 build 与 Android 平台 build 相结合,可能就会无法使用上述 BOARD
宏来指定要复制到设备的内核模块。如果供应商不希望在设备的平台 build 文件中列出内核模块,可以使用通配符 ($(wildcard device/vendor/mydevice/*.ko
)。请注意,如果集成了内核 build,该通配符会不起作用,因为调用 make 并在 makefile 中展开宏时,内核模块尚未构建,因此宏为空。
为了解决此问题,供应商可以让其内核 build 创建一个 zip 归档文件,其中包含要复制到每个分区的内核模块。将该 zip 归档文件的路径设置到 BOARD_*_KERNEL_MODULES_ARCHIVE
,其中 *
为分区的名称(例如 BOARD_VENDOR_KERNEL_MODULES_ARCHIVE
)。Android 平台 build 会将此 zip 归档文件解压缩到适当的位置,并对模块运行 depmod
。
内核模块 zip 归档文件应包含一条 make 规则,用于确保平台 build 可以在需要时生成归档文件。
恢复
在之前的 Android 版本中,恢复所需的内核模块在 BOARD_RECOVERY_KERNEL_MODULES
中指定。在 Android 12 中,恢复所需的内核模块仍使用该宏指定。但是,恢复内核模块会被复制到供应商 ramdisk cpio,而不是通用的 ramdisk cpio。默认情况下,BOARD_RECOVERY_KERNEL_MODULES
中列出的所有内核模块都会在第一阶段 init
期间加载。如果您只想加载这些模块中的一部分,请在 BOARD_RECOVERY_KERNEL_MODULES_LOAD
中指定这一部分的内容。
相关文档
如需了解如何创建供应商启动分区(其中包含本页中提及的供应商 ramdisk),请参阅启动分区。