(1)引入原因
在用户态下编程可以通过main()来传递命令行参数(具体可见C语言高级中的一篇文章),而编写一个内核模块则可通过module_param()来传递命令行参数。
(2)实现
module_param宏是Linux 2.6内核中新增的,该宏被定义在include/linux/moduleparam.h文件中,具体定义如下:
/* Helper functions: type is byte, short, ushort, int, uint, long, ulong, charp, bool or invbool, or XXX if you define param_get_XXX,param_set_XXX and param_check_XXX. */
#define module_param_named(name, value, type, perm)
param_check_##type(name, &(value));
module_param_call(name, param_set_##type, param_get_##type, &value, perm);
__MODULE_PARM_TYPE(name, #type)
#define module_param(name, type, perm) module_param_named(name, name, type, perm)
(3)module_param使用了3个参数:变量名,它的类型,以及一个权限掩码用来做一个辅助的sysfs入口。这个宏定义应当放在函数之外,典型的是出现在源文件的前面。
eg: static char *whom="world"
static int tige=1;
module_param(tiger,int,S_IRUGO);
module_param(whom,charp,S_IRUGO);
(4)数组参数
用逗号间隔的列表提供值,模块加载也支持。声明一个数组参数,使用:module_param_array(name,type,num,perm);这里 name 是你的数组的名子(也是参数名),
type 是数组元素的类型,num 是一个整型变量,perm 是通常的权限值。模块加载者拒绝比数组能放下的多的值。
(5)实例
1,编写一个moduleparam.c,如下:
#include <linux/init.h> #include <linux/module.h> #include <linux/moduleparam.h> MODULE_LICENSE("Dual BSD/GPL"); static char *who = "world"; static int times = 1; module_param(times,int,S_IRUSR); module_param(who,charp,S_IRUSR); static int hello_init() { int i; for(i = 0;i < times;i++) printk(KERN_ALERT"(%d)hello,%s! /n",i,who); return 0; } static void hello_exit() { printk(KERN_ALERT"Goodbye ,%s! /n",who); } module_init(hello_init); module_exit(hello_exit);
2,编写一个makefile文件,如下:
obj-m:=moduleparam.o CURRENT_PATH:=$(shell pwd) VERSION_NUM:=$(shell uname -r) LINUX_PATH:=/usr/src/linux-headers-$(VERSION_NUM) all: make -C $(LINUX_PATH) M=$(CURRENT_PATH) modules clean: make -C $(LINUX_PATH) M=$(CURRENT_PATH) clean
执行make后编译生成moduleparam.ko。然后终端执行:sudo insmod moduleparam.ko who=pig times=4,再用dmesg就可以看到内核消息末尾有:
[ 1637.910012] (0)hello,pig! /n
[ 1637.910039] (1)hello,pig! /n
[ 1637.910044] (2)hello,pig! /n
[ 1637.910047] (3)hello,pig! /n
可见模块在加载时调用了其后的模块参数。
参考原文:http://www.phpfans.net/article/htmls/201011/MzIxNzY3.html