阅读:1396回复:4
救救我吧
这是我的测试驱动程序代码:
#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 高人:救救我吧!!!!!!!!!! |
|
沙发#
发布于:2004-04-01 11:07
我是新手,遇到了内核不匹配的问题,该如何解决?
|
|
板凳#
发布于:2003-12-15 17:13
高!学到了很多
|
|
|
地板#
发布于: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出来的东西了。 |
|
地下室#
发布于:2003-06-19 14:44
这是我的测试驱动程序代码: 我也想知道,呵呵 我即将使用这个方法调用别的驱动中的函数,可以探讨 |
|
|