web-dev-qa-db-ja.com

insmodエラー: './hello.ko'の挿入:-1無効なモジュール形式」

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"

これはどういう意味ですか?構築中のカーネルの設定ファイルには表示されません。

10
roMoon

カーネルモジュールをビルドするカーネルとモジュールを挿入するカーネルは、同じバージョンである必要があります。このことを処理したくない場合は、次の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

これで、モジュールをビルドして挿入することができます。

この行の前に、可能であればルートになることをお勧めします

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

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

または、次のメイクファイルを使用することもできます

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
7
Punit Vara

クロスコンパイルを使用してみてください。メイクファイルについては、以下のコードをご覧ください。インデントに注意してください。そうしないと、 missing separator。Stop などのエラーが発生する可能性があります

obj-m += hello_.o #この名前は、.cファイルの名前にする必要があります。たとえば、こんにちはを使用しています

最善のアプローチはクロスコンパイルによることをお勧めします

Linuxカーネルディレクトリが存在するディレクトリ名を保持する変数を作成します。私の例では、値「PATH_TO_LINUX_KERNEL_DIRECTORY」を実際のパス値に変更します。例〜/ linux -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
0
rocksyne