Linux 内核:无法使用非 retpoline 编译器构建模块
操作系统 - RedHat 8.5,内核 4.18.0-348.20.1.el8_5.x86_64,gcc-8.5.0
我已经安装了 kernel-devel
和 kernel-headers
,并尝试过构建一个非常简单的内核模块(只需一对 printk())。
Makefile:
obj-m += test_mod.o
MSRC ?= $(PWD)
KDIR ?= /lib/modules/`uname -r`/build/
all:
make -C $(KDIR) M=$(MSRC) modules
clean:
make -C $(KDIR) M=$(MSRC) clean
但是我收到错误:
% make V=1
make -C /lib/modules/`uname -r`/build M= modules
make[1]: Entering directory '/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64'
arch/x86/Makefile:249: *** You are building kernel with non-retpoline compiler, please update your compiler.. Stop.
make[1]: Leaving directory '/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64'
make: *** [Makefile:4: all] Error 2
%
我是否必须升级到新的编译器,如果需要,需要哪个编译器版本?我的机器(RHEL8.5)上的 man gcc
表示支持 -mindirect-branch=
选项,我相信这是启用 retpoline 的选项。
是否可以禁用内核中的 retpoline 支持? (但是如果可能的话我不想重建内核)。
谢谢!
编辑
我按照0andriy的建议通过grub
配置文件禁用了retpoline
,(cat /proc/cmdline
显示 spectre_v2=off):
% grub2-editenv - set kernelopts=root=/dev/mapper/rhel_ps3cat5505k1-root ro crashkernel=auto resume=/dev/mapper/rhel_ps3cat5505k1-swap rd.lvm.lv=rhel_ps3cat5505k1/root rd.lvm.lv=rhel_ps3cat5505k1/swap rhgb quiet spectre_v2=off
% reboot
但是构建仍然失败:
% make V=1
make -C /lib/modules/`uname -r`/build/ M=/home/mrv/tmp modules
make[1]: Entering directory '/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64'
test -e include/generated/autoconf.h -a -e include/config/auto.conf || ( \
echo >&2; \
echo >&2 " ERROR: Kernel configuration is invalid."; \
echo >&2 " include/generated/autoconf.h or include/config/auto.conf are missing.";\
echo >&2 " Run 'make oldconfig && make prepare' on kernel src to fix it."; \
echo >&2 ; \
/bin/false)
mkdir -p /home/mrv/tmp/.tmp_versions ; rm -f /home/mrv/tmp/.tmp_versions/*
make -f ./scripts/Makefile.build obj=/home/mrv/tmp
(cat /dev/null; echo kernel//home/mrv/tmp/test_mod.ko;) > /home/mrv/tmp/modules.order
gcc -Wp,-MD,/home/mrv/tmp/.test_mod.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-redhat-linux/8/include -I./arch/x86/include -I./arch/x86/include/generated -I./include/drm-backport -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -include ./include/linux/compiler_types.h -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-PIE -DCC_HAVE_ASM_GOTO -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -DCONFIG_TPAUSE=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -Wframe-larger-than=2048 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -g -gdwarf-4 -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -fno-inline-functions-called-once -Wdeclaration-after-statement -Wno-pointer-sign -Wno-stringop-truncation -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -fmacro-prefix-map=./= -Wno-packed-not-aligned -DMODULE -DKBUILD_BASENAME='"test_mod"' -DKBUILD_MODNAME='"test_mod"' -c -o /home/mrv/tmp/.tmp_test_mod.o /home/mrv/tmp/test_mod.c
In file included from ./include/linux/module.h:18,
from /home/mrv/tmp/test_mod.c:1:
./include/linux/moduleparam.h:22:1: error: expected ‘,’ or ‘;’ before ‘static’
static const char __UNIQUE_ID(name)[] \
^~~~~~
./include/linux/module.h:158:32: note: in expansion of macro ‘__MODULE_INFO’
#define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
^~~~~~~~~~~~~
./include/linux/module.h:196:34: note: in expansion of macro ‘MODULE_INFO’
#define MODULE_LICENSE(_license) MODULE_INFO(license, _license)
^~~~~~~~~~~
/home/mrv/tmp/test_mod.c:19:1: note: in expansion of macro ‘MODULE_LICENSE’
MODULE_LICENSE("GPL")
^~~~~~~~~~~~~~
make[2]: *** [scripts/Makefile.build:322: /home/mrv/tmp/test_mod.o] Error 1
make[1]: *** [Makefile:1571: _module_/home/mrv/tmp] Error 2
make[1]: Leaving directory '/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64'
make: *** [Makefile:6: all] Error 2
%
因此,运行 'make oldconfig &&内核源代码目录 /usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64
中的“makeprepare”导致找不到 tools/build/Build.include
>。
不确定 RedHat 是否允许在 RHEL8 中构建内核模块。
EDIT2
简单内核模块:
#include <linux/module.h>
#include <linux/kernel.h>
static __init int test_init(void)
{
printk("Init module\n");
return 0;
}
static __exit void test_exit(void)
{
printk("Cleanup module\n");
}
module_init(test_init)
module_exit(test_exit)
MODULE_DESCRIPTION("Test module");
MODULE_LICENSE("GPL");
OS - RedHat 8.5, kernel 4.18.0-348.20.1.el8_5.x86_64, gcc-8.5.0
I have installed kernel-devel
and kernel-headers
, and tried to build a very simple kernel module (just a pair of printk()).
Makefile:
obj-m += test_mod.o
MSRC ?= $(PWD)
KDIR ?= /lib/modules/`uname -r`/build/
all:
make -C $(KDIR) M=$(MSRC) modules
clean:
make -C $(KDIR) M=$(MSRC) clean
However I'm getting error:
% make V=1
make -C /lib/modules/`uname -r`/build M= modules
make[1]: Entering directory '/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64'
arch/x86/Makefile:249: *** You are building kernel with non-retpoline compiler, please update your compiler.. Stop.
make[1]: Leaving directory '/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64'
make: *** [Makefile:4: all] Error 2
%
Do I have to upgrade to a new compiler, if so which compiler version is needed? man gcc
on my machine (RHEL8.5) says that -mindirect-branch=
option is supported, and I believe this is the one enabling retpoline.
Should it be possible to disable retpoline
support in the kernel? (however I would not like to rebuild the kernel if possible).
Thanks!
EDIT
I disabled retpoline
as suggested by 0andriy via grub
configuration file, (cat /proc/cmdline
shows spectre_v2=off):
% grub2-editenv - set kernelopts=root=/dev/mapper/rhel_ps3cat5505k1-root ro crashkernel=auto resume=/dev/mapper/rhel_ps3cat5505k1-swap rd.lvm.lv=rhel_ps3cat5505k1/root rd.lvm.lv=rhel_ps3cat5505k1/swap rhgb quiet spectre_v2=off
% reboot
However the build still fails:
% make V=1
make -C /lib/modules/`uname -r`/build/ M=/home/mrv/tmp modules
make[1]: Entering directory '/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64'
test -e include/generated/autoconf.h -a -e include/config/auto.conf || ( \
echo >&2; \
echo >&2 " ERROR: Kernel configuration is invalid."; \
echo >&2 " include/generated/autoconf.h or include/config/auto.conf are missing.";\
echo >&2 " Run 'make oldconfig && make prepare' on kernel src to fix it."; \
echo >&2 ; \
/bin/false)
mkdir -p /home/mrv/tmp/.tmp_versions ; rm -f /home/mrv/tmp/.tmp_versions/*
make -f ./scripts/Makefile.build obj=/home/mrv/tmp
(cat /dev/null; echo kernel//home/mrv/tmp/test_mod.ko;) > /home/mrv/tmp/modules.order
gcc -Wp,-MD,/home/mrv/tmp/.test_mod.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-redhat-linux/8/include -I./arch/x86/include -I./arch/x86/include/generated -I./include/drm-backport -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -include ./include/linux/compiler_types.h -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-PIE -DCC_HAVE_ASM_GOTO -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -DCONFIG_TPAUSE=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-int-in-bool-context -O2 --param=allow-store-data-races=0 -Wframe-larger-than=2048 -fstack-protector-strong -Wno-unused-but-set-variable -Wno-unused-const-variable -g -gdwarf-4 -pg -mrecord-mcount -mfentry -DCC_USING_FENTRY -fno-inline-functions-called-once -Wdeclaration-after-statement -Wno-pointer-sign -Wno-stringop-truncation -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -fmacro-prefix-map=./= -Wno-packed-not-aligned -DMODULE -DKBUILD_BASENAME='"test_mod"' -DKBUILD_MODNAME='"test_mod"' -c -o /home/mrv/tmp/.tmp_test_mod.o /home/mrv/tmp/test_mod.c
In file included from ./include/linux/module.h:18,
from /home/mrv/tmp/test_mod.c:1:
./include/linux/moduleparam.h:22:1: error: expected ‘,’ or ‘;’ before ‘static’
static const char __UNIQUE_ID(name)[] \
^~~~~~
./include/linux/module.h:158:32: note: in expansion of macro ‘__MODULE_INFO’
#define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
^~~~~~~~~~~~~
./include/linux/module.h:196:34: note: in expansion of macro ‘MODULE_INFO’
#define MODULE_LICENSE(_license) MODULE_INFO(license, _license)
^~~~~~~~~~~
/home/mrv/tmp/test_mod.c:19:1: note: in expansion of macro ‘MODULE_LICENSE’
MODULE_LICENSE("GPL")
^~~~~~~~~~~~~~
make[2]: *** [scripts/Makefile.build:322: /home/mrv/tmp/test_mod.o] Error 1
make[1]: *** [Makefile:1571: _module_/home/mrv/tmp] Error 2
make[1]: Leaving directory '/usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64'
make: *** [Makefile:6: all] Error 2
%
So, running 'make oldconfig && make prepare' in kernel sources directory /usr/src/kernels/4.18.0-348.20.1.el8_5.x86_64
results in failure to locate tools/build/Build.include
.
Not sure if RedHat allows to build kernel modules in RHEL8 at all.
EDIT2
Simple kernel module:
#include <linux/module.h>
#include <linux/kernel.h>
static __init int test_init(void)
{
printk("Init module\n");
return 0;
}
static __exit void test_exit(void)
{
printk("Cleanup module\n");
}
module_init(test_init)
module_exit(test_exit)
MODULE_DESCRIPTION("Test module");
MODULE_LICENSE("GPL");
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论