了解内容
加载内核模块时可以通过module_param宏来传递值给模块中变量。
原型是module_param(name, type, perm)
,可以在“include /linux/moduleparam.h”①中找到。
- name:填写已声明的变量(type类型),会把传入参数的值赋给该变量;
- type:传入参数的数据类型,支持int、long、short、uint、ulong、ushort类型;
- perm:传入参数的访问权限,比如
S_IRUSR
表示文件所有者可读(include/linux/stat.h有定义);也可以不用宏,写法类似777之类的。
另外可以通过module_param_array宏来传递一组值给模块中数组变量,原型是module_param_array(name, type, nump, perm)
,相比较传单个参数的宏,多了一个传值:
- nump:取已声明的num变量(int)的地址(&操作),会保存传入参数个数到num中。
①感觉接触最多内核文件大致可以分为3类:linux通用框架类(“include/linux/”,gpio申请释放赋值函数也在该目录下);arm厂家-设备信息类(“arch/arm/mach-exynos/include/mach/”和“arch/arm/plat-samsung/include/plat/”。可以理解为plat是一个平台一个系的CPU相同资源的一些函数操作库,mach相当于一个开发板的资源);驱动类(比如“drivers/char/”存放字符型驱动,有itop4412_leds.c等);
开始
编写demo模块
主要变动点:
-
加入头文件:linux/moduleparam.h和linux/stat.h;
-
静态声明需要传递值的变量:module_arg1、module_arg2和module_array[50];
传递数组的值(一次多个参数)时,需要再声明一个module_array_num变量;
-
宏定义module_param和module_param_array声明即可。
moduleparam_demo.c:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <linux/init.h>
#include <linux/module.h>
#include <linux/stat.h>
#include <linux/moduleparam.h>
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Jerry");
static int module_arg1;
static int module_arg2;
static int module_array[50]; //max get length: 50
static int module_array_num;
module_param(module_arg1,int,S_IRUSR);
module_param(module_arg2,int,S_IRUSR);
module_param_array(module_array,int,&module_array_num,S_IRUSR);
static int demo_init(void){
int i;
printk(KERN_EMERG "module_arg1 value is : %d!\n",module_arg1);
printk(KERN_EMERG "module_arg2 value is : %d!\n",module_arg2);
for(i=0;i<module_array_num;i++){
printk(KERN_EMERG "module_array[%d] value is : %d!\n",i,module_array[i]);
}
return 0;
}
static void demo_exit(void){
return;
}
module_init(demo_init);
module_exit(demo_exit);
验证传值
编写简单Makefile:参考这里
编译生成模块后,拷贝到开发板中加载:
-
不加传值
-
加传值后
加载模块后还可以在
/sys/module/moduleparam_demo/
中找到更多该模块的信息,比如传值就在子目录parameters中以文件形式展示了: