Scull 编译LINUX驱动的MAKEFILE

LINUX设备驱动程序的例子Scull的Makefile如下:

# Comment/uncomment the following line to disable/enable debugging
#DEBUG = y

# Add your debugging flag (or not) to CFLAGS
ifeq ($(DEBUG), y)
   DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expand inlines
else
   DEBFLAGS = -O2
endif
 
EXTRA_CFLAGS += $(DEBFLAGS) -I$(LDDINC)
 
ifneq ($(KERNELRELEASE),)
   # call from kernel build system
   scull-objs := main.o pipe.o access.o
   obj-m   := scull.o
else
   KERNELDIR ?= /lib/modules/$(shell uname -r)/build
   PWD       := $(shell pwd)
modules:
	echo $(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD)/../include modules
	$(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD)/../include modules
endif

clean:	
	rm -rf *.o *~ core .depend *.mod.o .*.cmd *.ko *.mod.c \
	.tmp_versions *.markers *.symvers modules.order a.out sculltest

depend .depend dep:
	$(CC) $(CFLAGS) -M *.c > .depend

ifeq (.depend,$(wildcard .depend))
	include .depend
endif

关于ifneq ($(KERNELRELEASE),)

其中KERNELRELEASE定义在内核的makefile中,所以我们走else分支,定义了KERNELDIR 和PWD变量

$(shell uname -r)得到的值等于shell中执行uname -r,得到操作系统的发行编号,比如我用的Ubuntu 20.4的发型编号为:

eden@ubuntu:~/Documents/Project/scull$ uname -r
5.15.0-46-generic

同理 $(shell pwd)得到的值等于shell中执行pwd得到的值,pwd就是当前命令执行的路径,因为我们是在模块源代码目录下执行的make,pwd得到的就是模块源代码目录

$(MAKE)其实就是make

$(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD)/../include modules

在我的机子上最终解析就是:

make -C /lib/modules/5.15.0-46-generic/build M=/home/eden/Documents/Project/scull LDDINC=/home/eden/Documents/Project/scull/../include modules

上述命令首先将目录改变到-C选项指向的路径(即内核源代码目录),其中保存有内核的顶层makefile文件,下面是我们的内核源代码目录的文件列表,可以看到有一个Makefile文件:

eden@ubuntu:/usr/src/linux-headers-5.15.0-46-generic$ ls -la
total 2076
drwxrwxrwx 7 root root    4096 Sep 26 08:18 .
drwxr-xr-x 6 root root    4096 Sep  4 19:47 ..
drwxrwxrwx 3 root root    4096 Sep  4 19:47 arch
lrwxrwxrwx 1 root root      41 Aug  4 11:44 block -> ../linux-hwe-5.15-headers-5.15.0-46/block
lrwxrwxrwx 1 root root      41 Aug  4 11:44 certs -> ../linux-hwe-5.15-headers-5.15.0-46/certs
-rwxrwxrwx 1 root root  262223 Aug  4 11:44 .config
lrwxrwxrwx 1 root root      42 Aug  4 11:44 crypto -> ../linux-hwe-5.15-headers-5.15.0-46/crypto
lrwxrwxrwx 1 root root      49 Aug  4 11:44 Documentation -> ../linux-hwe-5.15-headers-5.15.0-46/Documentation
lrwxrwxrwx 1 root root      43 Aug  4 11:44 drivers -> ../linux-hwe-5.15-headers-5.15.0-46/drivers
lrwxrwxrwx 1 root root      38 Aug  4 11:44 fs -> ../linux-hwe-5.15-headers-5.15.0-46/fs
-rwxrwxrwx 1 root root      39 Aug  4 11:44 .gitignore
drwxrwxrwx 4 root root    4096 Sep  4 19:47 include
lrwxrwxrwx 1 root root      40 Aug  4 11:44 init -> ../linux-hwe-5.15-headers-5.15.0-46/init
lrwxrwxrwx 1 root root      39 Aug  4 11:44 ipc -> ../linux-hwe-5.15-headers-5.15.0-46/ipc
lrwxrwxrwx 1 root root      42 Aug  4 11:44 Kbuild -> ../linux-hwe-5.15-headers-5.15.0-46/Kbuild
lrwxrwxrwx 1 root root      43 Aug  4 11:44 Kconfig -> ../linux-hwe-5.15-headers-5.15.0-46/Kconfig
drwxrwxrwx 2 root root    4096 Sep  4 19:47 kernel
lrwxrwxrwx 1 root root      39 Aug  4 11:44 lib -> ../linux-hwe-5.15-headers-5.15.0-46/lib
lrwxrwxrwx 1 root root      44 Aug  4 11:44 Makefile -> ../linux-hwe-5.15-headers-5.15.0-46/Makefile
-rwxrwxrwx 1 root root    1368 Aug  4 11:44 .missing-syscalls.d
lrwxrwxrwx 1 root root      38 Aug  4 11:44 mm -> ../linux-hwe-5.15-headers-5.15.0-46/mm
-rwxrwxrwx 1 root root 1812781 Aug  4 11:44 Module.symvers
lrwxrwxrwx 1 root root      39 Aug  4 11:44 net -> ../linux-hwe-5.15-headers-5.15.0-46/net
lrwxrwxrwx 1 root root      43 Aug  4 11:44 samples -> ../linux-hwe-5.15-headers-5.15.0-46/samples
drwxrwxrwx 7 root root   12288 Sep  4 19:47 scripts
lrwxrwxrwx 1 root root      44 Aug  4 11:44 security -> ../linux-hwe-5.15-headers-5.15.0-46/security
lrwxrwxrwx 1 root root      41 Aug  4 11:44 sound -> ../linux-hwe-5.15-headers-5.15.0-46/sound
drwxrwxrwx 4 root root    4096 Sep  4 19:47 tools
lrwxrwxrwx 1 root root      42 Aug  4 11:44 ubuntu -> ../linux-hwe-5.15-headers-5.15.0-46/ubuntu
lrwxrwxrwx 1 root root      39 Aug  4 11:44 usr -> ../linux-hwe-5.15-headers-5.15.0-46/usr
lrwxrwxrwx 1 root root      40 Aug  4 11:44 virt -> ../linux-hwe-5.15-headers-5.15.0-46/virt

M=选项让该makefile在构造modules目标之前返回到模块原代码目录,这里我们的模块源代码路径就是/home/eden/Documents/Project/scull。

这样就相对于再次执行了make命令

这次make包含了内核的makefile文件(kernel build system),并且还有上面的makefile文件,这次

ifneq ($(KERNELRELEASE),)条件满足,执行

scull-objs := main.o pipe.o access.o
obj-m   := scull.o

上述两句是扩展GUN Make语法,obj-m :=scull.o表示有一个模块需要从scull.o中构造,而从该目标文件中构造的模块名称为scull.ko.

scull-objs := main.o pipe.o access.o表示scull.ko由main.cc pipe.c access.c这3个源文件生成。

猜你喜欢

转载自blog.csdn.net/MashiMaroJ/article/details/127063305