首页 文章

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

提问于
浏览
7

我刚刚制作了我的第一个驱动模块,跟随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

使用Makefile:

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"

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

3 回答

  • 0

    构建内核模块以及插入模块的内核应该是相同的版本 . 如果您不想处理这件事,可以使用以下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
    
  • 5

    尝试使用交叉编译 . 请查看下面的代码以获取make文件 . 请注意缩进,否则您最终可能会出现错误,例如missing separator. Stop

    obj-m += hello_.o # 此名称应该是.c文件的名称 . 我只是用你好的例子

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

    创建一个变量来保存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
    
  • -2

    您已正确完成所有操作,但未使用您编译的内核启动系统,因此第一步是您应该使用它启动 . 如果您正在使用Ubuntu,您可以在启动时按住shift按钮,系统会从您那里选择 linux-source-2.6.38 给您的系统编译内核列表,然后尝试构建您的模块并按照您的方式安装它,而不是赢得'找不到任何问题 . 祝好运 .

相关问题