linux export_symbol: Unknown symbol

项目场景:

一份源代码支持多个产品类别,多个产品类别的硬件传感器列表都是相差不大。能不能把硬件传感器的linux驱动代码作为公共代码(common),提供个多个产品类别使用呢?


问题描述

在这里插入图片描述
现在的问题:“公共的传感器驱动” 代码中,需要调用 “产品类别” 目录中定义的函数。这时候编译出来的内核模块运行起来就会报错:“公共的传感器驱动” 代码中无法调用“产品类别” 目录中定义的函数,即使是通过 EXPORT_SYMBOL_GPL 导出的函数也没用。

在这里插入图片描述


原因分析:

在这里插入图片描述
可以看到:其中一个 .c 源代码定义了函数 common_lpc_to_cpld_get,并且导出符号:EXPORT_SYMBOL_GPL(common_lpc_to_cpld_get); 另外一个 .c 源代码,负责调用该函数,并且在代码也声明了该函数属于外部定义的函数:extern int common_lpc_to_cpld_get(int reg);


解决方案:

在原因分析的截图中,可以看到,common_lpc_to_cpld_get 函数确实是存在符号表中的。

在这里插入图片描述
我们还看到,“公共的传感器驱动” 代码中编译也会产生符号表。但是这个符号表的内容为空。
在这里插入图片描述

因此,我们断定:因为有两个符号表,并且两个符号表没有产生联系,所以才导致 “公共的传感器驱动”代码找不到相应的导出函数符号。

我们可以使用 KBUILD_EXTRA_SYMBOLS 符号进行 makefile 编译,如在 “公共的传感器驱动”的 makefile 文件使用语句:KBUILD_EXTRA_SYMBOLS=/modules/Module.symvers ,就可以连接 “产品类别”目录中的符号表。

在这里插入图片描述

make modules -C $(KERNEL_SRC)/build  M=$(MOD_SRC_DIR)/$(COMMON_DIR)/$${cpu}/  KBUILD_EXTRA_SYMBOLS=$(MOD_SRC_DIR)/$${mod}/modules/Module.symvers

可以看到编译后,原先为空的符号表中,现在已经填入了链接的modules/Module.symvers 符号表。这样内核模块运行的时候,就能正常找到符号了。

在这里插入图片描述


参考链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值