模块参数与符号

模块参数

module_param(name,type, perm);
module_param_array(name, type, num, perm);
perm表示该参数在sysfs文件系统中所对应的文件节点的属性;你应该使用<linux/stat.h>中定义的权限值;这个值决定谁可以存取这些模块参数在sysfs文件系统中的表示;当perm为0时,表示此参数不存在sysfs文件系统下对应的文件节点;否则,模块被加载后,在/sys/module/目录下将会出现以此模块名命名的目录,带有给定的权限;在该目录下,有一个parameters子目录,在里面每个文件对应一个参数,参数值就在以该参数名命名的文件中。
注意:如果一个参数被sysfs修改了,那么你的模块看到的参数值也被修改了,但是你的模块不会收到任何通知;你应当不要使模块参数可写,除非你准备好检测这个改变并因而作出反应。

模块符号

EXPORT_SYMBOL标签内定义的函数对全部内核代码公开,不用修改内核代码就可以在您的内核模块中直接调用。

加入B中调用A中导出函数
[1] 在模块A中c文件或者头文件中使用EXPORT_SYMBOL(xxxx)导出函数.有些需要添加编译选项-DEXPORT_SYMTAB.
[2] 在模块B中用"extern" 申明函数(如, extern int xxxx);申明以后就能够直接使用导出的函数了。
另外:在导出函数以后,可以使用 cat  proc/kallsyms来查看所有的导出符号,其中属性为t的标识是不能被调用的,所以如果导出符号是t类型,那么无法直接被其他模块使用。
无法导出问题解决
方法一:在A模块编译好后会生成符号表文件Module_symvers,里面有函数地址和函数名对应关系,把这个文件拷贝到需要调用的B的源代码下,替换B的该文件。
然后重新编译B模块.这样就能够让B调用A的函数,以后加载模块顺序也必须先A后B,卸载相反。
方法二:将两个模块放在一个目录下,进行编译。其实和方法一类似。
这样就能够成功的实现两个模块之间的函数调用,比如KVM如果需要和驱动模块相互调用,就能使用这个方法。如果是两个模块之间需要相互调用,可以让驱动模块函数导出,KVM模块将函数指针当做回调函数传给驱动,是想双方的函数调用通讯。
/*
* 内核符号导出 给其他模块使用 使用前要申明一下
* 另外从 /proc/kallsyms 可以查看内核符号表的相关信息(eg.所在内存地址)
* eg. cat /proc/kallsyms | grep integar
*/
 
#include<linux/init.h>
 #include<linux/module.h>

 MODULE_LICENSE("Dual BSD/GPL");

 static int __init symbol_init(void)
 {
 printk("<0> symbol_init\n");
 return 0;
 }
 int add_integar(int a, int b)
 {
 return (a + b);
 }

 int sub_integar(int a, int b)
 {
 return (a - b);
 }

 static void __exit symbol_exit(void)
 {
 printk("<0> symbol_exit\n");
 }
 EXPORT_SYMBOL(add_integar);
 EXPORT_SYMBOL(sub_integar);
 module_init(symbol_init);
 module_exit(symbol_exit);

/*
*使用其他内核模块导出的符号
*/
 
#include<linux/module.h>
 #include<linux/init.h>
 extern int add_integar(int, int);
 extern int sub_integar(int, int);

 MODULE_LICENSE("GPL");

 static int __init use_symbol_init(void)
 {
 printk("<0> use_symbol_init");
 printk("<0> 1+2 = %d\n",add_integar(1,2));
 printk("<0> 3-2 = %d\n",sub_integar(3,2));
 return 0;
 }

 static void __exit use_symbol_exit(void)
 {
 printk("<0> Module exit!\n");
 }
 module_init(use_symbol_init);
 module_exit(use_symbol_exit);

你可能感兴趣的:(参数,Module,模块,符号)