1, 首先,为什么会出现修改了kernel重新编译后magic num改变
内核版本是如何生成的:
Linux 内核在进行模块装载时先完成模块的 CRC 值校验,再核对 vermagic 中的字符信息,linux版本在 include/generated/utsrelease.h中定义,文件中的内容如下:
#define UTS_RELEASE "4.9.123"
utsrelease.h是kernel编译后自动生成的,用户更改里面的内容不会有效果。
这个值可以通过修改最顶层的Makefile文件来修改。
VERSION = 4
PATCHLEVEL = 9
SUBLEVEL = 123
EXTRAVERSION =
...
在init/version.c中,定义了kernel启动时的第一条打印信息:
/* FIXED STRINGS! Don't touch! */
const char linux_banner[] =
"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
const char linux_proc_banner[] =
"%s version %s"
" (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ")"
" (" LINUX_COMPILER ") %s\n";
这里UTS_RELEASE在kernel编译时自动生成
在init/main.c的asmlinkage __visible void __init start_kernel(void)函数中,有kernel启动的第一条打印信息,这条信息是dmesg命令打印出来:
pr_notice("%s", linux_banner);
驱动模块的version magic信息是怎么生成的:
4.x 内核下,在include/linux/vermagic.h中定义有VERMAGIC_STRING,如下:
#include <generated/utsrelease.h>
/* Simply sanity version stamp for modules. */
#ifdef CONFIG_SMP
#define MODULE_VERMAGIC_SMP "SMP "
#else
#define MODULE_VERMAGIC_SMP ""
#endif
#ifdef CONFIG_PREEMPT
#define MODULE_VERMAGIC_PREEMPT "preempt "
#else
#define MODULE_VERMAGIC_PREEMPT ""
#endif
#ifdef CONFIG_MODULE_UNLOAD
#define MODULE_VERMAGIC_MODULE_UNLOAD "mod_unload "
#else
#define MODULE_VERMAGIC_MODULE_UNLOAD ""
#endif
#ifdef CONFIG_MODVERSIONS
#define MODULE_VERMAGIC_MODVERSIONS "modversions "
#else
#define MODULE_VERMAGIC_MODVERSIONS ""
#endif
#ifndef MODULE_ARCH_VERMAGIC
#define MODULE_ARCH_VERMAGIC ""
#endif
#define VERMAGIC_STRING \
UTS_RELEASE " " \
MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT \
MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS \
MODULE_ARCH_VERMAGIC
VERMAGIC_STRING不仅包含内核版本号,还包含有内核使用的SMP与preempt, MODULE_UNLOAD, 架构等配置信息。模块在编译时,我们可以看到屏幕上会显示”MODPOST”。
<~/Documents/Demo/driver/debugfs> make
make -C ~/kernel/ SUBDIRS=~/Documents/Demo/driver/debugfs modules
make[1]: Entering directory '~/kernel'
CC [M] ~/Documents/Demo/driver/debugfs/my_debugfs.o
Building modules, stage 2.
MODPOST 1 modules
CC ~/Documents/Demo/driver/debugfs/my_debugfs.mod.o
LD [M] ~/Documents/Demo/driver/debugfs/my_debugfs.ko
make[1]: Leaving directory '~/kernel'
在此阶段, VERMAGIC_STRING会添加到模块的modinfo段。在内核源码目录下scripts\mod\modpost.c文件中可以看到模块后续处理部分的代码。模块编译生成后,通过modinfo my_debugfs.ko命令可以查看此模块的vermagic等信息。
<~/Documents/Demo/driver/debugfs> modinfo my_debugfs.ko
filename: ~/Documents/Demo/driver/debugfs/my_debugfs.ko
license: GPL
depends:
vermagic: 4.9.123 SMP preempt mod_unload aarch64
4.x 内核下的模块装载器里保存有内核的版本信息,在装载模块时,装载器会比较所保存的内核vermagic与此模块的modinfo段里保存的vermagic信息是否一致,两者一致时,模块才能被装载。
为了使两个版本一致:可以把 依赖源码中的include/linux/vermagic.h中的UTS_RELEASE修改成与目标机器的版本一致,这样,再次编译模块就可以了。
内核模块版本和内核版本不一致的处理方法
2, 发现版本号会追加git的版本号,还有个“+”
向linux内核版本号添加字符/为何有时会自动添加“+”号,根据这篇文章,一步一步试一下
第一步:去掉git的附加信息
先在menuconfig中找到
│ Symbol: LOCALVERSION [=] │
│ Type : string │
│ Prompt: Local version - append to kernel release │
│ Location: │
│ (1) -> General setup │
│ Defined at init/Kconfig:81 │
│ │
│ │
│ Symbol: LOCALVERSION_AUTO [=n] │
│ Type : boolean │
│ Prompt: Automatically append version information to the version string │
│ Location: │
│ (2) -> General setup │
│ Defined at init/Kconfig:91 │
│ Depends on: !COMPILE_TEST [=n] │
│
关掉LOCALVERSION_AUTO并留空LOCALVERSION,发现git版本确实是不见了,但是‘+’还是存在。
第二步:去掉“+”号
在scripts/setlocalversion文件中,找到以下语句:
# CONFIG_LOCALVERSION and LOCALVERSION (if set)
res="${res}${CONFIG_LOCALVERSION}${LOCALVERSION}"
# scm version string if not at a tagged commit
if test "$CONFIG_LOCALVERSION_AUTO" = "y"; then
# full scm version string
res="$res$(scm_version)"
else
# append a plus sign if the repository is not in a clean
# annotated or signed tagged state (as git describe only
# looks at signed or annotated tags - git tag -a/-s) and
# LOCALVERSION= is not specified
if test "${LOCALVERSION+set}" != "set"; then
scm=$(scm_version --short)
# res="$res${scm:++}" //××××××××××××××注释掉这句话××××××××××××
fi
fi
下面是注释前后的对比


问题解决。
Note:在网上还看到两种方法,写在下面:第一种:menuconfig 的时候不要勾选,直接搜MODVERSIONS

注意不要选图中那行
第二种:modprobe –force-vermagic helloworld.ko
这个大家可以自行尝试一下
本站的文章和资源来自互联网或者站长的原创,按照 CC BY -NC -SA 3.0 CN协议发布和共享,转载或引用本站文章应遵循相同协议。如果有侵犯版权的资源请尽快联系站长,我们会在24h内删除有争议的资源。欢迎大家多多交流,期待共同学习进步。