有时,需要对内核模块的编译进行优化或取消优化,加上自定义宏等。这就要对默认的编译选项进行修改了。 这一块内容属于内核的 Kbuild 系统,Kbuild系统非常灵活,在Makefile中定义了有较多的变量用于控制 编译行为,其中就有编译选项的变量。Kbuild系统的一个特点是很多变量会从顶层makefile继承下来,如果 不修改就保持一致,用户也可以在自己添加的模块的makefile中修改这些变量,这样仅对自己的模块生效。
详细文档参考:
内核Kbuild系统 - 内核Makefile说明
修改模块的编译选项参数
对于自定义的模块,在makefile中可以使用ccflags-y
变量指定编译选项,定义在模块的makefile中,仅对当前模块makefile生效。 将ccflags-y变量写在obj-m相同的地方,参考:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ifneq ($(KERNELRELEASE),)
obj-m:=testmod.o
ccflags-y:=-O0 -DMYDBG
# ccflags-y:=-O2
else
KERNEL_DIR ?= /usr/src/linux-headers-`uname -r`
# ARCH:=
# CROSS_COMPILE:=
# 用于将ARCH和CROSS_COMPILE 参数传递给内核的Makefile
# export ARCH CROSS_COMPILE
all:
# $(CURDIR) 是makefile的内置变量,为当前目录,等效于 CURDIR = `pwd`
$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) modules
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) clean
endif
可以在编译时补充V=1
参数显示详细信息以查看是否生效。如 make -j4 V=1
使用gnuc扩展以禁用优化
如只要对模块内某个关键函数取消优化,进行测试,可以使用__attribute__((optimize("O0"))
描述函数,以实现对单个函数的取消优化。
1
2
3
4
void __attribute__((optimize("O0"))) kmem_cache_test(void)
{
// unmodifiable compiler code
}
这样,该函数就是以 -O0
编译的。针对单个函数使用,比较方便。