如何使用符号列表

为了减少需要作为稳定版维护的符号的数量和类型,GKI 内核具有将导出符号限制在模块所需符号范围内的功能。对于外部编译的模块,您需要有一个模块使用的符号列表,以便 GKI 内核可以导出这些符号。例如,模块用于 Cuttlefish 的符号存储在 android/abi_gki_aarch64_virtual_device 中。

添加用于生成符号列表的目标

符号列表由 kernel_abi 目标生成。使用以下选项将该目标添加到设备的 BUILD.bazel

  • name

    应使用 <kernel_build>_abi 的格式。

  • kernel_build

    应包含设备 kernel_build 目标的名称。

您也可以使用以下选项:

  • kernel_modules

    树外模块的目标列表。此处不应包含树内模块。请参阅准备树内模块以进行符号提取

  • kmi_symbol_list_add_only

    此选项可防止移除未使用的符号。符号移除操作仅在 KMI 稳定阶段的特定时间内允许执行,当 KMI 进入冻结阶段后不允许执行。

    如果您为多个不同的设备使用相同的符号列表,此选项也很有用。这样就不会仅移除设备 A 使用的符号而不移除设备 B 使用的符号。

  • module_grouping

    如果此选项设置为 True 或未指定,则符号列表将根据引用符号的内核模块对符号进行分组。否则,符号列表将只是包含所有内核模块所用符号的常规排序列表。

如需查看示例,请参阅 common-modules/virtual-device/BUILD.bazel

kernel_abi(
    name = "virtual_device_aarch64_abi",
    kernel_build = ":virtual_device_aarch64",
    kernel_modules = [
        ":virtual_device_aarch64_external_modules",
    ],
    kmi_symbol_list_add_only = True,
)

另请参阅有关 Kleaf 中的 kernel_abi 目标的参考文档

准备树内模块以进行符号提取

如需准备树内模块以进行符号提取,请在 kernel_build 目标的 module_outs 属性中列出供应商专用的树内模块。有关示例,请参阅 _VIRT_COMMON_MODULES 及其使用方式。此列表不得包含 GKI 模块。

请将这些模块配置为无符号,否则符号列表可能为空。为此,请将下面这行代码添加到内核配置 fragment 中:

# CONFIG_MODULE_SIG_ALL is not set

如需查看示例,请参阅 common-modules/virtual-device/virtual_device_core.fragment

向设备内核 build 添加设备符号列表

将属性 kmi_symbol_list 添加到设备 BUILD.bazel 中定义的 kernel_build 目标。符号列表的名称应使用 //common:android/abi_gki_<arch>_<device> 的格式。如需查看示例,请参阅 common-modules/virtual-device/BUILD.bazel

kernel_build(
    name = "virtual_device_aarch64",
    base_kernel = "//common:kernel_aarch64",
    kmi_symbol_list = "//common:android/abi_gki_aarch64_virtual_device",
    ...
    module_outs = _VIRT_COMMON_MODULES + _VIRT_AARCH64_MODULES,
)

创建并提交初始符号列表

common/android/abi_gki_<arch>_<device> 中创建一个空符号列表。对于以上示例,相关命令如下:

touch common/android/abi_gki_aarch64_virtual_device

将此文件添加到基础 GKI 内核 build 的 additional_kmi_symbol_lists 中。例如,将 //common:android/abi_gki_aarch64_virtual_device 添加到 aarch64_additional_kmi_symbol_lists 文件组(在 common/BUILD.bazel 中声明)。

更新设备符号列表以填充新的符号列表,并将其发送到 Android 通用内核仓库。

更新设备符号列表

kernel_buildmodule_outskernel_abikernel_modules 中的模块所使用的所有核心内核符号都应包含在符号列表中。为此,您可以运行带有 _update_symbol_list 后缀的 kernel_abi 目标。例如,以下命令会更新 //common-modules/virtual-device:virtual_device_aarch64 的符号列表:

tools/bazel run //common-modules/virtual-device:virtual_device_aarch64_abi_update_symbol_list

向 ACK 发送符号列表更新

将包含符号列表更改的补丁发送到 Android 通用内核 Gerrit,使新符号成为 KMI 的一部分。

提交消息中应包含已添加或已移除的符号的列表。您可以手动编写此列表以进行小幅的符号列表更新,也可以在更新参考 ABI 表示法后使用 $DIST_DIR/abi.report.short 报告。

虽然您不需要在发送符号列表更新之前更新参考 ABI 表示法,但这样做可以免去额外的提交前步骤,并更快地让更改做好提交准备。在任何情况下,提交前测试中都会执行这项检查并根据需要进行更新。

旧版本(Android 12 及更低版本)

使用 build_abi.sh 工具,如下所示:

BUILD_CONFIG=path/to/build.config.device build/build_abi.sh --update-symbol-list

在此示例中,build.config.device 必须包含以下配置选项:

  • vmlinux

    必须是 FILES 列表的一部分。这可以通过添加 build.config.aarch64 来实现。

  • KMI_SYMBOL_LIST

    必须设置并使其指向要更新的 KMI 符号列表。

更新设备符号列表后,您还需要在 GKI build (common/build.config.gki.aarch64) 中反映这些更改:

  • 将更新后的符号列表复制到 common/android/abi_gki_aarch64_<device>

  • 检查 common/build.config.gki.aarch64 中的 ADDITIONAL_KMI_SYMBOL_LISTS 是否包含 android/abi_gki_aarch64_<device>

  • 将符号列表更新发送到 ACK