本文在上一节《Linux v2.6内核编程之最简单的内核模块helloworld》的基础上,添加了模块参数,并拓展为多个源文件组成的内核模块。
先直接上代码:
主文件:
/* file name: sayhi.c
* author: yilonglucky#gmail.com
* description: a kernel module with parameters
*/
#include <linux/init.h>
#include <linux/module.h>
#include "farewell.h"
static int times = 1;
static char *whom = "world";
static int debug = 0;
module_param(times, int, S_IRUGO);
module_param(whom, charp, S_IRUSR);
module_param(debug, int, S_IRUGO|S_IWUSR);
static int hello_init(void)
{
int i;
if(debug)
{
printk(KERN_ALERT "###times:%d\n", times);
}
for(i = 0; i < times; i++)
{
printk(KERN_ALERT "#%d: Hi, %s!\n", i, whom);
}
return 0;
}
static void hello_exit(void)
{
if(debug)
{
printk(KERN_ALERT "###whom:%s\n", whom);
}
farewell_to(whom);
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("Dual BSD/GPL");
需要引用的用户自定义头文件:
/* file name: farewell.h
* author: yilonglucky#gmail.com
* description: a kernel module with parameters
*/
void farewell_to(char *);
引用的函数原型所在源文件:
/* file name: farewell.c
* author: yilonglucky#gmail.com
* description: a kernel module with parameters
*/
#include <linux/kernel.h>
void farewell_to(char *s)
{
printk("Farewell, %s\n", s);
return;
}
最后是对应的Makefile:
ifneq ($(KERNELRELEASE),)
obj-m:=greet.o
greet-objs:=sayhi.o farewell.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
-rm -rf .* *.o *.ko *.mod.c *.order *.symvers
endif
本例内核模块的功能是在添加的模块的时候,根据传入的内核模块参数,向内核log中向相应的名称打招呼若干次,默认向world说一次Hi。
编译出的内核模块名字是greet.ko,源代码在sayhi.c和farewell.c这2个源文件中,其中后者是被调用的角色,在更进一步的用法中,可以以so库的形式链接进来。
在实际使用内核模块时,为了便于调试可以添加控制调试信息的内核模块参数。在本例中,默认关闭调试标志。
举例操作序列:
#sudo insmod greet.ko whom=csdn times=5 debug=1
#dmesg
#ls -l /sys/modules/greet/parameters
#echo 0 > /sys/modules/greet/parameters/debug
#sudo rmmod greet
#dmesg
说明:
在源代码中,在定义内核模块参数的时候指定了相应的权限,这在成功加载模块后可以看到。
关于宏S_IRUGO和S_IWUSR,定义在linux/stat.h中,实际上是文件访问权限的八进制掩码,转贴部分代码如下:
#define S_IRWXU 00700
#define S_IRUSR 00400
#define S_IWUSR 00200
#define S_IXUSR 00100
#define S_IRWXG 00070
#define S_IRGRP 00040
#define S_IWGRP 00020
#define S_IXGRP 00010
#define S_IRWXO 00007
#define S_IROTH 00004
#define S_IWOTH 00002
#define S_IXOTH 00001
#endif
#ifdef __KERNEL__
#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO)
#define S_IALLUGO (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
#define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH)
#define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH)
#define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH)