#
# Makefile for kernel helloworld drivers
#
# If KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq ($(KERNELRELEASE),)
obj-m := helloDev.o
# Otherwise we were called directly from the command
# line; invoke the kernel build system.
else
KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build // 取内核的build目录给KDIR
PWD := $(shell pwd) // 表示取当前的pwd值赋给PWD变量
all:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) // -C:表示change,change到内核源码里面去编译, M=$( ):指定了要编译驱动的源码目录;因此就该程序会再次进入我们这个makefile文件进行执行,接下来继续去判断 KERNELRELEASE 变量.......
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean
endif
分析:
由于首次进入这个Makefile的时候KERNELRELEASE 肯定为空,所以会进入到else中
KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build 内核目录
PWD := $(shell pwd) 当前目录
看all:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD)
先编译$(KERNEL_DIR)下的Makefile这个时候会让KERNELRELEASE不为空,然后再编译$(PWD)目录下的Makefile也就是当前的Makefile 所以此时就会调用obj-m := helloDev.o生成目标驱动文件
obj-m := helloDev.o这句话是给内核使用,他会收集内核驱动的binary文件,最终生成.ko的驱动文件。
总结:
这个Makefile会进来两次,第一次编译内核 第二次生成.ko文件
有一个博主 写的
①简单字符设备驱动总体代码的详细分析
https://blog.csdn.net/qq_18649781/article/details/103760893