How to work with symbol lists

To reduce the surface of symbols and types that need to be maintained as stable, the GKI kernel has functionality to limit exported symbols to only those that are needed by modules. For externally compiled modules, you need to have a list of used symbols to allow them to be exported by the GKI kernel. For example, symbols used by modules for Cuttlefish are stored in android/abi_gki_aarch64_virtual_device.

Add a target for the symbol list generation

Symbol lists are generated by the kernel_abi target. Add this target to the device BUILD.bazel with the following options:

  • name

    Should be in the format of <kernel_build>_abi.

  • kernel_build

    Should contain the name of the device kernel_build target.

You can also use the following options:

  • kernel_modules

    List of the targets for out-of-tree modules. In-tree modules shouldn't be included here. Refer to Prepare in-tree modules for symbol extraction.

  • kmi_symbol_list_add_only

    This option prevents the removal of unused symbols. Symbol removal is only permitted at specific times during KMI stabilization and is not allowed once the KMI is frozen.

    This is also useful when you use the same symbol list for multiple different devices. This way it won't remove symbols used by device A but not device B.

  • module_grouping

    If True or unspecified, then the symbol list will group symbols based on the kernel modules that reference the symbol. Otherwise the symbol list will simply be a sorted list of symbols used by all the kernel modules.

See common-modules/virtual-device/BUILD.bazel for example:

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,
)

Also see reference documentation on kernel_abi target in Kleaf.

Prepare in-tree modules for symbol extraction

To prepare in-tree modules for symbol extraction, list vendor-specific in-tree modules in a module_outs attribute of the kernel_build target. See _VIRT_COMMON_MODULES and its usage for an example. Don't include GKI modules in this list.

Configure these modules to be unsigned, otherwise the symbol list might be empty. To do so, add this line to your kernel config fragments:

# CONFIG_MODULE_SIG_ALL is not set

See common-modules/virtual-device/virtual_device_core.fragment for example.

Add a device symbol list to the device kernel build

Add attribute kmi_symbol_list to the kernel_build target defined in the device BUILD.bazel. The name of the symbol list should be in the format of //common:android/abi_gki_<arch>_<device>. See common-modules/virtual-device/BUILD.bazel, for example:

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,
)

Create and submit an initial symbol list

Create an empty symbol list at common/android/abi_gki_<arch>_<device>. For the example above the command would be:

touch common/android/abi_gki_aarch64_virtual_device

Add this file to additional_kmi_symbol_lists of the base GKI kernel build. For example, //common:android/abi_gki_aarch64_virtual_device is added to the aarch64_additional_kmi_symbol_lists filegroup, declared in common/BUILD.bazel.

Update the device symbol list to fill the new symbol list and send it to the Android Common Kernel repository.

Update a device symbol list

All core kernel symbols used by modules in module_outs of kernel_build and kernel_modules of kernel_abi should be included in the symbol list. This can be done by running the kernel_abi target with the _update_symbol_list suffix. For example, the following command updates the symbol list for //common-modules/virtual-device:virtual_device_aarch64:

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

Send a symbol list update to ACK

Send a patch with the symbol list change to the Android Common Kernel gerrit to make the new symbols part of the KMI.

The commit message should include a list of added or removed symbols. You can either write this list manually for a small symbol list update or use $DIST_DIR/abi.report.short report after updating the reference ABI representation.

While updating the reference ABI representation before sending a symbol list update is not required, it may eliminate extra presubmit steps and make the change ready to submit faster. In any case, it will be checked and updated if necessary during presubmit.

Older versions (Android 12 and lower)

Use build_abi.sh tool as follows:

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

In this example, build.config.device must include these configuration options:

  • vmlinux

    Must be part of the FILES list. This can be done by including build.config.aarch64.

  • KMI_SYMBOL_LIST

    Must be set and pointed at the KMI symbol list to update.

After updating the device symbol list you also need to reflect these changes in the GKI build (common/build.config.gki.aarch64):

  • Copy the updated symbol list to common/android/abi_gki_aarch64_<device>.

  • Check that android/abi_gki_aarch64_<device> is included in ADDITIONAL_KMI_SYMBOL_LISTS in common/build.config.gki.aarch64.

  • Send symbol list update to ACK.