EXPORT_SYMBOL和EXPORT_SYMBOL_GPL使用

博客介绍了Linux内核模块中EXPORT_SYMBOL和EXPORT_SYMBOL_GPL的用途。这两个宏用于将模块的符号导出到内核符号表,允许其他模块调用。EXPORT_SYMBOL导出的符号不受GPL许可限制,而EXPORT_SYMBOL_GPL仅限GPL许可的模块使用。在使用这些导出符号时,需要包含特定的头文件,并在Makefile中配置KBUILD_EXTRA_SYMBOLS来指定模块间的依赖。文章还提到了模块编译过程中的module.symvers文件及其作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

EXPORT_SYMBOLEXPORT_SYMBOL_GPL作用

        用于导出符号到内核符号表中(内核符号表可通过 ‘cat /proc/kallsyms’ 查看),导出的符号可以被其它模块调用,调用前需要先声明。

        确切的说在使用 EXPORT_SYMBOL 或 EXPORT_SYMBOL_GPL 的模块文件中要包含<linux/module.h>头文件,在使用导出函数的模块中也要包含这个头文件,同时用extern 声明一下。

        如果mod2用到mod1的函数,因为是两个模块,在mod1里用EXPORT_SYMBOL_GPL导出链接,会在当前目录下生成module.symvers文件,可以通过cat module.symvers 查看内容(普通用户看到的前面的地址都是0,root权限才能看到具体的地址),但是mod2编译的时候找这个文件的时候会先从内核里找,然后从makefile中M=所指定的路径(等效于变量KBUILD_EXTMOD的值)找,再从kbuild_extra_symbols里找。

        因为mod1是自己编译的模块,内核和当前目录肯定是没有module.symvers的,这种情况只需要在Makefile文件中定义一下 KBUILD_EXTRA_SYMBOLS += mod1 module.symvers的绝对路径,编译mod2即可。或者两个mod一起编译,不要分开编译。

        通过 EXPORT_SYMBOL 导出的符号可以被包含GPL许可权的模块和不包含GPL许可权的模块调用;通过 EXPORT_SYMBOL_GPL 导出的符号只能被包含GPL许可权的模块调用,否则会报错 FATAL: modpost: GPL-incompatible module ***.ko uses GPL-only symbol '***

        

<think>好的,我现在需要解决用户遇到的modpost错误,也就是GPL不兼容模块gw5a_copy.ko使用GPL-only符号'platform_driver_unregister'的问题。首先,我得回忆一下Linux内核模块的许可证相关机制。 根据用户提供的引用[1],出现类似错误是因为模块的许可证声明不符合GPL,而内核中的某些符号(比如这里的platform_driver_unregister)被标记为GPL-only,只有声明为GPL兼容的模块才能使用这些符号。因此,我需要检查模块的许可证声明是否正确。 接下来,用户提供的引用[4]提到,高版本内核中接口有变化,可能需要调整代码。这里可能需要确认platform_driver_unregister的使用是否符合当前内核版本的要求,比如函数原型或相关结构体是否有变化。不过,许可证问题更可能是主要原因。 然后,解决方案方面,第一步应该是修改模块的许可证声明。通常在模块代码的最后会有MODULE_LICENSE("...")的宏,需要将其改为"GPL"或者兼容的许可证,如"GPL v2"等。这样modpost在检查时就会允许模块使用GPL-only的符号。 如果用户确实不能将模块改为GPL许可证,可能需要寻找替代函数或重构代码,避免直接调用GPL-only的符号。但根据引用[4]中的情况,高版本内核可能已经移除了非GPL的替代接口,所以这条路可能行不通,只能调整许可证声明。 另外,检查Makefile是否正确,确保编译时使用的内核源码路径正确,如引用[3]中的KERN_DIR设置是否正确。虽然这可能不是导致许可证错误的原因,但确保编译环境正确有助于排除其他潜在问题。 最后,用户可能需要重新编译并安装模块,测试是否解决了问题。如果仍然出现错误,可能需要进一步审查代码中是否有其他依赖GPL-only符号的地方,或者内核版本升级带来的其他接口变化。</think>### 解决方案:GPL不兼容模块使用GPL-only符号错误 该错误是由于模块未声明为GPL兼容许可证,却调用了内核中标记为`EXPORT_SYMBOL_GPL()`的符号(如`platform_driver_unregister`)。以下是具体解决步骤: --- #### **步骤1:确认模块许可证声明** 在模块源代码(如`gw5a_copy.c`)末尾添加GPL许可证声明: ```c MODULE_LICENSE("GPL"); // 或 MODULE_LICENSE("GPL v2"); ``` *这是强制要求*,否则无法通过modpost检查[^1][^4]。 --- #### **步骤2:验证内核符号导出类型** 通过以下命令查看符号`platform_driver_unregister`的导出类型: ```bash grep platform_driver_unregister /proc/kallsyms ``` 若输出包含`GPL-only`标记,则必须使用GPL兼容许可证。 --- #### **步骤3:检查内核版本兼容性** 高版本内核(如4.19+)可能移除非GPL替代接口。若代码基于旧版内核(如2.6.32),需按新版API调整代码结构。 --- #### **步骤4:重编译并测试** 1. 清理编译环境: ```bash make clean ``` 2. 重新编译模块: ```bash make -C /path/to/kernel/source M=$(pwd) modules ``` 3. 加载模块验证: ```bash sudo insmod gw5a_copy.ko ``` --- #### **替代方案(不推荐)** 若无法声明GPL许可证,需重构代码: 1. 避免直接调用`platform_driver_unregister`,改用其他非GPL接口。 2. 重新设计驱动架构,减少对GPL符号的依赖。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值