一、创建test目录,并在该目录下新建hello.c和Makefile文件
编写hello.c和Makefile文件
hello.c:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
int hello_init(void)
{
printk(KERN_INFO"Hello World!\n");
return 0;
}
void hello_exit(void)
{
printk(KERN_INFO"------exit------\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Adolph_wy");
MODULE_DESCRIPTION("This is a simple hello world module");
说明:所有的linux内核都必须包含头文件module.h
头文件kernel.h包含了常用的内核函数
头文件init.h包含了宏_init和_exit,一个内核模块至少包含两个函数,分别是模块被加载时执行的初始化函数init_module()和模块卸载时执行的结束函数cleanup_module()。在大部分内核版本里面这两个函数可以随意命名,通过宏module_init()和module_exit()注册调用要编译的内核模块,把代码嵌进内核空间。
这里的hello_init()函数为模块的初始化函数,hello_exit()为模块的退出和清理函数
其中printk()函数是内核定义的函数,与C库中的printf()功能相似,将输出信息打印到终端或系统日志
MODULE_LICENSE(“GPL”)是模块许可证声明,这是必须的
后面的两个是关于模块的作者与描述,这是可选的
Makefile文件:
obj-m := hello.o
KERNELDIR := /lib/modules/3.13.0-32-generic/build
PWD := $(shell pwd)
all:
make -C $(KERNELDIR) M=$(PWD) modules
clean:
make -C $(KERNELDIR) M=$(PWD) clean
说明:
1、obj这个变量指明最终产生模块的名字,如果内核模块的源文件只有一个,一般取与源文件一样的名字,这里的源文件是hello.c故取hello.o
【注】:如果有一个模块名为hello.ko是来自两个源文件(分别为hello1.c与hello2.c),正确写法应该是:
obj-m := hello.o
hello-objs := hello1.c hello2.c
2、定义一个变量KERNELDIR(该变量可以随意命名),KERNELDIR := /lib/modules/3.13.0-32-generic/build是编译内核模块所需要的Makefile路径,指示当前linux系统内核的源码位置,不同的操作系统可能路径不同
3、make -C 表示进入源代码目录编译,然后调用module目标,modules命令是在内核代码中执行的。传入参数M=当前目录,跳转到当前目录去make
【注】最后make -C需要注意tab键空格,会有颜色提示
二、编译模块
1、在Makefile文件所在目录下直接make,成功后查看是否生成hello.ko文件
2、使用insmod命令加载该模块模块,并用lsmod命令查看模块是否在内核中正确运行
3、使用dmesg命令查看模块运行后的输出
4、使用rmmod命令卸载模块