编译环境
参照源码 /Documentation/kbuild/modules.txt
配置makefile,然后make
ifneq ($(KERNELRELEASE),)
# kbuild part of makefile
obj-m := proTest.o
else
# normal makefile
KDIR ?= /lib/modules/`uname -r`/build
default:
$(MAKE) -C $(KDIR) M=$$PWD
endif
先写个helloWorld吧
我们现在来实现一个Module,就是在kernel中运行的一个小组件,系统启动的时候会加载很多的module,现在实现一个手动加载的。
#include <linux/module.h>
char modNameInLog[] = "proTest";
static int __init myinit (void )
{
printk("MyMod> Install %s module.\n",modNameInLog);
return 0;
}
static void __exit myexit (void )
{
printk("MyMod> Remove %s module.\n",modNameInLog);
}
module_init(myinit);
module_exit(myexit);
然后在bash里面make
编译, insmod proTest.ko
加载module,rmmod proTest.ko
去掉module。
kernel里面使用printk
输出到log文件,dmesg
命令可以看输出。
[root@fedora arena]# insmod proTest.ko
[root@fedora arena]# dmesg
[40823.084204] MyMod> Install proTest module.
[root@fedora arena]# rmmod proTest.ko
[root@fedora arena]# dmesg
[40840.031236] MyMod> Remove proTest module.
参考链接
一步一步写内核模块之HelloWorld:http://web.archive.org/web/20150628053535/http://uliweb.clkg.org:80/tutorial/view_chapter/75
内核态和用户态:http://book.51cto.com/art/201001/177431.htm
扩展之 然后我们来传个参
module_param(参数名,type,/sys中访问权限)
指定对外变量module_param_array(参数名,type,读了几个参,/sys中访问权限)
指定数组MODULE_PARM_DESC(proArray, "Input array.");
参数说明,使用modinfo proTest.ko
看介绍。
Type可以是比如 short int charp long ulong bool等等...(charp是字符串)
直接看源码吧 好理解
#include <linux/module.h>
#include <linux/kernel.h>
static char* name="defaultName";
module_param(name, charp, 0644);
static int proArray[6];
int arrSize;
module_param_array(proArray, int, &arrSize, 0644);
MODULE_PARM_DESC(proArray, "Input array.");
char modNameInLog[] = "proTest";
static int __init myinit (void )
{
int i;
printk(KERN_INFO "MyMod> Install %s module.\n",modNameInLog);
printk(KERN_DEBUG "(String) name = %s",name);
printk("Int array size = %d",arrSize);
for(i=0; i<arrSize; i++)
printk(" array[%d]=%d",i,proArray[i]);
return 0;
}
static void __exit myexit (void )
{
printk(KERN_DEBUG "(String) name= %s",name);
printk(KERN_INFO "MyMod> Remove %s module.\n",modNameInLog);
}
module_init(myinit);
module_exit(myexit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("vrqq");
上文printk里面可以用:KERN_ALERT, KERN_CRIT, KERN_ERR, KERN_WARNING, KERN_NOTICE, KERN_INFO, KERN_DEBUG.
运行一下试试
[root@fedora arena]# insmod proTest.ko name="goodDay" proArray=1,2,9
[root@fedora arena]# cat /sys/module/proTest/parameters/name
goodDay
[root@fedora arena]# echo "bye!" > /sys/module/proTest/parameters/name
[root@fedora arena]# rmmod proTest.ko
[root@fedora arena]# dmesg
[41789.790516] MyMod> Install proTest module.
[41789.790518] (String) name = goodDay
[41789.790519] Int array size = 3
[41789.790520] array[0]=1
[41789.790520] array[1]=2
[41789.790521] array[2]=9
[41935.273139] (String) name= bye!
[41935.273141] MyMod> Remove proTest module.
参考链接
一步一步学内核 内核模块之参数传递 : http://web.archive.org/web/20150627074727/http://uliweb.clkg.org:80/tutorial/view_chapter/78
The Linux Kernel Module Programming Guide https://www.tldp.org/LDP/lkmpg/2.6/html/lkmpg.html#AEN323