我的任务是移植系统,将CentOS5.8的运用程序和驱动在CentOS6.8中重新编译并需要正常运行,在此过程中遇到一个模块加载的问题,特此记录下来
问题如下:
我的内核模块名为switcher.ko
进入到内核模块文件夹目录中,开始加载模块
insmod switcher.ko
提示错误
insmod: error inserting 'switcher.ko': -1 Unknown symbol in module
shell窗口下没有提示其他错误信息,因为我加了printk打印,所以这时候我查看系统日志信息,获取模块加载失败原因
tail -f /var/log/messages
获取到如下信息
Jan 21 10:26:12 etc kernel: switcher: Unknown symbol __x86_indirect_thunk_edx
Jan 21 10:26:12 etc kernel: switcher: Unknown symbol __x86_indirect_thunk_ecx
Jan 21 10:26:12 etc kernel: switcher: Unknown symbol __x86_indirect_thunk_esi
Jan 21 10:26:12 etc kernel: switcher: Unknown symbol __x86_indirect_thunk_eax
Jan 21 10:26:12 etc kernel: switcher: Unknown symbol __x86_indirect_thunk_ebx
经过查询获知,这个是通过内核连接获取到模块
arch/x86/include/asm/asm-prototypes.h:15:#define INDIRECT_THUNK(reg) extern asmlinkage void __x86_indirect_thunk_r ## reg(void);
查询INDIRECT_THUNK可以了解该定义域CONFIG_RETPOLINE宏定义有关
retpoline是什么东西?
我百度了一下,好像是在某个内核版本之后添加封装接口,每次调用特定接口时会通过该retpoline进行安全校验,具体的不清楚,目前来说我的内核即使开启了该内核选项还是提示该错误
开启该内核选项
cd /lib/modules/2.6.32-642.el6.i686/build
make menuconfig
Processor type and features --->
Avoid speculative indirect branches in kernel
查看该内核模块信息
modinfo switcher.ko
filename: switcher.ko
description: Support to control 2 Marvel 88E6097 switch chips
author: dongyun,gktel.com.cn
license: GPL
retpoline: Y
srcversion: EDB1348DCA1EA7250B98486
depends: lpcio
vermagic: 2.6.32-696.30.1.el6.i686 SMP mod_unload modversions 686
retpoline一直为Y状态,通过在该模块编译环境中了解
gcc -Wp,-MD,/home/whoami/come_drivers/marvell-switch/DSDT_2.8b/src/platform/.gtMiiSmiIf.o.d -nostdinc -isystem /usr/lib/gcc/i686-redhat-linux/4.4.7/include -Iinclude -I/usr/src/kernels/2.6.32-696.30.1.el6.i686/include/uapi -I/usr/src/kernels/2.6.32-696.30.1.el6.i686/arch/x86/include -Iarch/include/generated -Iinclude -include /usr/src/kernels/2.6.32-696.30.1.el6.i686/include/linux/kconfig.h -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -fno-delete-null-pointer-checks -O2 -m32 -msoft-float -mregparm=3 -freg-struct-return -mpreferred-stack-boundary=2 -march=i686 -mtune=generic -Wa,-mtune=generic32 -ffreestanding -fstack-protector -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_AVX=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mindirect-branch=thunk-extern -mindirect-branch-register -DRETPOLINE -Wframe-larger-than=1024 -Wno-unused-but-set-variable -fomit-frame-pointer -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fno-dwarf2-cfi-asm -fconserve-stack -DMODULE -D"KBUILD_STR(s)=\#s" -D"KBUILD_BASENAME=KBUILD_STR(gtMiiSmiIf)" -D"KBUILD_MODNAME=KBUILD_STR(switcher)" -D"DEBUG_HASH=14" -D"DEBUG_HASH2=61" -c -o /home/whoami/come_drivers/marvell-switch/DSDT_2.8b/src/platform/.tmp_gtMiiSmiIf.o /home/whoami/come_drivers/marvell-switch/DSDT_2.8b/src/platform/gtMiiSmiIf.c
编译该模块时使用了-DRETPOLINE
我的修改方法
# Avoid indirect branches in kernel to deal with Spectre
ifdef CONFIG_RETPOLINE
RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch=thunk-extern -mindirect-branch-register)
ifneq ($(RETPOLINE_CFLAGS),)
# KBUILD_CFLAGS += $(RETPOLINE_CFLAGS) -DRETPOLINE
else
# Fail brew build, but let other users proceed with warning
RETPOLINE_MSG := CONFIG_RETPOLINE=y, but not supported by the compiler. Toolchain update recommended.
KBUILD_USER := $(shell id -un)
ifeq ($(KBUILD_USER), mockbuild)
$(error $(RETPOLINE_MSG))
else
$(warning $(RETPOLINE_MSG))
endif
endif
endif
注释 KBUILD_CFLAGS += $(RETPOLINE_CFLAGS) -DRETPOLINE,使其编译的时候不使用-DRETPOLINE
然后重新编译模块,没有在提示上面的错误,模块能够正常加载
modinfo switcher.ko
filename: switcher.ko
description: Support to control 2 Marvel 88E6097 switch chips
author: dongyun,gktel.com.cn
license: GPL
srcversion: EDB1348DCA1EA7250B98486
depends: lpcio
vermagic: 2.6.32-696.30.1.el6.i686 SMP mod_unload modversions 686