语句解释
# ifneq是比较两个参数是否相同,这里被比较参数为空
ifneq ($(KERNELRELEASE),) # 如果KERNELRELEASE的返回值是非空的
MODULE_NAME = hellomodule # 指定驱动模块的名称hellomodule,赋给MODULE_NAME
$(MODULE_NAME)-objs := hello.o # 指定驱动模块的所有依赖文件hello.o
obj-m := $(MODULE_NAME).o # 驱动程序编译成模块,生成hellomodule.o模块
else # 如果KERNELRELEASE的返回值是空的
KERNEL_DIR = /lib/modules/`uname -r`/build # 指定内核的路径,uname是Linux的命令,显示操作系统的版本号
MODULEDIR := $(shell pwd)
# 指定模块的路径,把当前目录的地址赋给MODULEDIR,shell是make的函数,shell pwd执行Linux命令pwd,显示工作目录
.PHONY: modules # .PHONY表示modules是个伪目标文件
default: modules
modules:
make -C $(KERNEL_DIR) M=$(MODULEDIR) modules
# -C的作用是将当前工作目录转移到你所指定的位置,即KERNEL_DIR目录中
# M=的作用是当用户需要以某个内核为基础编译一个外部模块的话,需要在make modules命令中加入"M=dir"
# 程序会自动到你所指定的dir目录中(即KERNEL_DIR目录)查找模块源码,将其编译,生成KO文件。
clean distclean: # 类似make clean,但同时也将configure生成的文件全部删除掉,包括Makefile文件
rm -f *.o *.mod.c .*.*.cmd *.ko # 删除目标文件,包括.o文件和执行文件
rm -rf .tmp_versions # 删除所有的暂时版本
endif
运行过程
在第一次运行的时候,KERNELRELEASE中的值是空的,则执行else中的语句,设置路径建立文件夹并将目录的地址赋给MODULEDIR,在modules中执行make modules,设置KERNEL_DIR的路径在build文件夹下
在下一次运行的时候,KERNELRELEASE中的值是非空的,于是将hellomodule赋给MODULE_NAME,然后用hello.o生成hellomodule模块,在编译后生成hellomodule.o模块。在modules中再次执行make modules,程序自动到KERNEL_DIR的目录中查找模块源码,将其编译生成KO文件。
最后执行clean,将生成的目标文件以及暂时版本全部删除。