driver: linux2.6 内核模块导出函数实例(EXPORT_SYMBOL) 【转】
转自:http://blog.chinaunix.net/uid-23381466-id-3837650.html
内核版本:2.6.38-11-generic
内核自己都大量利用内核符号表导出函数,那么应该导出呢,ldd3上面说只需要EXPORT_SYMBOL一类的宏导出即可,结果试了很久都不行,最后查看文档,算是明白一点了。
对于导出符号表,内核文档给出了三种解决方案,见尾部,现在忽略。
现在有两个模块,a模块导出函数myprint,b模块使用该函数,想象一下如果a模块 EXPORT_SYMBOL(myprint) ,实际上b模块知道吗,很明显b模块对这件事情不是很清楚(这么说不是很准确),要调用a模块的myprint函数,需要知道myprint函数在内存中的位置,首先在内核符号表中是没有说明的,所以...
当我们编译完a模块后,看看有些什么文件,是不是有一个Module.symvers文件,打开看看什么状况?
0x705034f7 myprint /home/darren/Desktop/darren/print/myprint EXPORT_SYMBOL
好了,这一行对b模块来说已经足够了,指定了内存位置,符号名称,模块路径。最简单的方法就是把这个文件复制到b模块所在目录,然后编译就没有讨厌的错误了,可以正常insmod模块。这种方法是内核文档中提到的方法之一。
但是每次调用该函数都要复制一次,更糟糕的是a模块每编译一次,都要重新复制一次,为什么内核自己导出的函数我们可以直接用呢?现在就就解决:
编译内核的时候同样会生成一个Module.symvers文件,内核导出的所有符号都在里面,我们在编译模块的时候实际上会调用内核的顶层makefile,也就是说内核的Module.symvers对我们的模块是可见的,和我们自己的Module.symvers文件一样,OK,把a模块的Module.symvers文件合并到内核的Module.symvers文件中,这时候myprint函数就成了真正的导出函数了,其他的模块只需要生命一下就可以用了。
代码如下
a模块代码:
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/kernel.h>
- MODULE_LICENSE("GPL");
- int myprint(void)
- {
- printk("c");
- return 0;
- }
- static int darren_init(void)
- {
- return 0;
- }
- static void darren_exit(void)
- {
- }
- module_init(darren_init);
- module_exit(darren_exit);
- EXPORT_SYMBOL(myprint);
b模块代码:
- #include <linux/seq_file.h>
- #include <linux/cdev.h>
- #include <asm/system.h>
- MODULE_LICENSE("GPL");
- extern int print(void);
- static int darren_init(void)
- {
- int i=0;
- printk("b module init\n");
- for(;i<10;i++)print();
- return 0;
- }
- static void darren_exit(void)
- {
- }
- module_init(darren_init);
- module_exit(darren_exit);
a模块的Makefile如下:
- NAME:=a
- SYM:=/usr/src/linux-headers-2.6.38-8-generic/Module.symvers
- DIR:=/lib/modules/$(shell uname -r)/build/
- PWD:=$(shell pwd)
- obj-m = $(NAME).o
- build:
- make -C $(DIR) M=$(PWD)
- sudo chmod 777 $(SYM)
- sudo sed -i '/myprint/d' $(SYM)
- sudo cat Module.symvers>>$(SYM)
- sudo chmod 644 $(SYM)
b模块的makefile:
- NAME:=b
- DIR:=/lib/modules/$(shell uname -r)/build/
- PWD:=$(shell pwd)
- obj-m = $(NAME).o
- build:
- make -C $(DIR) M=$(PWD)
注意:路径/usr/src/linux-headers-2.6.38-8-generic/Module.symvers 有可能不对如果不行就改成/usr/src/linux-headers-`uname -r`-generic/Module.symvers
内核文档:
- Sometimes, an external module uses exported symbols from
- another external module. kbuild needs to have full knowledge of
- all symbols to avoid spitting out warnings about undefined
- symbols. Three solutions exist for this situation.
- NOTE: The method with a top-level kbuild file is recommended
- but may be impractical in certain situations.
- Use a top-level kbuild file
- If you have two modules, foo.ko and bar.ko, where
- foo.ko needs symbols from bar.ko, you can use a
- common top-level kbuild file so both modules are
- compiled in the same build. Consider the following
- directory layout:
- ./foo/ <= contains foo.ko
- ./bar/ <= contains bar.ko
- The top-level kbuild file would then look like:
- #./Kbuild (or ./Makefile):
- obj-y := foo/ bar/
- And executing
- $ make -C $KDIR M=$PWD
- will then do the expected and compile both modules with
- full knowledge of symbols from either module.
- Use an extra Module.symvers file
- When an external module is built, a Module.symvers file
- is generated containing all exported symbols which are
- not defined in the kernel. To get access to symbols
- from bar.ko, copy the Module.symvers file from the
- compilation of bar.ko to the directory where foo.ko is
- built. During the module build, kbuild will read the
- Module.symvers file in the directory of the external
- module, and when the build is finished, a new
- Module.symvers file is created containing the sum of
- all symbols defined and not part of the kernel.
- Use "make" variable KBUILD_EXTRA_SYMBOLS
- If it is impractical to copy Module.symvers from
- another module, you can assign a space separated list
- of files to KBUILD_EXTRA_SYMBOLS in your build file.
- These files will be loaded by modpost during the
- initialization of its symbol tables.
driver: linux2.6 内核模块导出函数实例(EXPORT_SYMBOL) 【转】的更多相关文章
- linux模块导出符号 EXPORT_SYMBOL_GPL&EXPORT_SYMBOL(转)
转自:http://blog.csdn.net/angle_birds/article/details/7396748 一个模块mod1中定义一个函数func1:在另外一个模块mod2中定义一个函数f ...
- AFX_MANAGE_STATE(AfxGetStaticModuleState())DLL导出函数包含MFC资源
AFX_MANAGE_STATE(AfxGetStaticModuleState()) 先看一个例子: .创建一个动态链接到MFC DLL的规则DLL,其内部包含一个对话框资源.指定该对话框ID如下: ...
- DLL 导出函数
DLL的链接方式分为两种:隐式链接和显式链接 DLL导出的函数 和 导出类在调用时,有些区别,这里暂时不讲,直说简单的导出函数: 隐式链接: #include "stdafx.h" ...
- dll导出函数的两种方式的比较
最初的网页链接已经挂了, 在此贴一个中间的转载链接 https://blog.csdn.net/zhazhiqiang/article/details/51577523 一 概要 vs中导出 dll的 ...
- DLL导出函数和类的定义区别 __declspec(dllexport)
DLL导出函数和类的定义区别 __declspec(dllexport) 是有区别的, 请看 : //定义头文件的使用方,是导出还是导入 #if defined(_DLL_API) #ifndef D ...
- 分享一个批量导出当前实例下的所有linkedserver脚本
分享一个批量导出当前实例下的所有linkedserver脚本 很多时候,我们都需要导出实例下面的登录用户,job,linkedserver等等 导出job比较复杂,下午写了一个脚本把所有的linked ...
- JavaScript学习笔记-函数实例
函数实例 var p = { a:15, b:'5', f1:function(){ var self = this; console.log(self.a+self.b); f2(); functi ...
- Mysql导出函数、存储过程
下面是导出存储过程的代码 1 # mysqldump -u 数据库用户名 -p -n -t -d -R 数据库名 > 文件名 其中,-d 表示--no-create-db, -n表示--no-d ...
- python迭代器与iter()函数实例教程
python迭代器与iter()函数实例教程 发布时间:2014-07-16编辑:脚本学堂 本文介绍了python迭代器与iter()函数的用法,Python 的迭代无缝地支持序列对象,而且它还允许程 ...
随机推荐
- MVC 4 图片的上传及显示
1 首先我们看一下如何上传 1.1 view 上传页面: 1: @using (Html.BeginForm("Create", "Achievement", ...
- 分别用postman和python做post请求接口功能测试
前几天,在做一个post请求的接口功能测试的时候,发现数据始终无法入库, 认真加仔细检查了请求的url.方式.参数,均没有问题 找到技术确认,原来是需要传json格式数据 在头信息中加上类型,body ...
- 【poj2396】 Budget
http://poj.org/problem?id=2396 (题目链接) 题意 给出一个矩阵,给出每一行每一列的和,以及若干限制条件,限制了其中每一个元素的上下界,求一种可行的方案使得每一行每一列数 ...
- 前端学习 -- Html&Css -- ie6 png 背景问题
在IE6中对图片格式png24支持度不高,如果使用的图片格式是png24,则会导致透明效果无法正常显示 解决方法: 1.可以使用png8来代替png24,即可解决问题,但是使用png8代替png24以 ...
- Luogu 1979 NOIP 2013 华容道(搜索,最短路径)
Luogu 1979 NOIP 2013 华容道(搜索,最短路径) Description 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面 ...
- Python基本数据类型——元组和集合
元组 tuple tuple和list非常类似,但是tuple一旦初始化就不能修改.元组采用圆括号表示. 例如: >>> tuple = (1,2,3) >>> t ...
- Codeforces Round #419 (Div. 2)(B)差分数组
传送门:Problem B https://www.cnblogs.com/violet-acmer/p/9721160.html 题意: Karen有n个关于煮咖啡的食谱,每个食谱都有个煮咖啡的最适 ...
- get方式传值中文乱码
问题描述: 本机可以,服务器乱码: 解决方案: 我采用了第三条,改server.xml配置 方法一: get方式提交的参数编码,只支持iso8859-1编码.因此,如果里面有中文.在后台就需要转换编码 ...
- DTLS协议中client/server的认证过程和密钥协商过程
我的总结:DTLS的握手就是协商出一个对称加密的秘钥(每个客户端的秘钥都会不一样),之后的通信就要这个秘钥进行加密通信.协商的过程要么使用非对称加密算法进行签名校验身份,要么通过客户端和服务器各自存对 ...
- 漏洞评估工具Nexpose的配置使用
nexpose是领先的漏洞评估工具之一.Nexpose社区版是一个免费的程序,其他版本是收费的.在这篇文章中,我们将使用Nexpose免费社区版,里面有扫描32主机的能力.用户界面干净.报告强大.像大 ...