第一个驱动helloworld module加载i…

来源:互联网 发布:联合国工作 知乎 编辑:程序博客网 时间:2024/06/06 16:34

在使用命令ismod helloworld.ko加载编译成功的模块helloworld.ko时出现错误  insmod:error inserting 'helloworld.ko': -1 Invalid moduleformat

一般出错信息被记录在文件/var/log/messages中
[root@hailiang linux-2.6.15.5]# cat /var/log/messages|tail 

 May  8 16:41:45 hailiang kernel: helloworld:version magic '2.6.27.5-117.fc10.i686 SMP mod_unload modversions 686 4KSTACKS ' should be'2.6.27.5-117.fc10.i686 SMP mod_unload 686 4KSTACKS '

通过命令看一下模块的相关信息

[root@hailiang tmp]# modinfohelloworld.ko
filename:      helloworld.ko
alias:         a simplest module
description:   A simple helloworld module
author:        zhanghailiang
depends:       
vermagic:      2.6.27.5-117.fc10.i686 SMP mod_unload modversions 6864KSTACKS  

 内核无法加载模块的原因是因为记载版本号的字符串和当前正在运行的内核模块的不一样,这个版本印戳作为一个静态的字符串存在于内核模块中,叫vermagic,可以从编译模块中间生成的文件helloworld.moc.h中

#include<linux/module.h>
#include<linux/vermagic.h>
#include<linux/compiler.h>

MODULE_INFO(vermagic,VERMAGIC_STRING);找到这个符号,

打开文件/usr/src/kernels/2.6.27.5-117.fc10.i686/include/linux/vermagic.h (注意在fedroa10 中源码树是在/usr/src/下)

#include<linux/utsrelease.h>
#include<linux/module.h>


#ifdef CONFIG_SMP
#define MODULE_VERMAGIC_SMP "SMP "
#else
#define MODULE_VERMAGIC_SMP ""
#endif
。。。。。。。。。。。。。。。。。。。
#ifdef CONFIG_MODVERSIONS
#defineMODULE_VERMAGIC_MO

DVERSIONS "modversions "
#else
#define MODULE_VERMAGIC_MODVERSIONS ""
#endif
#ifndef MODULE_ARCH_VERMAGIC
#define MODULE_ARCH_VERMAGIC ""
#endif

#defineVERMAGIC_STRING                                                /
       UTS_RELEASE ""                                                /
       MODULE_VERMAGIC_SMPMODULE_VERMAGIC_PREEMPT                    /
       MODULE_VERMAGIC_MODULE_UNLOADMODULE_VERMAGIC_MODVERSIONS      /
       MODULE_ARCH_VERMAGIC

从这里看出vermagic中多出来的字符modversions是由于编译内核时选上了“”选项的原因,(其实这是因为在编译helloworld模块前,自己曾试图重新编译内核所致:cd /usr/src/kernel..

[root@hailiang2.6.27.5-117.fc10.i686]# make menuconfig
scripts/kconfig/mconf arch/x86/Kconfig
#
# configuration written to .config
#


*** End of Linux kernelconfiguration.
*** Execute 'make' to build the kernel or try 'makehelp'.

[root@hailiang2.6.27.5-117.fc10.i686]# make
scripts/kconfig/conf -s arch/x86/Kconfig
  CHK    include/linux/version.h
 CHK    include/linux/utsrelease.h
make[1]: *** No rule to make target`missing-syscalls'.  Stop.
make: *** [prepare0] Error 2

 
)见下图

 

然后再重新编译helloworld.ko模块,然后再加载helloworld成功。

  一点别的:在网上对这个问题有另一个解决方法就是modprobe --force-vermagichelloworld强制加载内核,在这里我试了一下问题还是原来invalid moduleformat

 注意:(1)modprobe  模块名(不要带后缀.ko)  注:挂载一个模块

(2)在这里直接modprobe ./helloworld 错误 
FATAL: Module helloworld notfound.
这是因为

使用man modprobe看

DESCRIPTION

     modprobeintelligently adds or removes a module from the Linux kernel: notethat  for  conve-
      nience, there is no difference between _ and - in modulenames.  modprobelooks in the module
      directory /lib/modules/‘uname -r‘ for all the  modules and  other files,
  except for  the
      optional  /etc/modprobe.conf configuration  file and  /etc/modprobe.d directory  (see mod-
      probe.conf(5)). modprobe will also use module options specified onthe kernel command line i
modprobe会自动在/lib/modules/'uname-r'下寻找模块加载,将helloworld.ko拷到/lib/modules 下然后再执命令 modprobe helloworld发现还是找不到,从man modprobe

  modprobe expects  an up-to-date  modules.dep  file, asgenerated by depmod (seedepmod(8))

看出还需要依赖命令:depmod生成的module.dep 使用这个命令后在modprobe helloworld成功 

0 0