zhouwei
驱动牛犊
驱动牛犊
  • 注册日期2001-10-23
  • 最后登录2005-07-13
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1394回复:4

救救我吧

楼主#
更多 发布于:2003-06-19 14:21
这是我的测试驱动程序代码:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/devfs_fs_kernel.h>

#include \"func.h\"//该h文件包含Opendevice的定义

static int __init ktest_init(void)
{
unsigned int retval;
void * handle;

retval = Opendevice(&handle,0,0,1);
if(retval)
{
printk(\"ktest::Opendevice Error:%d\\n\",retval);
return 0;
}
printk(\"ktest::Opendevice Success\\n\");

return 0;
}

static void __exit ktest_exit(void)
{
printk(\"ktest::entry ktest_exit\\n\");
}

module_init(ktest_init);
module_exit(ktest_exit);
MODULE_LICENSE(\"GPL\");

其中:函数Opendevice在我的另一个驱动程序driver1中通过EXPORT_SYMBOL(Opendevice)导出的函数,当driver1加载后
在/proc/ksyms中都可以看到我导入的这个函数:c88b806c Opendevice_R__ver_Opendevice [driver1],
但我在把这个测试驱动程序加载时,它找不到函数链接Opendevice
高人:救救我吧!!!!!!!!!!


 
flycat0101
驱动小牛
驱动小牛
  • 注册日期2002-06-24
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望22点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2003-06-19 14:44
这是我的测试驱动程序代码:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/devfs_fs_kernel.h>

#include \"func.h\"//该h文件包含Opendevice的定义

static int __init ktest_init(void)
{
unsigned int retval;
void * handle;

retval = Opendevice(&handle,0,0,1);
if(retval)
{
printk(\"ktest::Opendevice Error:%d\\n\",retval);
return 0;
}
printk(\"ktest::Opendevice Success\\n\");

return 0;
}

static void __exit ktest_exit(void)
{
printk(\"ktest::entry ktest_exit\\n\");
}

module_init(ktest_init);
module_exit(ktest_exit);
MODULE_LICENSE(\"GPL\");

其中:函数Opendevice在我的另一个驱动程序driver1中通过EXPORT_SYMBOL(Opendevice)导出的函数,当driver1加载后
在/proc/ksyms中都可以看到我导入的这个函数:c88b806c Opendevice_R__ver_Opendevice [driver1],
但我在把这个测试驱动程序加载时,它找不到函数链接Opendevice
高人:救救我吧!!!!!!!!!!


  


我也想知道,呵呵
我即将使用这个方法调用别的驱动中的函数,可以探讨
我思,故我在
hclily
驱动牛犊
驱动牛犊
  • 注册日期2003-11-19
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-12-14 16:13
如果我们自己的module想要export一些东西让别的module使用呢。很简单。缺省来说,在你的module里所有的global variable和function都会被认定为你要export出去的。所以,如果你的module里有10个global variable,经由ksyms,你可以发现这十个variable都会被export出去。这非常方便,但是,如果我们根本不想把所有的variable都export出去,以防别的module没事乱改我们的variable,我们应该怎么办呢?在很多时候,我们都只会限定几个必要的东西export出去。在2.2.1之前的kernel(不是很确定)可以利用register_symtab来帮我们。但是在更新的版本中是怎么样的呢?在此,介绍kernel 2.2.1里所提供的一个macro,叫做EXPORT_SYMBOL,这是用来帮我们选择要export的variable或function。比方说,我要export一个叫full的variable,那我只要在module里写:
EXPORT_SYMBOL(full);
就会自动将full export出去,你马上就可以从ksyms里发现有full这个变量被export出去。在使用EXPORT_SYMBOL之前,要小心一件事,就是必须在gcc里定义EXPORT_SYMTAB这个constant,否则在compile时会发生parser error。所以,要使用EXPORT_SYMBOL的话,那gcc应该如下:
gcc -c -D__KERNEL__ -DMODULE -DMODVERSIONS -DEXPORT_SYMTAB \\
main.c -include /usr/src/linux/include/linux/modversions.h
如果我们不想export任何的东西,那我们只要在module里定义
EXPORT_NO_SYMBOLS;
就可以了。使用 EXPORT_NO_SYMBOLS用不着定义任何的constant。其实,如果各位使用过旧版的register_symbol的话,一定会觉得新版的方式比较好用。至少我是这样觉得啦。因为使用register_symbol还要先定义出自己的symbol_table,感觉有点麻烦。
当我们使用EXPORT_SYMBOL把一些function或variable export出来之后,我们使用ksyma -a去看一些结果。我们发现EXPORT_SYMBOL(full)的确是把full export出来了:
c8822200 full [my_module]
c01b8e08 pci_find_slot_R454463b5
. . .
但是,结果怎么跟我们想象中的不太一样,照理说,应该是full_Rxxxxxx之类的东西才对啊,怎么才出现full而已呢?问题出在那里呢?其实,问题就在于我们没有对本身的module所export出来的function或variable的名字做encode。想想,如果在module的开头。我们加入一行
#define full full_Rxxxxxx
之后,我们再重新compile module一次,载到kernel之后,就可以发现ksyms -a显示的是
c8822200 full_Rxxxxxx [my_module]
c01b8e08 pci_find_slot_R454463b5
. . . . .
了。我们需要去对每一个export出来的variable和function做define的动作呢?那是不需要的。我们前边讲使用kernel export的function时,由于include了一些.ver的头文件,我们就不用再做define的动作。现在,我们也要利用.ver的module来帮我们,使我们module export出来的function也可以自动加入kernel version的information。也就是变成full_Rxxxxxx之类的东西。
Linux 里提供了一个command,叫genksyms,就是用来帮我们产生这种.ver的头文件的。它会从stdin里读取source code,然后检查source code里是否有export的variable或function。如果有,它就会自动为每个export出来的东西产生一些define。这些define就是我们之前说的。等我们有了这些define之后,只要在我们的module里加入这些define,那export出来的function或variable就会变成上面那个样子。
假设我们的程序都放在一个叫main.c的档案里,我们可以使用下列的方式产生这些define。
gcc -E -D__GENKSYMS__ main.c | genksyms -k 2.2.1 > main.ver
gcc的-E参数是指将preprocessing的结果show出来。也就是说将它include的头文件,一些define的结果都展开。-D__GENKSYMS__是一定要的。如果没有定义这个constant,你将不会看到任何的结果。用一个管线是因为genksyms是从stdin读资料的,所以,经由管线将gcc的结果传给genksyms。-k 2.2.1是指目前使用的kernel版本是2.2.1,如果你的kernel版本不一样,必须指定你的kernel的版本。产生的define将会被放到main.ver里。产生完main.ver档之后,在main.c里将它include进来,那一切就OK了。有件事要告诉各位的是,使用这个方式产生的module,其export出来的东西会经由main.ver的define改头换面。所以如果你要让别人使用,那你必须将main.ver公开,不然,别人就没办法使用你export出来的东西了。
Inventec
驱动牛犊
驱动牛犊
  • 注册日期2003-04-29
  • 最后登录2005-11-14
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-12-15 17:13
高!学到了很多
真心英雄
xiang324
驱动牛犊
驱动牛犊
  • 注册日期2004-03-23
  • 最后登录2004-04-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-04-01 11:07
我是新手,遇到了内核不匹配的问题,该如何解决?
游客

返回顶部