安装驱动的时候传递参数 导出符号表
安装驱动传递参数
#include <linux/module.h>
#include <linux/init.h>
/*
module_param(name, type, perm)
功能:接收安装驱动的时候传递的参数
参数
@name:变量名
@type:变量的类型
/ * Standard types are:
* byte, hexint, short, ushort, int, uint, long, ulong
* charp: a character pointer
* bool: a bool, values 0/1, y/n, Y/N.
* invbool: the above, only sense-reversed (N = true).
* /
@perm:权限(/sys/module/驱动命名的目录/parameters/文件,最大权限是0664)
MODULE_PARM_DESC(_parm, desc)
功能:对这个传参的变量进行描述,可以通过modinfo xxx.ko查看到描述字段
参数:
@_parm:被描述的变量
@desc:描述的字符串
*/
int back = 255;
module_param(back, int, 0664);
MODULE_PARM_DESC(back, "this is back var, rang[0-255]");
/*
module_param 传递参数
MODULE_PARM_DESC 提示,使用modinfo xxx.ko可以查看
方法一:
在安装模块的时候进行赋值
insmod param.ko back=111
方法二:
在导入模块后
/sys/module/驱动名/parameters/变量名
通过cat 可以查看
通过echo xx > 变量名可以修改
*/
static int __init param_init(void)
{
printk("%s:%s:%d\r\n", __FILE__, __func__, __LINE__);
printk("into param_init\r\n");
return 0;
}
static void __exit param_exit(void)
{
printk("%s:%s:%d\r\n", __FILE__, __func__, __LINE__);
printk("exit param_exit\r\n");
}
module_init(param_init);
module_exit(param_exit);
MODULE_LICENSE("GPL");
符号表
两个进程之间无法相互调用另一个进程的函数,因为每个进程都独立拥有0-3G的空间,想要调用需要使用进程传参,间接调用
内核中两个驱动可以相互调用其模块内的函数,因为它们共享3-4G的内核空间,只需要一个模块导出符号表,另一个模块在编译的时候导入符号表即可。
导出符号表
demoA.c
#include <linux/module.h>
#include <linux/init.h>
int add(int x, int y)
{
return x + y;
}
/*
EXPORT_SYMBOL_GPL(name)
功能:导出符号表
参数:
@name:函数名
编译此模块后会产生一个Module.symvers的文件,此文件就是符号表
*/
EXPORT_SYMBOL_GPL(add);//导出符号表
static int __init demoA_init(void)
{
printk("%s:%s:%d\r\n", __FILE__, __func__, __LINE__);
return 0;
}
static void __exit demoA_exit(void)
{
printk("%s:%s:%d\r\n", __FILE__, __func__, __LINE__);
}
module_init(demoA_init);
module_exit(demoA_exit);
MODULE_LICENSE("GPL");
导入符号表
demoB.c
#include <linux/init.h>
#include <linux/module.h>
int x , y;
module_param(x, int, 0664);
MODULE_PARM_DESC(x, "x in add");
module_param(y, int, 0664);
MODULE_PARM_DESC(y, "y in add");
/*
若是想使用其它模块的函数
首先需要其编译生成符号表
有了符号表之后有两种方法:
方法一:
将符号表拷贝到该模块所在的目录下
方法二:
Makefile中加入
KBUILD_EXTRA_SYMBOLS+= /符号表所在的路径/Module.symvers
在加载驱动的时候要先加载生成符号表的模块,然后再加载此模块,否则会报错
卸载的顺序相反,否则会报错
*/
extern int add(int x, int y); //导入外部函数
static int __init demoB_init(void)
{
printk("%s:%s:%d\r\n",__FILE__, __func__, __LINE__);
printk("%d add %d = %d\r\n", x, y, add(x, y));
return 0;
}
static void __exit demoB_exit(void)
{
printk("%s:%s:%d\r\n",__FILE__, __func__, __LINE__);
}
module_init(demoB_init);
module_exit(demoB_exit);
MODULE_LICENSE("GPL");
展示
加载模块
insmod demoA.ko //demoA导出的符号表,需要先加载驱动A
insmod demoB.ko x=10 y=20 //demoB
卸载模块
rmmod demoB
rmmod demoA