Chinaunix首页 | 论坛 | 博客
  • 博客访问: 574513
  • 博文数量: 192
  • 博客积分: 3780
  • 博客等级: 中校
  • 技术积分: 1487
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-26 10:11
文章存档

2012年(6)

2011年(160)

2010年(26)

分类: 嵌入式

2011-05-05 23:15:13

非开源的驱动程序如何绕过version magic的检查

最近在分析Linux内核模块与内核之间的版本耦合关系时,在开发kernel driver时,总是会遇到讨人厌的vermagic检查,只要目前在run的kernel版本跟driver编译时用的kernel版本不一致,就没办法insmod。

比如要将第三方的驱动”ntfs.ko”加入带android HoneyComb系统中。然后insmod。结果报错:

version magic ’2.6.36-android-x86 SMP preempt mod_unload modversion PENTIUMM’ should be ’2.6.36-android-epc1015+ SMP preempt mod_unload ATOM’。

version magic 是啥?Linux的是依靠内核模块构建时自动产生的“vermagic”标识检查是否与当前内核版本一致的,如果不一致则拒绝加载。除非在insmod/modprobe时指定参数强制忽略vermagic,但这样做的代价是如果使用错误版本的内核模块就可能导致内核崩溃。

由于没有源码,只有ko文件。于是只能按照提示的错误信息一步步配置kernel。首先把CONFIG_LOCALVERSION配置成-android-x86。然后把Processor type and features的ATOM关掉打开PENTIUMM。这些可以通过图形化界面来配置(make menuconfig),也可以直接修改.config文件,但前提你必须知道你所修改而产生的依赖项。个人建议用前者。

修改完后运行还是报错。

version magic ’2.6.36-android-x86 SMP preempt mod_unload modversion PENTIUMM’ should be ’2.6.36- android-x86+ SMP preempt mod_unload PENTIUMM’。

嗯?怎么有加号“+”,参数CONFIG_LOCALVERSION明明没有”+”.费了一番力气最终确定是由kernel下scripts/setlocalversion文件产生的。简单修改逻辑就ok了。

重新编译运行”+”问题解决了。但是会出现error:

version magic ’2.6.36-android-x86 SMP preempt mod_unload modversion PENTIUMM’ should be ’2.6.36- android-x86 SMP preempt mod_unload PENTIUMM’。

于是乎继续看modversion的相关信息,看了内核这部分的源代码(include/linux/vermagic.h)

#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

发现了两种不同截然的处理方式,由一个内核构建宏“CONFIG_MODVERSIONS”所控制。在它关闭的情况下,加载内核模块时,将对vermagic作全字符串的完整匹配,任何不一致均会阻止该内核模块的加载;而倘若这个宏被开启,则只有vermagic第一个空格之后的部分会参与匹配,也就是说形如“2.6.36-”这一段内核版本标识其实并不要求一致。事实上,当上述宏开启后,除了对vermagic后半段的匹配性检查外,内核还会进行额外的“内核接口指纹”检验,才最终决定是否允许加载该内核模块。

而若想知晓一个内核模块是否包含指纹信息,则需要用到modprobe的下面这个参数:

modprobe –dump-modversions

   因此,MODVERSIONS可以作为版本不配套时的后备选择(尤其对非开源的驱动程序),但不能依赖它作为兼容性的判定依据。

   初次写博客,难免会有各种不足,欢迎大家批评指正!

    原创文章,如需转载请注明【大雄的博客】:http://wangliping.net/owen/blog/ 

    本文地址:http://wangliping.net/owen/blog/2011/04/08/linux-version-magic

阅读(7279) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~