一个普通的内核模块Makefile文件一般是下面的样子
pwd = $(shell pwd)
KERNEL_SRC = /lib/modules/$(shell uname -r)/build
obj-m := hello.o
hello-objs := hello.o
all:
$(MAKE) -C $(KERNEL_SRC) M=$(PWD) modules
clean:
rm -f *o *~ .*cmd *o *ko *~ .*cmd hello.mod.c
驱动模块名称
网上好多都是obj-m:=hello.o这个形式,我一直想改掉,结果找到方法了。obj-m:=$(MODULE).o中的m是说要将这个驱动做成模块,使用insmod加载、rmmod删除。而在内核很多目录中的Makefile还可以看到另一种形式obj-y,意思是说将这个驱动搞到内核中去,跟着内核一起混,系统启动时它就加载了。关于:=就直接百度了,顺便可以把$@、$<、$^这几个给一起学习了。注意,$(MODULE).o是.o文件,不是.ko文件,内核会帮你从hello.o创建一个hello.ko模块的。$(MODULE)-objs := foo.o bar.o是说这个模块由两个文件组成,这里也是.o文件。实际使用中需要修改模块名称以及模块源文件(其实算是目标文件)名称。
Make会执行两次
当我们敲下make时,我们进入了这个权威的makefile二次。第一次进入makefile,发现KERNELRELEASE没有被设置时,于是她根据build这个符号链接定位内核源代码目录,然后进入default,开始第二个make,-C选项进入内核源代码目录,找到顶层的makefile,然后-M返回当前目录执行makefile文件,这就是第二次进入这个makefile,在这次,由于KERNELRELEASE变量已经定义,因此不需要进入else语言,在这里,obj-m:=hello.o这个语句和我们以前不是驱动程序中的makefile不同,在这里内核会帮你处理一切,这句话是告诉内核,需要从hello.o创建一个驱动模型(module)。