我正在尝试为 构建我自己的模块usbhid.ko,但是在我编译之后,我无法加载该模块。dmesg说no symbol version for module_layout。我想知道是什么问题?我已经使用了 Ubuntu 提供的内核源代码,并且我还确保内核版本相同。
小智 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.
Run Code Online (Sandbox Code Playgroud)
2)另一种选择是告诉愚蠢的 modprobe 忽略所有这些废话,无论如何只加载你的模块:
modprobe -f <module>
Run Code Online (Sandbox Code Playgroud)
我倾向于支持选项 2 :)
小智 18
安装与您的内核相对应的linux-headers和linux-source软件包。例如对于内核,3.2.0-27-generic-pae您需要:
linux-headers-3.2.0-27-generic-pae 和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)下面的每个以匹配已安装软件包中的版本字符串。
cd /usr/src/linux-source-$Version 并将 .tar.bz2 存档解压到位,然后 cd 进入解压目录 - 我猜你已经这样做了cp /boot/config-$(uname -r) .config 进入内核源目录cp /usr/src/linux-headers-$(uname -r)/Module.symvers . 进入内核源目录完成后,在内核源目录中,执行以下操作:
make preparemake scriptsmake M=drivers/usb/serial- 更改后的路径M=以满足您的需求不幸的是,我不知道如何在保持Module.symvers不变的情况下构建特定的模块。make drivers/usb/serial/option.ko例如,这样做会杀死Module.symvers文件,最终会出现原始问题。使用M=参数并不会杀死它,但是您必须在指定路径中构建所有模块 - 我还没有找到解决方法。
在运行之前,您必须使用完全相同的内核配置make prepare。另外,如果您要在树外构建它,则需要根据与当前运行的内核(或者如果您在编译时未运行它的话,则为目标内核)匹配的完全相同的内核头来构建它。
| 归档时间: |
|
| 查看次数: |
64086 次 |
| 最近记录: |