linux内核模块编译

1 Makefile编写

ifneq ($(KERNELRELEASE),)
obj-m := mytest.o
mytest-objs := file1.o file2.o file3.o
else
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
       $(MAKE) -C $(KDIR) M=$(PWD) modules//到linux源码所在的目录执行主Makefile 并当前路径传给主Makefile,告诉主Makefile执行完后返回到当前目录,执行Makefile
endif
解释为:
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.o

file3.o表示mytest.o 由file1.o,file2.o与file3.o 连接生成。obj-m :=
mytest.o表示编译连接后将生成mytest.o模块。

2 测试

  源文件

 1 //
 2 //hello.c
 3 //
 4 #include <linux/init.h>
 5 #include <linux/kernel.h>
 6 #include <linux/module.h>
 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) clean
10 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!

posted @ 2013-04-05 19:10  在于思考  阅读(1525)  评论(0编辑  收藏  举报