使用符号列表

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

为符号列表生成添加目标

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

  • 名称

    应采用 <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 模块。

将这些模块配置为未签名,否则符号列表可能为空。为此,请将此行添加到您的内核配置片段

# CONFIG_MODULE_SIG_ALL is not set

有关示例,请参阅 common-modules/virtual-device/virtual_device_core.fragment

将设备符号列表添加到设备内核构建

将属性 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 内核构建的 additional_kmi_symbol_lists 中。例如,//common:android/abi_gki_aarch64_virtual_device 被添加到 common/BUILD.bazel 中声明的 aarch64_additional_kmi_symbol_lists 文件组。

更新设备符号列表以填充新的符号列表并将其发送到 Android Common Kernel 存储库。

更新设备符号列表

模块中使用的所有核心内核符号(在 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 Common Kernel 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 构建 (common/build.config.gki.aarch64) 中反映这些更改

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

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

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