如何更新GKI内核公共区域向厂商及其他区域导出的符号列表?
解决Android GKI公共区域函数导出给厂商模块的问题
核心逻辑:别手动改ABI文件,用官方脚本自动生成
手动修改abi_gki_aarch64和abi_gki_aarch64.xml无效的原因很明确:这两个文件是通过build_abi.sh脚本自动生成的,手动修改的内容会被脚本覆盖,而且XML里的CRC校验值是脚本根据函数签名自动计算的,手动填肯定不对。
具体操作步骤
标记要导出的公共函数
在你开发的公共区域模块代码里,给需要开放的注册函数加上导出标记:- 如果允许非GPL厂商模块调用,用:
EXPORT_SYMBOL(my_public_register_func); - 只允许GPL兼容的厂商模块调用,用:
EXPORT_SYMBOL_GPL(my_public_register_func);
注意:函数不能是static类型,否则无法被外部模块访问。
- 如果允许非GPL厂商模块调用,用:
运行
build_abi.sh生成更新后的ABI文件- 找到内核源码中的
build_abi.sh脚本(通常路径是build/scripts/abi或kernel/build/scripts/abi) - 确保内核已经完成一次完整配置和编译(脚本需要依赖编译后的符号表)
- 执行脚本生成aarch64架构的ABI文件:
./build_abi.sh --arch aarch64
脚本会自动扫描所有带EXPORT标记的函数,生成最新的
abi_gki_aarch64和abi_gki_aarch64.xml,包括正确的CRC校验值。- 找到内核源码中的
验证导出结果
- 打开生成的
abi_gki_aarch64文件,确认你的目标函数已经在列表中 - 查看
abi_gki_aarch64.xml,对应的函数条目里的CRC值已经由脚本自动计算填充,无需手动修改
- 打开生成的
常见问题排查
- 脚本运行后找不到目标函数:
- 检查函数是否真的用EXPORT_SYMBOL/EXPORT_SYMBOL_GPL标记,且没有被编译优化(比如函数被定义为static,或者内核配置中禁用了该模块)
- 确认内核编译时开启了
CONFIG_KALLSYMS选项,脚本需要读取符号信息才能生成ABI列表
- 厂商模块仍无法调用:
- 在厂商模块代码中用
extern声明该函数:extern int my_public_register_func(...); - 如果用了
EXPORT_SYMBOL_GPL,厂商模块必须在代码中添加MODULE_LICENSE("GPL")才能合法调用
- 在厂商模块代码中用
内容的提问来源于stack exchange,提问作者uraganu1
相关产品推荐
相关产品推荐

