Linux Kernel之 Module

@vrqq  February 14, 2018

编译环境

参照源码 /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


添加新评论