Linux Kernel module isnmod 时的检查以及MODVERSIONS

来源:互联网 发布:windows计划任务命令 编辑:程序博客网 时间:2024/05/16 11:39

作者:Sam(甄峰) sam_code@hotmail.com

 

Modues是Linux Kernel中很灵活的一种机制。利用这种机制,可以在Kernel启动后添加新的功能。

 

Modules在insmod 到Kernel中时,需要判断它与Kenrel是否匹配。

2.4 Kernel时代,内核符号的后缀(即符号校验字符串)与KernelVersion有关,linux/modversions.h文件中包含了此校验字符串。所以当模块包含linux/modversions.h文件后,编译时,模块里使用的内核符号实质上成为带有校验后缀的内核符号。在加载模块时,如果模块使用的内核符号的校验字符串与当前运行内核所导出的相应的内核符号的校验字符串不一致,即当前内核空间并不存在模块所使用的内核符号,就会出现“Invalidmodule format ”的错误。

 

Linux内核所采用的在内核符号添加校验字符串来验证模块的版本与内核的版本是否匹配的方法繁且会浪费内核空间,而且随着SMP、PREEMPT等机制在2.6内核的引入和完善,模块运行时对内核的依赖不再仅仅取决于内核版本,还取决于内核的配置,此时内核符号的校验码是否一致不能成为判断模块可否被加载的充分条件。

 

Linux 2.6下,linux/vermagic.h头文件中定义了Version MagicString――VERMAGIC_STRING,VERMAGIC_STRING不仅包含内核版本号,还包含内核编译所使用的gcc版本、SMP与PREEMPT等配置信息。在内核源码目录下scripts/mod/modpost.c文件中可以看到模块后续处理部分的代码。就是在这个阶段,VERMAGIC_STRING会被添加到模块的modinfo段中,模块编译生成后,通过“modinfoxxx.ko”命令可以查看此模块的vermagic等信息。2.6内核下的模块装载器里保存有内核的版本信息,在装载模块时,装载器会比较所保存的内核vermagic与此模块的modinfo段里保存的vermagic信息是否一致,两者一致时,模块才能被装载。

 

以下作详细讲解:

LinuxKernel支持多架构(如:ARM,MIPS,SH4等),所以modules也有其针对的架构平台。所以需要检测Kernel与Modules所支持架构是否一致。

其次,Linux Modules也有其针对的Linux Kernel Version. 因为不同VersionKernel所提供的内核符号表不尽相同。

另外,2.6 Kernel中有很多关键配置,需要modules与Kernel保持一致。

 

在insmod时出现的类似

Error inserting  `xxx.ko`: -1 Invalid moduleformat的错误,(具体信息在/var/log/messages)通常就是由以上3个原因导致的。

这时候,只需要以目标kernel 目录为KDIR,重现编译即可顺利insmod.

 

 

insmod modules时,会依次检测这三项。

在Modules ELF文件中,会存储Version Magic String信息如下:

vermagic=2.6.18-7.1 SMP mod_unload MIPS32_R1 32BIT gcc-4.2

可以用以下命令查看之:

#modinfo xxx.ko

如果此信息与Kernel中vermagic.o中信息不符合。则无法insmod.

Kernel Version 在Kernel Source include/linux/version.h:

#define LINUX_VERSION_CODE 132636

132636 即为:2061C==>2.6.1C==>2.6.28

 

平台信息在:

include/linux/compile.h

include/linux/vermagic.h

中。

 

kernel/module.c中:

same_magic(modmagic, vermagic, versindex))

这里判断modules与Kernel的VerMagic是否一致。

Kernel VerMagic其实就是:vermagic.h中的VERMAGIC_STRING 。

 

 

另:编译Kernel 时可以选点是否支持Module。

make menuconfig:

Enable loadable module support

 

 

MODVERSIONS简介:

#make menuconfig

Enable loadable module support ---> Module versioning support

可以配置为y  CONFIG_MODVERSIONS

Usually, you have to use modules compiled with yourkernel.
         Saying Y here makes it sometimes possible to use modules
         compiled for different kernels, by adding enough information
         to the modules to (hopefully) spot any changes which would
         make them incompatible with the kernel you are running.

 

这里说明如果设置了MODVERSION. 则在某种情况下不会严格的判断是当前Kerneltree所编译出的modules.