若要编译hello的内核模块,最简单的方法就是要编写如下内容的Makefile(若对Makefile比较陌生,请参考Linux开发基础讲义): ----------------------------------------------------------------------- ifeq ($(KERNELRELEASE),) KERNELDIR ?=/usr/src/kernels/2.6.18-8.el5xen-i686 #指向你的内核代码目录 #KERNELDIR ?=/home/eetek/linux-2.6.29-eetek PWD := $(shell pwd) all: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules #编译内核模块的指令 clean: #删除生成的所有文件 rm -rf modules.* *.o *~ core .depend .*.cmd *.ko rm –rf *.mod.c .tmp_versions Module* .PHONY: modules modules_install clean else obj-m := hello.o #你要编译的模块名称 endif ----------------------------------------------------------------------- 对于上述的Makefile需要特别说明如下几点: (1) $(MAKE) -C $(KERNELDIR) M=$(PWD) modules #编译内核模块的指令 ü 理解这条指令,首先需要理解make命令选项-C的作用,-C是指Change Directory。 ü MAKE是Makefile中的宏变量,和KERNELDIR相似,要引用这个宏变量的值需要使用$符号。在这里实际上就是指向make程序。注:此时应该写为$(MAKE),而不能写成$MAKE,请思考为什么。 ü M=$(PWD) 是指要编译的内核模块的源程序在那个目录下,$(PWD)指与Makefile在同一目录下,也就是当前目录。(pwd命令的作用是:print work directory).modules指明要按照内核模块的方式编译。 结合起来理解,就是进入$(KERNELDIR)的目录,并且执行make命令,如果没有M=$(PWD) modules,make –C $(KERNELDIR)将是编译Linux内核映像的指令。M=$(PWD) modules也就是按照$(KERNELDIR)中内核模块的方式编译$(PWD)目录下的程序。modules实际上是$(KERNELDIR)目录下的Makefile的一个Target入口. 既然是为$(KERNELDIR)编译内核模块,所以必须要求$(KERNELDIR)这个内核必须正确配置,并且得到编译的,以为编译模块的过程需要使用内核配置的相关信息,比如处理器的类型等。至于如何配置Linux内核,请参考Linux系统移植过程中的相关实验。 (2) obj-m = hello.o #你要编译的模块名称 这里必须和$(PWD)目录下C程序文件的名称相对应,如果C程序文件为world.c,那么必须修改成obj-m = world.o. 和很多C语言程序一样,一个内核模块也可能有多个C程序文件,那么如何修改Makefile让其编译成一个内核模块呢?此时,需要将obj-m = hello.o换成如下代码: Obj-m = hello.o Hello-objs = hello1.o, hello2.o (3) clean是Makefile的入口,其目的是为了清除所有生成的文件。 正确的配置和编译了$(KERNELDIR)的内核,就可以编译hello的内核模块了,你将会在当前的目录中看到一个hello.ko的内核模块。 |
更多回帖