在公司一个项目中,需要提供给合作方linux内核用于编译他们的内核模块,由于我们的内核是板一级移植,加入了一些重要的信息,这部分信息不能透漏给他人。根据之前的了解模块安装时会进行版本的检测。当编译驱动用的内核和加载驱动用的内核不一致时就会出现 version magic 'xxxxx' should be 'xxxxxx'的字样。首先想到的就是让内核版本变得一致。内核的版本信息都记录在include/linux/vermagic.h。
1 #include <generated/utsrelease.h>
2 #include <linux/module.h>
3
4 /* Simply sanity version stamp for modules. */
5 #ifdef CONFIG_SMP
6 #define MODULE_VERMAGIC_SMP "SMP "
7 #else
8 #define MODULE_VERMAGIC_SMP ""
9 #endif
10 #ifdef CONFIG_PREEMPT
11 #define MODULE_VERMAGIC_PREEMPT "preempt "
12 #else
13 #define MODULE_VERMAGIC_PREEMPT ""
14 #endif
15 #ifdef CONFIG_MODULE_UNLOAD
16 #define MODULE_VERMAGIC_MODULE_UNLOAD "mod_unload "
17 #else
18 #define MODULE_VERMAGIC_MODULE_UNLOAD ""
19 #endif
20 #ifdef CONFIG_MODVERSIONS
21 #define MODULE_VERMAGIC_MODVERSIONS "modversions "
22 #else
23 #define MODULE_VERMAGIC_MODVERSIONS ""
24 #endif
25 #ifndef MODULE_ARCH_VERMAGIC
26 #define MODULE_ARCH_VERMAGIC ""
27 #endif
28
29 #define VERMAGIC_STRING \
30 UTS_RELEASE " " \
31 MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT \
32 MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS \
33 MODULE_ARCH_VERMAGIC
编译模块时会产生一个*.mod.c文件。MODULE_INFO(vermagic, VERMAGIC_STRING);中的VERMAGIC_STRING用的就是29行中的宏定义。根据这个宏定义就清楚了应该保证哪一些信息一致。比如我将MODULE_ARCH_VERMAGIC改成我们的板子的信息,用这个纯净的内核编译的模块能被我用的内核加载。当然编译内核时要选对Machine和CPU相关的信息。我们的CPU是MIPS结构,可以在arch/mips/configs找一个config文件,用这个config文件配置内核,然后make menuconfig继续修改。
Linux 对可装载模块采取了两层验证:模块的 CRC 值校验和 vermagic 的检查。CONFIG_MODVERSIONS设为N可以关掉CRC校验。
其中preempt是便携的意思。