内核模块具有如下特点:
1、模块本身并不编译进内核文件;2、可以根据需要,在内核运行期间动态地安装或卸载。
模块操作:
加载模块:insmod hello.ko
卸载模块:rmmod hello
查看内核模块:lsmod
加载模块的另一种方式:modprobe hello
modprobe与insmod的不同之处在于它会根据文件/lib/modules/<$version>/modules.dep来查看要加载的模块,看它是否还依赖于其他模块,
如果是,modprobe会先首先找到这些模块,把它们加载到内核。
一、最简单的模块代码:
#include
#include
MODULE_LICENSE("GPL"); ---》许可证声明
MODULE_AUTHOR("David Xie");
MODULE_DESCRIPTION("Hello World Module");
MODULE_ALIAS("a simplest module");
static int __init hello_init()
{
printk(KERN_EMERG"Hello World!\n");
return 0;
}
static void __exit hello_exit()
{
printk("<6>hello exit\n");
}
module_init(hello_init);
module_exit(hello_exit);
单源文件makefile:
ifneq ($(KERNELRELEASE),) --》第一次编译的时候,KERNELRELEASE为空,所以执行else里的语句,第二次开始则不为空
obj-m := hello.o --》hello.o与hello.c对应
else
KDIR := /lib/modules/2.6.18-53.el5/build
all:
make -C $(KDIR) M=$(PWD) modules --》-C的意思是进入KDIR,使用这个目录下的makefile;m=$(PWD)的意思是要编译的模块在当前目录
clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers
endif
以上为x86平台下的实现,若为arm平台则:make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
多源文件makefile:
假设两个源文件,main.c和add.c,则改变上面makefile中的两行,其他不变
obj-m := hello.o
hello-objs := main.o add.o
二、模块参数
例子:
#include
#include
MODULE_LICENSE("GPL");
static char *name = "David Xie";
static int age = 30;
module_param(age, int, S_IRUGO); --》用于在加载模块时给模块传递参数
module_param(name, charp, S_IRUGO); --》第一个参数是模块参数的名称,第二个是类型(int,bool,charp),
第三个是模块参数的访问权限(S_IRUGO--任何用户都对/sys/module出现的该参数有读权限,
S_IWUSR,允许root修改/sys/module中出现的该参数)
static int hello_init(void)
{
printk(KERN_EMERG" Name:%s\n",name);
printk(KERN_INFO" Age:%d\n",age);
return 0;
}
static void hello_exit(void)
{
printk(KERN_INFO" Module Exit\n ");
}
module_init(hello_init);
module_exit(hello_exit);
insmod时若无加参数,则为代码里设定的值,若要添加参数,则格式为:insmod param.ko name=... age =... 注意类型要对应
三、内核符号导出,模块之间存在依赖时使用
EXPORT_SYMBOL(符号名)、EXPORT_SYMBOL_GPL(符号名),其中后者只能用于包含GPL许可证的模块
模块一:hello.c
#include
#include
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Xie");
MODULE_DESCRIPTION("Hello World Module");
MODULE_ALIAS("a simplest module");
extern int add_integar(int a,int b); --》在模块二中定义
extern int sub_integar(int a,int b);
static int __init hello_init()
{
int res = add_integar(1,2);
return 0;
}
static void __exit hello_exit()
{
int res = sub_integar(2,1);
}
module_init(hello_init);
module_exit(hello_exit);
模块二:calc.c
#include
#include
MODULE_LICENSE("GPL");
int add_integar(int a,int b)
{
return a+b;
}
int sub_integar(int a,int b)
{
return a-b;
}
static int __init sym_init()
{
return 0;
}
static void __exit sym_exit()
{
}
module_init(sym_init);
module_exit(sym_exit);
/* EXPORT_SYMBOL(add_integar); */ --》这两句要添加才能使用hello.ko模块,这个模块要先安装,再安装hello.ko模块,卸载时相反
/* EXPORT_SYMBOL(sub_integar); */
阅读(1905) | 评论(0) | 转发(0) |