尝试加载usbhid.ko时,“ module_layout没有符号版本”


27

我正在尝试为构建自己的模块usbhid.ko,但是在编译后,无法加载该模块。dmesgno symbol version for module_layout。我想知道是什么问题?我已经使用过Ubuntu提供的内核源代码,并且还要确保内核版本相同。

Answers:


22

具体来说,问题是在构建模块时,内核源代码树可能缺少Modules.symvers文件。当您构建模块时,kbuild系统实际上会警告您。如果缺少Modules.symvers,您将看到:

警告:缺少符号版本转储/usr/src/linux-2.6.34-12/Modules.symvers;模块将没有依赖关系和modversions。

如果您的内核已CONFIG_MODVERSIONS启用,则在构建驱动程序的modpost阶段,它将使用-m选项运行scripts / mod / modpost。如果您勇敢地看一下scripts / mod / modpost.c源代码,您会看到-m选项添加了vmlinux中的_module_layout_符号,但是,如果您的内核中没有Modules.symvers,您将无法获得该符号的CRC值,并最终收到此错误消息。

因此,有两种解决方法。

1)运行正在运行的内核的完整版本以生成Modules.symvers,然后重新构建模块。[http://www.mjmwired.net/kernel/Documentation/kbuild/modules.txt][1]

51  === 2. How to Build External Modules
52  
53  To build external modules, you must have a prebuilt kernel available
54  that contains the configuration and header files used in the build.
55  Also, the kernel must have been built with modules enabled. If you are
56  using a distribution kernel, there will be a package for the kernel you
57  are running provided by your distribution.
58  
59  An alternative is to use the "make" target "modules_prepare." This will
60  make sure the kernel contains the information required. The target
61  exists solely as a simple way to prepare a kernel source tree for
62  building external modules.
63  
64  NOTE: "modules_prepare" will not build Module.symvers even if
65  CONFIG_MODVERSIONS is set; therefore, a full kernel build needs to be
66  executed to make module versioning work.

2)另一个选择是让愚蠢的modprobe忽略所有的废话,反正只是加载模块:

modprobe -f <module>

我倾向于选择选项2 :)


1
+1表示“告诉愚蠢的modprobe只忽略所有废话,无论如何都只是加载模块”。
HayriUğurKoltuk

我尝试了2次,发现该模块在引导时不会自动加载。引导时有没有办法使用-f?
贾斯汀·张

17

同时安装与您的内核相对应的linux-headerslinux-source软件包。例如,对于内核,3.2.0-27-generic-pae您需要:

  1. linux-headers-3.2.0-27-generic-pae
  2. linux-source-3.2.0-27-generic-pae

如果上述软件包的版本与您正在运行的内核版本不匹配,那么您需要$(uname -r)用上面安装的内核软件包中的版本字符串替换。
对于上述示例,软件包版本为3.2.0-27-generic-pae。当您运行uname -r并且其输出有所不同时,则3.2.0-27-generic-pae需要替换$(uname -r)下面的每个内容以匹配已安装软件包中的版本字符串。

  1. cd /usr/src/linux-source-$Version 并将.tar.bz2存档解压缩到位,然后将cd放入提取的目录中-我想您已经做到了
  2. cp /boot/config-$(uname -r) .config 进入内核源目录
  3. cp /usr/src/linux-headers-$(uname -r)/Module.symvers . 进入内核源目录

完成之后,在内核源目录中执行以下操作:

  1. make prepare
  2. make scripts
  3. make M=drivers/usb/serial- M=根据需要改变路径

不幸的是,我不知道如何构建特定的模块Module.symversmake drivers/usb/serial/option.ko例如,这样做会杀死Module.symvers文件,而您最终会遇到原来的问题。使用该M=参数不会杀死它,但是您必须在指定路径中构建所有模块-而且我还没有找到解决它的方法。


这似乎做的事情最好的办法,如果你正在编译在同一棵树版本的模块...
特维诺

2

在运行之前,必须使用完全相同的内核配置make prepare。另外,如果要在树外进行构建,则需要针对与当前运行的内核(如果在编译时未运行,则为目标)完全相同的内核头文件进行构建。


“ make mrproper”,“ cp / boot / config-$(uname -r).config”,“ make oldconfig”,“ make prepare”,“ make scripts”我已经使用这些指令来准备编译。我想知道是否复制了正确的配置文件?似乎只有一个配置与/ boot /中的内核版本匹配。遗憾的格式为评论框没有格式....
SpecC

是的,这似乎是正确的。您在哪里调用构建,如果不是从顶级目录调用,您要传递什么SUBDIRS值?
Daniel T Chen

谢谢回复。当我尝试构建usbhid.ko时。我使用了以下命令“ make modules SUBDIRS = drivers / hid / usbhid”
SpecC 2010年

当我运行命令“ make modules SUBDIRS = drivers / hid / usbhid”时,出现以下警告“警告:符号版本转储/usr/src/linux-source-2.6.31/Module.symvers丢失;模块将具有没有依赖项和modversions。“
SpecC 2010年

@SpecC在调查问题时,请按照要执行的步骤更新原始问题。然后Dan将更新他的答案,并且您将一直更新直到找到答案为止,而不是一连串的评论最终被掩盖
Jorge Castro
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.