"); //-->
http://www.cnblogs.com/riskyer/p/3221805.html
EXPORT_SYMBOL只出现在2.6内核中,在2.4内核默认的非static 函数和变量都会自动
导入到kernel 空间的, 都不用EXPORT_SYMBOL() 做标记的。
2.6就必须用EXPORT_SYMBOL() 来导出来(因为2.6默认不到处所有的符号)。
1、EXPORT_SYMBOL的作用是什么?
EXPORT_SYMBOL标签内定义的函数或者符号对全部内核代码公开,不用修改内核代
码就可以在您的内核模块中直接调用,即使用EXPORT_SYMBOL可以将一个函数以符
号的方式导出给其他模块使用。
这里要和System.map做一下对比:
System.map 中的是连接时的函数地址。连接完成以后,在2.6内核运行过程中,是不知道哪个符号在哪个地址的。
EXPORT_SYMBOL 的符号, 是把这些符号和对应的地址保存起来,在内核运行的过程中,可以找到这些符号对应的地址。而模块在加载过程中,其本质就是能动态连接到内核,如果在模块中引 用了内核或其它模块的符号,就要EXPORT_SYMBOL这些符号,这样才能找到对应的地址连接。
2、使用方法
第一、在模块函数定义之后使用EXPORT_SYMBOL(函数名)
第二、在掉用该函数的模块中使用extern对之声明
第三、首先加载定义该函数的模块,再加载调用该函数的模块
例如:
一个模块mod1中定义一个函数func1;
在另外一个模块mod2中定义一个函数func2,func2调用func1。
在模块mod1中,EXPORT_SYMBOL(func1);
在模块mod2中,extern int func1();
就可以在mod2中调用func1了。
(1)helloworld.c
#include <linux/module.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
static void hello_fun(void)
{
printk("##### helloworld####\n");
}
EXPORT_SYMBOL(hello_fun);
static int __init hello_init(void)
{
printk(KERN_ERR "#### hello world\n");
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_ERR "#### exit\n");
}
module_init(hello_init);
module_exit(hello_exit);
Makefile
obj-m := hello.o
hello-objs := helloworld.o
KID := /lib/modules/`uname -r`/build
PWD := $(shell pwd)
all:
make -C $(KID) M=${PWD} modules
clean:
rm -rf *.o .cmd *.ko *.mod.c .tmp_versions
(2)call-module.c
#include <linux/module.h>
#include <linux/init.h>
extern void hello_fun(void);
static int __init hello_init(void)
{
hello_fun();
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_ERR "#### exit\n");
}
MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);
Makefile
obj-m := call-module.o
KID := /lib/modules/`uname -r`/build
PWD := $(shell pwd)
KBUILD_EXTRA_SYMBOLS=/usr/src/linux-headers-3.5.0-34-generic/Module.symvers
KBUILD_EXTRA_SYMBOLS +=/home/snail/work/2.linux-driver/1.helloworld/Module.symvers
all:
make -C $(KID) M=${PWD} modules
clean:
rm -rf *.o .cmd *.ko *.mod.c .tmp_versions *.order *.symvers .*
(3)
加载 hello.ko
sudo insmod ./hello.ko
加载 call-module.ko
sudo insmod ./call-module.ko
观察 dmesg
<4>[ 3837.857657] ##### helloworld####
(4)注意事项
加载call-module.ko可能会出现
“NO SYMBOL VERSION FOR”问题
解决:
这是linux kernel 2.6.26 之后版本的bug (详细描述, 请看http://bugzilla.kernel.org/show_bug.cgi%3Fid%3D12446)
并且这个bug不会被fix
解决办法:
(1)mod_a的Module.symvers放到mod_b的当前路径,从而编译mod_b,符号信息会自动连接进去.
(2)或者在mod_b的makefile中使用KBUILD_EXTRA_SYMBOLS指定mod_a的Module.symvers,
如:
KBUILD_EXTRA_SYMBOLS=/mod_a/Module.symvers
编译mod_b时,搜索Module.symvers的路径是:
1, kernel source path, e.g. /usr/src/kernels/linux-2.6.28.10
2, makefile中M=所指定的路径, 它等效于变量KBUILD_EXTMOD的值
3, 变量KBUILD_EXTRA_SYMBOLS的值
问题的本质:
简单说来,就是小b生成的时候不知道小a symbol的校验码,小b加载的时候自然check 校验码出错。
专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们
相关推荐
Pat Gelsinger告诫陈立武“华尔街的短期主义”
高通在全球范围内指控 Arm垄断反竞争,芯片架构授权模式面临重构
过压过流保护器
基于ARM7的智能行动辅助专家
能检测热电偶开路故障的电路(隔离式热电偶冷端温度补偿及信号调理器1B51)
诚寻长期单片机开发的合作伙伴(HOLTEK,EMC,NTK,SONIX)
过压自动断电装置
苹果全球开发者大会WWDC25官宣6月10日开幕
各位大哥请帮我一下
康普发布面向数据中心的Propel XFrame解决方案
由数字式压力信号调理器MAX1459构成的4~20mA电流变送器的电路
由热电偶冷端温度补偿器AD594/595构成的摄氏温度计电路
基于87C196MC控制的大功率EGBT超声波逆变电源
应用于健康手机的高性能生物电信号采集模块
汽车安全完整性等级 (ASIL) 指南
由热电偶冷端温度补偿及转换器MAX6675构成的测温系统电路框图
新版DeepSeek V3悄然发布 外媒:很强但少了\"人味\"
高强度放电(HID)灯电子镇流器设计
用于电动汽车车载充电器的CLLLC与DAB比较
基于ADS8344的交流采样系统
ads中的利用scatter file创建内存映射的问题请教
由热电偶冷端温度补偿器AD596/597构成温度测控仪电路
瑞萨电子推出全新低功耗蓝牙SoC,为车载应用带来更低能耗
智能迎宾机器人的设计与实现
Gartner发布2025年数据和分析重要趋势
华强9W(5W)电子镇流器原理图
斑竹您好,我下载61ic的dsp资料内存详解,无法下载,请斑竹发一份给我,谢谢
基于LPC3250之一种海浪能发电系统
Littelfuse推出通过AEC-Q200认证的823A系列高压汽车应用保险丝
请高手提供一份tidsp6000的ram自检程序吧