在编译内核模块时,如有Makefile文件如下:
# KERNELRELEASE,是linux内核模块编译系统makefile文件中定义的宏,
# 初次执行本模块的makfile时,还未进入内核模块编译系统,所以KERNELRELEASE为空
# 内核编译模块反过来调用本模块的makefile时,KERNELRELEASE就有值了
ifeq ($(KERNELRELEASE),)
X86_PATH := /lib/modules/$(shell uname -r)/build
ARM_PATH := /home/linux/imx6ull-iot-smart-car/linux-imx-driver
MODULE_PATH := $(shell pwd)
x86_module:
make -C $(X86_PATH) M=$(MODULE_PATH) modules
arm_module:
# make -C:进入内核的编译系统
# M=$(MODULE_PATH) modules ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-:传给内核编译系统的参数。
# M=$(MODULE_PATH):告诉内核编译系统,模块编译的路径;
# modules: 是linux内核模块编译系统makefile文件中的modules
make -C $(ARM_PATH) M=$(MODULE_PATH) modules ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.order *.mod
else
# else分支是被内核模块编译的时候反过来调用的分支。主要用于内核编译模块获取目标文件
hello-objs := file1.o file2.o
obj-m := hello.o
endif
KERNELRELEASE是在内核源码的顶层Makefile中定义的一个变量。
在本模块内执行make 命令编译时,由于KERNELRELEASE没有被定义,值为空,所以make将执行ifeq分支:如果make的参数是clean,直接执行clean操作,然后结束。
当make的目标为x86_module/arm_module或者不传参时:
• -C $(xxx):指明跳转到内核编译系统。
• modules:传给内核编译系统的参数。表明利用内核编译系统来编译本模块,可省略。
• M=$(PWD) :传给内核编译系统的参数。告诉内核编译系统本模块的路径;内核模块编译系统会反过来执行本模块的Makefile,主要目的是走else分支获取本模块的目标文件。
• ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-:传给内核编译系统的参数,表面编译架构、用什么编译器编译。
KERNELRELEASE是内核编译系统的Makefile中定义的宏,当内核编译系统反过来调用本模块的Makefile时,KERNELRELEASE已被定义,不为空,所以走else分支。
else分支,主要用于指明模块源码中各文件的依赖关系,以及要生成的目标模块名。
• param-objs := file1.o file2.o 表示param.o由file1.o与file2.o 连接生成,
• obj-m := param.o表示编译连接后将生成param.o模块。

469

被折叠的 条评论
为什么被折叠?



