内核模块概览

使用集合让一切井井有条 根据您的偏好保存内容并对其进行分类。

内核模块有两种类型:与硬件无关的 GKI 模块和特定于硬件的供应商模块。本页将简要介绍这两种模块。

GKI 模块

某些 GKI 内核功能以模块形式提供,以减少不需要该功能的设备上的 GKI 内核内存占用量。此架构还提供一种机制,可让供应商在 KMI 冻结里程碑后纳入新的上游功能。GKI 模块由 Google 使用内核构建时密钥对进行签名,并且仅与其构建时使用的 GKI 兼容。GKI 内核和 GKI 模块之间不具有 ABI 稳定性,因此必须一同构建和更新内核和 GKI 模块,以便模块在运行时正确加载。

GKI 模块有两种逻辑类型:受保护的 GKI 模块和不受保护的 GKI 模块。

受保护的 GKI 模块

受保护的 GKI 模块由 Google 提供,各方面都不受限,加载后其行为和使用内核构建的模块类似。此外,受保护的 GKI 模块具有以下特征:

  • 受保护的 GKI 模块可以访问供应商模块或不受保护的 GKI 模块不可用的非 KMI 内核符号。
  • 受保护的 GKI 模块可以导出符号用于 KMI Surface 中,前提是这些符号已在符号列表中列出。
  • 受保护的 GKI 模块无法被供应商模块替换。

受保护的 GKI 模块是 GKI 模块的默认类型。在 KMI 冻结时,所有 GKI 模块都会被视为受到保护。

不受保护的 GKI 模块

不受保护的 GKI 模块可能会被供应商模块替换。在 KMI 冻结后,如果 GKI 团队确定供应商模块需要将默认实现替换为包含上游 Linux 中新功能的版本,受保护的 GKI 模块可能会被重新归类为不受保护的类型。在下一个 GKI 版本中,在上游代码归入 Android 通用内核 (ACK) 后,不受保护的模块将被重新归类为受保护的类型。不受保护的 GKI 模块具有以下特征:

  • 不受保护的 GKI 模块对导出的符号拥有的访问权限与供应商模块相同。
  • 不受保护的 GKI 模块无法导出受保护的 GKI 模块导出的符号。
  • 不受保护的 GKI 模块必须保留所有 KMI 接口,就像保留核心内核的组成部分一样。
  • 不受保护的 GKI 模块可能会被供应商模块替换。

供应商模块

供应商模块是合作伙伴提供的,用于实现 SoC 和设备专用功能。任何未作为 GKI 内核的一部分提供的现有内核模块都可以作为供应商模块提供。

由于 GKI 项目的主要目标之一是尽可能减少核心内核中特定于硬件的代码,供应商可能会预期 GKI 内核不包含明确管理自身硬件的模块。例如,供应商 ABC Inc. 可能会认为,若 CONFIG_ABC_SOC_SUPPORT 等配置不受支持,将无法作为内置或可加载的 GKI 模块被启用。

如果内核驱动程序或框架存在于 ACK 中,但未作为 GKI 内核的一部分提供,供应商可以修改相应驱动程序并将其作为供应商模块提供。我们不建议对非供应商专用模块进行此类修改,因为在未来版本中,GKI 内核可能会提供相同的功能。当 GKI 内核包含供应商模块提供的功能时,供应商模块将不会加载。例如,Android 11 中没有为 GKI 设置 CONFIG_GREYBUS,因此供应商可能会提供 greybus 供应商模块。不过,Android 12 中可能会将 CONFIG_GREYBUS 作为 GKI 内置或可加载的模块启用,在这种情况下,系统不会加载 greybus 供应商模块。如果内核驱动程序作为供应商模块提供,最佳实践是使用非供应商专用驱动程序的上游版本。

您可以在 vendorvendor_boot 映像中提供供应商模块。启动过程早期所需的模块必须位于 vendor_boot 中。从 vendor_boot 加载模块时会产生启动时开销。