我写了一个驱动,由于要依赖另一个模块导出的符号,搞了很久才弄好。现在总结一下我的做法。
为了方便表述,我把被依赖的模块称为模块B, 我自己的模块称为模块A。
步骤一:
在被依赖的模块B中导出要用的符号,如:
int cat9555_state_get_inp(void)
{
................
}
EXPORT_SYMBOL(cat9555_state_get_inp);
步骤二:
编译模块B,当前目录下生成Module.symvers文件,将其复制到模块A的目录下。
打开Module.symvers可以看到他的内容如下:
0x3c1007e5cat9555_add_opt_addr/home/project/MeterRead/gpio/gpioEXPORT_SYMBOL
0x20473c2bcat9555_state_get_inp/home/project/MeterRead/gpio/gpioEXPORT_SYMBOL
0x3cc81287cat9555_del_opt_addr/home/project/MeterRead/gpio/gpioEXPORT_SYMBOL
0x68be5229cat9555_release_addr/home/project/MeterRead/gpio/gpioEXPORT_SYMBOL
0x743cae4dcat9555_state_as_gpo/home/project/MeterRead/gpio/gpioEXPORT_SYMBOL
0x9c89640ecat9555_state_as_gpi/home/project/MeterRead/gpio/gpioEXPORT_SYMBOL
0x977f0740cat9555_open_addr/home/project/MeterRead/gpio/gpioEXPORT_SYMBOL
0xf9713bbbcat9555_state_get_outp/home/project/MeterRead/gpio/gpioEXPORT_SYMBOL
0x28d7d46fcat9555_state_set_outp/home/project/MeterRead/gpio/gpioEXPORT_SYMBOL
原来这是记录导出符号的文件。
步骤三:
在模块A的文件中引用导出的符号。
extern cat9555_state_get_inp(void); //声明引用的符号是外部变量。
int f(){
................
cat9555_state_get_inp(); //在这里引用导出的符号
................
}
编译A模块。
我如果没有步骤二的话,插入A模块时会出现以下错误(找不到符号 ):
gprsiodrv: no symbol version for cat9555_state_get_inp
gprsiodrv: Unknown symbol cat9555_state_get_inp
gprsiodrv: no symbol version for cat9555_state_as_gpi
gprsiodrv: Unknown symbol cat9555_state_as_gpi
insmod: cannot insert 'gprsiodrv.ko': unknown symbol in module
但是有人不用步骤二也可以,猜测与编译器有关。
分享到:
相关推荐
代码是公众号一口Linux 文章驱动部分所有势力代码,文章如下: 《玩转内核链表list_head,如何管理不同类型节点的实现...《手把手教Linux驱动2-模块参数param和符号导出export用法》 《手把手教Linux驱动1-模块化编程》
| |-- 内核模块导出符号 | | `-- export_symb.c | `-- 最简单的内核模块 | `-- hello.c |-- 05 | `-- udev源代码 | `-- udev-114.tar.gz |-- 06 | |-- globalmem驱动 | | `-- globalmem.c | `-- 包含2个globalmem...
| |-- 内核模块导出符号 | | `-- export_symb.c | `-- 最简单的内核模块 | `-- hello.c |-- 05 | `-- udev源代码 | `-- udev-114.tar.gz |-- 06 | |-- globalmem驱动 | | `-- globalmem.c | `-- 包含2个globalmem...
| |-- 内核模块导出符号 | | `-- export_symb.c | `-- 最简单的内核模块 | `-- hello.c |-- 05 | `-- udev源代码 | `-- udev-114.tar.gz |-- 06 | |-- globalmem驱动 | | `-- globalmem.c | `-- 包含2个globalmem...
如何导出符号、如何使用导出的符号?背后的内核机制 1、“处理未解决引用”问题的本质是在模块加载期间找到当前“未解决的引用“符号在内存中的实际目标地址。 通过“符号表”的形式向外界导出符号信息。 由EXPORT_...
“在追求效率的代码中使用goto语句仍是最好的错误恢复机制。”--《Linux设备驱动程序(第3版)》以下是初始化出错处理的推荐代码示例: struct something *item1; struct somethingelse *item2; int stuff_ok; ...
| |-- 内核模块导出符号 | | `-- export_symb.c | `-- 最简单的内核模块 | `-- hello.c |-- 05 | `-- udev源代码 | `-- udev-114.tar.gz |-- 06 | |-- globalmem驱动 | | `-- globalmem.c | `-- 包含2个globalmem...
4.6 Linux模块的参数与导出符号 4.7 Linux模块的使用计数 第5章Linux文件系统 5.1 Linux文件系统概述 5.1.1 Linux文件系统的目录结构 5.1.2设备驱动与Linux文件系统的关联 5.2 Linux设备文件系统 5.2.1 devfs设备...
提供和使用导出符号的两个简单驱动程序。 像往常一样使用 EXPORT_GPL_SYMBOL 或 EXPORT_SYMBOL 导出您的符号。 正常构建您的提供程序模块 - 并查看 Module.symvers 文件,因为我们将取决于它导出的内容 - ...
.....................\..\内核模块导出符号 .....................\..\................\export_symb.c .....................\..\最简单的内核模块 .....................\..\................\hello.c ........
| |-- 内核模块导出符号 | | `-- export_symb.c | `-- 最简单的内核模块 | `-- hello.c |-- 05 | `-- udev源代码 | `-- udev-114.tar.gz |-- 06 | |-- globalmem驱动 | | `-- globalmem.c | `-- 包含2个globalmem...
“在库中的对应命令名”请务必准确填写静态库中公开导出的符号名称(C函数(cdecl)编译后,符号名称通常是在函数名称前加下划线(_));“在库中的对应命令名”以@开头表示以cdecl方式调用,否则表示以默认的stdcall...
IV:Open Inventor中使用的文件格式 IVD:超过20/20微观数据维数或变量等级文件 IVP:超过20/20的用户子集配置文件 IVT:超过20/20表或集合数据文件 IVX:超过20/20微数据目录文件 IW:Idlewild屏幕保护程序 ...
1)在定制主题和外表中使用拖放 85 2)拖放标记摘要 85 3)拖放 API 86 八、功能应用或问题 87 1、WCM多子站区指向指定子站区配置 87 2、更改PORTAL默认的登录选项 89 3、如何在主题与皮肤中获取PORTAL登录用户信息 ...