繁体   English   中英

insmod 错误:插入“./hello.ko”:-1 无效的模块格式”

[英]insmod error: inserting './hello.ko': -1 Invalid module format"

我刚刚制作了我的第一个驱动程序模块,即 LDD3 之后的 hello world 模块。 然而不幸的是遇到了这个错误:

insmod: error inserting './hello.ko': -1 Invalid module format.

我在 Ubuntu 11.04 和我的环境中这样做:

$ uname -r
2.6.38-8-generic

我得到这样的内核源代码:

sudo apt-cache search linux-source
linux-source - Linux kernel source with Ubuntu patches
linux-source-2.6.38 - Linux kernel source for version 2.6.38 with Ubuntu patches
$sudo apt-get install linux-source-2.6.38

我的 /usr/src:

$ls /usr/src/
linux-headers-2.6.38-8          linux-source-2.6.38          vboxguest-5.0.10
linux-headers-2.6.38-8-generic  linux-source-2.6.38.tar.bz2

然后我编译内核

$sudo cp /boot/config-2.6.38-8-generic ./.config
$sudo make menuconfig -- load the .config file
$make
$make modules

然后我编译我的内核模块

$make -C /usr/src/linux-source-2.6.38/linux-source-2.6.38 M=`pwd` modules

使用生成文件:

obj-m := hello.o

最后当我插入模块时:

$sudo insmod hello_world.ko
insmod: error inserting 'hello_world.ko': -1 Invalid module format

我在 dmesg 中发现了什么:

hello: disagrees about version of symbol module_layout

所以有什么问题?

我还注意到linux-header is -2.26.38-generic ,源代码版本是 -2.26.38,这是问题所在吗? 但我真的没有在网上找到linux-source-2.26.38-generic包。

状态更新:我发现文件 /lib/moduels/$(name -r)/build/Makefile 指示我正在运行的内核版本:

VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 38
EXTRAVERSION = .2

于是我下载了linux-2.6.38.2并编译,还是一样的错误。

我还发现 /boot/config-$(uname -r) 中有一行:

CONFIG_VERSION_SIGNATURE="Ubuntu 2.6.38-8.42-generic 2.6.38.2"

有谁知道这是什么意思? 我在正在构建的内核的配置文件中没有看到它。

从中构建内核模块的内核和要插入模块的内核应该是同一版本。 如果你不想处理这件事,你可以使用下面的 Makefile。

obj−m += hello−world.o

all:
 make −C /lib/modules/$(shell uname −r)/build M=$(PWD) modules
clean:
 make −C /lib/modules/$(shell uname −r)/build M=$(PWD) clean

现在您可以构建并尝试插入模块。

如果可能的话,我建议你在这条线之前成为 root

$sudo cp /boot/config-2.6.38-8-generic./.config

$su
#cp /boot/config-2.6.38-8-generic ./.config
#insmod hello_world.ko

或者,您也可以使用以下 make 文件

TARGET  := hello-world
WARN    := -W -Wall -Wstrict-prototypes -Wmissing-prototypes
INCLUDE := -isystem /lib/modules/`uname -r`/build/include
CFLAGS  := -O2 -DMODULE -D__KERNEL__ ${WARN} ${INCLUDE}
CC      := gcc-3.0

${TARGET}.o: ${TARGET}.c

.PHONY: clean

clean:
    rm -rf ${TARGET}.o

尝试使用交叉编译。 请查看下面的 make 文件代码。 请注意缩进,否则您可能会遇到诸如缺少分隔符之类的错误。 停止

obj-m += hello_.o #这个名字应该是你的.c 文件的名字。 例如,我只是使用 hello

我建议最好的方法是通过交叉编译

创建一个变量来保存 linux 内核目录所在的目录名称在我的示例中,将值“PATH_TO_LINUX_KERNEL_DIRECTORY”更改为真实路径值示例 ~/linux 您确实需要这样做,以便 make 文件知道在哪里可以找到 arm -linux-gnueabi- 没有这个,你可能会遇到问题 arm-linux-gnueabi-

KDIR := PATH_TO_LINUX_KERNEL_DIRECTORY

all:
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -C $(KDIR) M=$(shell pwd) modules

clean:
    make -C $(KDIR) M=$(shell pwd) clean

你做的一切都正确,但没有用你编译的内核引导你的系统,所以第一步是你应该用它引导。 如果您使用的是 Ubuntu,您可以在启动时按住 shift 按钮,然后您将获得系统中已编译内核的列表,从那里选择linux-source-2.6.38然后尝试构建您的模块并使用您的安装方式,比你不会发现任何问题。 祝你好运。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM