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"
これはどういう意味ですか?構築中のカーネルの設定ファイルには表示されません。
カーネルモジュールをビルドするカーネルとモジュールを挿入するカーネルは、同じバージョンである必要があります。このことを処理したくない場合は、次の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
クロスコンパイルを使用してみてください。メイクファイルについては、以下のコードをご覧ください。インデントに注意してください。そうしないと、 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