内核与驱动的version magic匹配
i40e: version magic '4.4.58-svn-46674 SMP mod_unload modversions aarch64' should be '4.4.131.kylin.server.YUN SMP mod_unload aarch64'
一校招生在insmod ko的时候总是遇到此问题, 当时就给了答案就说 了 config 配置文件中 某某字段 不对--->内核 svn版本 不对
问题很好解决!
目前来看下这个version magic的内核实现
根据打印log信息看,是由version magic不匹配造成,找到信息打印点
static int check_modinfo(struct module *mod, struct load_info *info, int flags) { const char *modmagic = get_modinfo(info, "vermagic"); int err; if (flags & MODULE_INIT_IGNORE_VERMAGIC) modmagic = NULL; /* This is allowed: modprobe --force will invalidate it. */ if (!modmagic) { err = try_to_force_load(mod, "bad vermagic"); if (err) return err; } else if (!same_magic(modmagic, vermagic, info->index.vers)) { pr_err("%s: version magic '%s' should be '%s'\n", mod->name, modmagic, vermagic); return -ENOEXEC; } ------------------------------------------- }
当前module ko的modmagic 和 内核的vermagic 对比;
static const char vermagic[] = VERMAGIC_STRING; #define VERMAGIC_STRING \ UTS_RELEASE " " \ MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT \ MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS \ MODULE_ARCH_VERMAGIC \ MODULE_VERMAGIC_RETPOLINE #define MODULE_ARCH_VERMAGIC "aarch64" #define MODULE_VERMAGIC_MODULE_UNLOAD "mod_unload " #define MODULE_VERMAGIC_PREEMPT "preempt " #define MODULE_VERMAGIC_MODVERSIONS "modversions " #define MODULE_VERMAGIC_SMP "SMP "
VERMAGIC_STRING 中的UTS_RELEASE 指向啥呢??
这个是在Makefile中定义!
#define UTS_RELEASE \"$(KERNELRELEASE)\";)
# Read KERNELRELEASE from include/config/kernel.release (if it exists) KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null) KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)
可见KERNELRELEASE由include/config/kernel.release文件读取获得,此文件是编译生产的,在原始的内核代码中没看到,但是make 后就能看到!
Q2:在查看 same_magic 函数实现的时候发现有两个函数实现, 通过CONFIG_MODVERSIONS 宏来控制
- 如果宏没有开启,将对vermagic作全字符串的完整匹配,任何不一致均会阻止该内核模块的加载;
- 而倘若这个宏被开启,则只有vermagic第一个空格之后的部分会参与匹配
PS:在对比的时候发现 4.4.131.kylin.server.YUN SMP mod_unload aarch64 这段字符中没有看到 #define MODULE_VERMAGIC_PREEMPT "preempt "
也就是没有开启 CONFIG_PREEMPT
回归正题, 那 kernel.release是怎样生成的呢?
define filechk_kernel.release
echo (FROM_DPKG)" != y ]; then (srctree)/scripts/setlocalversion $(srctree);fi)
endef
# Store (new) KERNELRELEASE string in include/config/kernel.release
include/config/kernel.release: include/config/auto.conf FORCE
$(call filechk,kernel.release)
看Makefile 中 可以看到 依赖于setlocalversion 脚本
也就是 只需要执行 setlocalversion 这个脚本就知道 version magic 的生成了!!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战