1 Makefile编写
ifneq ($(KERNELRELEASE),)
obj-m := mytest.omytest-objs := file1.o file2.o file3.oelseKDIR := /lib/modules/$(shell uname -r)/buildPWD := $(shell pwd)default: $(MAKE) -C $(KDIR) M=$(PWD) modules//到linux源码所在的目录执行主Makefile 并当前路径传给主Makefile,告诉主Makefile执行完后返回到当前目录,执行Makefileendif解释为:KERNELRELEASE是在内核源码的顶层Makefile中定义的一个变量,在第一次读取执行此Makefile时,KERNELRELEASE没有被定义,所以make将读取执行else之后的内容。如果make的目标是clean,直接执行clean操作,然后结束。当make的目标为all时,-C$(KDIR) 指明跳转到内核源码目录下读取那里的Makefile;M=$(PWD)表明然后返回到当前目录继续读入、执行当前的Makefile。当从内核源码目录返回时,KERNELRELEASE已被被定义,kbuild也被启动去解析kbuild语法的语句,make将继续读取else之前的内容。else之前的内容为kbuild语法的语句,指明模块源码中各文件的依赖关系,以及要生成的目标模块名。mytest-objs := file1.o file2.ofile3.o表示mytest.o 由file1.o,file2.o与file3.o 连接生成。obj-m :=mytest.o表示编译连接后将生成mytest.o模块。2 测试
源文件
1 // 2 //hello.c 3 // 4 #include5 #include 6 #include 7 8 static int hello_init(void) { 9 printk(KERN_WARNING "Module init: Hello world!\n");10 return 0;11 }12 13 static void hello_exit(void) {14 printk(KERN_WARNING "Module exit: bye-bye\n");15 }16 17 module_init(hello_init);18 module_exit(hello_exit);
Makefile文件
1 ifneq ($(KERNELRELEASE),) 2 obj-m:=hello.o 3 else 4 KDIR := /lib/modules/$(shell uname -r)/build 5 6 all: 7 make -C $(KDIR) M=$(PWD) modules 8 clean: 9 make -C $(KDIR) M=$(PWD) clean10 endif
插入模块到内核
# insmod hello.ko
查看输出
[root@localhost demo]# dmesg | tail -n 5
<span>[ 2445.017321] virbr0: port 2(vif1.0) entering forwarding state[ 2445.017439] virbr0: port 2(vif1.0) entering disabled state
[ 2494.639683] hello: module license 'unspecified' taints kernel.
[ 2494.639688] Disabling lock debugging due to kernel taint
[ 2494.639841] Module init: Hello world!