自作モジュールを組み込む方法についての質問

このQ&Aのポイント
  • 自作モジュールを組み込む方法について教えてください。
  • カーネルモジュールを組み込む際に発生するエラーについて解決方法を教えてください。
  • 自作モジュールがカーネルに組み込まれず、無効なモジュールフォーマットというエラーメッセージが表示される場合の対処方法を教えてください。
回答を見る
  • ベストアンサー

自作モジュールを組み込む

以下に何もしない何もしないカーネルモジュールを組み込みたいのですが、うまくいきません。 以下のソースをコンパイルします。 #define MODULE #include <linux/module.h> #include <linux/kernel.h> int init_module(void) { printk("my module installed\n"); return 0; } void cleanup_module(void) { printk("my module removed\n"); } そして、コンパイル $gcc -c sample.c #insmod sample.o とすると、 insmod: error inserting 'sample.o': -1 Invalid module format と怒られてしまいます。 モジュールフォーマットが無効と言われますが、ソースが間違っているのでしょうか。 カーネルのメッセージを調べると、 $dmesg ... No module found in object と、やっぱり組み込まれていません。 何がいけないのか、御知恵をくださいお願いします。 追記: 自分の環境を以下に記載させていただきます。 Linux localhost.localdomain 2.6.11-1.1369_FC4 #1 Thu Jun 2 22:55:56 EDT 2005 i686 athlon i386 GNU/Linux

質問者が選んだベストアンサー

  • ベストアンサー
  • Lean
  • ベストアンサー率72% (435/603)
回答No.1

>Linux localhost.localdomain 2.6.11-1.1369_FC4 #1 Thu Jun 2 22:55:56 EDT 2005 i686 athlon i386 GNU/Linux カーネル2.6系ですよね? 2.6では作成方法が変わっています。 下記のページを参照してみてください。 Linux Kernel 2.6.x プログラミングガイド http://uguisu.skr.jp/algo/device.html

damedamekun
質問者

お礼

解決しました。 本当にありがとうございました。

関連するQ&A

  • linux/module.h インクルードできない

    もう自力ではわからず、検索しても解決できなかったので、わかる方、力を貸してください。 まず環境は Ubuntu 12.10 をVirtualBoxで動かしています。 そして、以下のパッケージをインストールしました。 linux-source-3.5.0 linux-header-3.5.0-19-generic その後、以下のソースをコンパイルしようとしました。 1 #include <linux/module.h> /* module 作成には必須 */ 2 #include <linux/kernel.h> /* printk */ 3 4 MODULE_LICENSE( "GPL" ); 5 6 static char* msg = "module [message.o]"; 7 8 9 /* 10 * モジュールの初期処理 11 * insmod 時に呼ばれる 12 */ 13 int 14 init_module( void ) 15 { 16 printk( KERN_INFO "%s : loaded into kernel\n", msg ); 17 18 /* モジュール初期化に成功したので 0 を返す 19 0 以外の値を返せば初期化失敗とみなされモジュールは 20 カーネルには組み込まれない */ 21 return 0; 22 } 23 24 25 /* 26 * モジュールの解放処理 27 * モジュールの参照数が 0 であれば、rmmod 時に呼ばれる 28 */ 29 void 30 cleanup_module( void ) 31 { 32 printk( KERN_INFO "%s : removed from kernel\n", msg ); 33 } 34 35 36 /* End of message.c */ このソース自体はネットで公開されていたもののコピペです。 これを解説を読んで、いざコンパイルというときに、 linux/module.h そのようなファイルやディレクトリはありません 上のエラーが出ます。 でも、/usr/src/linux-source-3.5.0/include/linuxの中に、module.hは確かにありました。 あったのにもかかわらず、そのようなファイルやディレクトリがありませんというのは、いったいどのような原因が考えられるのでしょうか。 自力では解決できなかったので、わかるかた教えてください。

  • LKMの分割コンパイルについて

    こんばんは、自分は今LKMの分割コンパイルに挑戦しています。 以下のようなファイルを作成して、モジュールを作ってみました。 [Makefile] obj-m := message.o message-objs := message.o sample_func.o KDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) all: $(MAKE) -C $(KDIR) M=$(PWD) modules clean: rm -f *.o *.ko *.symvers *~ *.mod.c [message.c] #include <linux/module.h> #include <linux/kernel.h> #include "sample_func.h" static char *msg = "[message.o]:"; static int message_module(void) { printk(KERN_INFO "%s loaded\n",msg); printk(KERN_INFO "%s %d\n", msg, sample_add(2,3)); return 0; } static void message_remove(void) { printk(KERN_INFO "%s removed\n", msg); } module_init(message_module); module_exit(message_remove); [sample_func.c] #include "sample_func.h" static int inner_add(int,int); int sample_add(int a, int b) { return inner_add(a,b); } static int inner_add(int a, int b) { return a+b; } [sample_func.h] int sample_add(int,int); コンパイルは正しく通るようなのですが、/var/log/messages に何も出力がありません。 (KERN_INFOを指定しているので/var/log/messagesに出力されると思っているのですが。。。) lsmodで確認したところ、モジュールはカーネル内に正常に組み込まれているようでした。 どなたか解決方法をご存知の方教えていただけないでしょうか。 宜しくお願いします。

  • モジュールんの有効(?)に関する質問

    ディストリビューションはTurbo Linuxでカーネルは2.6です。 モジュールを以下のコマンドでコンパイルでコンパイルしようとした所 make -C ~/linux-2.6.5/linux-2.6.5 M='pwd' modules The present kernel configuration has modules disabled. Type 'make config' and enable loadable module support. Then build a kernel with module support enabled. というエラーメッセージ(?)がでました。 意味としては、「'make config'変更してをモジュールを有効にしてください」 という意味だと思いますが、何処を変更すれば良いのでしょうか

  • [Debian]LKMの作成について

    こんにちは LKMの作成で躓いているのでお力をお貸しください OS: Debian4.0 r6 kernel: 2.6.18-6-686 GCC: 4.1.2 [ソース: message.c] #include <linux/module.h> #include <kernel.h> #include <linux/init.h> static int __init init_module(void) { printk(KERN_INFO "loaded\n"); return 0; } static void __exit cleanup_module(void) { printk(KERN_INFO "removed\n"); } module_init(init_module); module_exit(cleanup_module); [コンパイル結果] make -C /lib/modules/2.6.18-6-686/build M=/home/user/lkm modules make[1]: ディレクトリ `/usr/src/linux-headers-2.6.18-6-686' に入ります CC [M] /home/user/lkm/message.o /home/user/lkm/message.c:6: error: static declaration of 'init_module' follows non-static declaration include/linux/module.h:65: error: previous declaration of 'init_module' was here /home/user/lkm/message.c:12: error: static declaration of 'cleanup_module' follows non-static declaration include/linux/module.h:66: error: previous declaration of 'cleanup_module' was here /home/user/lkm/message.c:16: error: redefinition of 'init_module' /home/user/lkm/message.c:6: error: previous definition of 'init_module' was here /home/user/lkm/message.c:17: error: redefinition of 'cleanup_module' /home/user/lkm/message.c:12: error: previous definition of 'cleanup_module' was here make[2]: *** [/home/user/lkm/message.o] エラー 1 make[1]: *** [_module_/home/user/lkm] エラー 2 make[1]: ディレクトリ `/usr/src/linux-headers-2.6.18-6-686' から出ます make: *** [default] エラー 2 初歩的な質問で申し訳ないですが エラー冒頭のstatic declaration of ...というエラーが直せなくて困っております。 どなたかお分かりになる方、お力をお貸しください 宜しくお願いします。

  • LKMを用いたカーネル2.6でのシステムコールのフック

    度々すみません。 LKMを使ったシステムコールのフックに挑戦しているのですがうまくいかずに悩んでいます。 お力を貸していただけたら嬉しいです。 ディストリビューション: Debian 4.0r4 カーネル: 2.6.24 以前2.6.18のカーネルを使っていたのですが、使用するカーネルのバージョンを上げました。 開発前にやったことをすべて書いておきます。 ・ linux-source-2.6.24_2.6.24-6~etchnhalf.7_all.deb ・ linux-headers-2.6.24-etchnhalf.1-686_2.6.24-6~etchnhalf.7_i386.deb ・ linux-kbuild-2.6.24-1~etchnhalf.1_i386.deb をダウンロードし、dpkg -i *.deb で展開。 /usr/src/linux-source-2.6.24/arch/x86/kernel/i386_ksyms_32.c の末尾に以下の2行を追加 extern void *sys_call_table[]; EXPORT_SYMBOL(sys_call_table); 変更後以下の手順でカーネルコンパイル cp /boot/config-2.6.18-6-686 .config make menuconfig (Enterを押しっぱなしにして設定終了) make-kpkg --initrd kernel_image dpkg -i (kernel_image).deb 書いたプログラムは以下です。 #include <linux/module.h> #include <linux/init.h> #include <linux/syscalls.h> #include <linux/utsname.h> #include <asm-x86/unistd_32.h> MODULE_LICENSE("GPL"); extern void *sys_call_table[]; static char *msg = "[message.o]:"; asmlinkage int (*orig_open)(const char *pathname, int flags); asmlinkage static int hook_open(const char *pathname, int flags) { printk(KERN_INFO "hook_open(\"%s\", %d)\n", pathname, flags); return orig_open(pathname, flags); } static int message_module(void) { printk(KERN_INFO "%s loaded\n",msg); printk(KERN_INFO "%s hook_init\n", msg); orig_open = sys_call_table[__NR_open]; sys_call_table[__NR_open] = hook_open; return 0; } static void message_remove(void) { printk(KERN_INFO "%s removed\n", msg); printk(KERN_INFO "%s hook_exit\n", msg); sys_call_table[__NR_open] = orig_open; } module_init(message_module); module_exit(message_remove); コンパイルすると以下のようなエラーが出ます。 user@debian:~/lkm/message$ make make -C /lib/modules/2.6.24/build M=/home/user/lkm/message modules make[1]: ディレクトリ `/usr/src/linux-source-2.6.24' に入ります Building modules, stage 2. MODPOST 1 modules WARNING: "sys_call_table" [/home/user/lkm/message/message.ko] undefined! make[1]: ディレクトリ `/usr/src/linux-source-2.6.24' から出ます 長文で申し訳ありませんが、お力をお貸しください。 宜しくお願いします。

  • dlopenで目的の*.soファイルをロードできません

    以下C++のテストソース2ファイルをコンパイルし実行したのですが、libtest.soをロードすることが出来ません。OSはRed Hat Linux EL4.0WS、カーネルは2.6.9-5です。原因と思しき点がお分かりの方がいれば、教えて頂けますでしょうか。 ********** ソースファイル1(libtest.cpp) ********** #include <stdio.h> #include <stdlib.h> extern "C" {void printTest();} void printTest(){ printf(" *** SUCCESS!! *** Java - Native Interface test at INOAC\n"); } ********** ソースファイル2(test.cpp) ********** #include <dlfcn.h> #include <stdio.h> #include <stdlib.h> static void (*testFunc)(); int main(){ void *library; const char * error; library = dlopen("libtest.so",RTLD_LAZY); if(library==NULL){ printf("Could not open libtest.so\n"); exit(1); } dlerror(); testFunc = (void (*)())dlsym(library,"printTest"); error = dlerror(); if(error){ printf("Could not find the function printTest\n"); exit(1); } printf("Test from C;\n"); (*testFunc)(); dlclose(library); return 0; } ********** 実行方法 ********** pgCC -fPIC -shared libtest.cpp -o libtest.so pgCC -ldl test.cpp -o test.exe setenv LD_LIBRARY_PATH "." ./test.exe

  • 静的ライブラリについて教えて下さい

    静的ライブラリについて教えて下さい。作成方法は大体わかったのですが、使い方と利用シーンがわかりません。例えば、 -main.c- #include <stdio.h> #include "abc.h" int main(){ a(); b(); c(); } -a.c- #include <stdio.h> void a(void){ printf("a\n"); } -b.c- #include <stdio.h> void b(void){ printf("b\n"); } -c.c- #include <stdio.h> void c(void){ printf("c\n"); } -abc.h- void a(void); void b(void); void c(void); というファイルを作成した上で以下のようにコンパイルしました。 gcc -c a.c gcc -c b.c gcc -c c.c これで、a.o, b.o, c.oというオブジェクトファイルが出来ました。 次にar rcs static a.o b.o c.oとコマンドを打ったところ、問題なくstaticという静的ライブラリと思われるファイルが出来ました。で、そもそもですがこの使い方がわかりません。main.cをコンパイルする際に使うのでしょうか?そもそも上で作成した静的ライブラリにはmain.oも含めるべきものでしょうか?初歩的な質問ですみません。宜しくお願いします。

  • 多重定義が起きている?--lnk2005エラー:VC++

    今つまずいている問題は、VC++2008環境下で、以下のような構造になっているプログラムにおいて、多重定義?されているのでコンパイルが通らないというものです。 ソースコードを載せることは大きすぎてできないので、問題となる部分の記述のみ抽出して書きます。 -------define.h---------- ・・・・(module.h内の関数に使われる型の定義など) --------------------------- -------module.h---------- #include "define.h" void mod_1(void){・・・} void mod_2(void){・・・} --------------------------- このように、2つのヘッダーファイルがあり、define.hをインクルードしてmodule.hを使うという構造です。 (一般的ではないようですが、module.h内にmod_1やmod_2の実体を書き込んでいます。) その中で、以下のようなcppソースファイルがあります。 -------Main.cpp---------- #include "module.h"   (他のMain.cpp内の関数の都合上、Main.cppでもmodule.hをインクルードしています。関係あるかもしれないと思い書きました。) int main(){ M(); N(); } ------------------------ -------M.cpp---------- #include "module.h" void M(void){ mod_1(); mod_2(); } ---------------------- -------N.cpp---------- #include "module.h" void N(void){ mod_1(); mod_2(); } ---------------------- とすると、コンパイルの結果は次のようになります。 1>N.obj : error LNK2005: "void __cdecl mod_1(void)" (?mod_1@@YAXXZ) は既に M.obj で定義されています。 1>N.obj : error LNK2005: "void __cdecl mod_2(void)" (?mod_2@@YAXXZ) は既に M.obj で定義されています。 多重定義や多重インクルードは起こしていないと思っていますが、M.cppとN.cpp内の定義が衝突する理由がわかりません。どなたか理由が思いつく方、教えていただけたら幸いです。お願いいたします!! ◆◆◆   ◆◆◆   ◆◆◆   ◆◆◆   ◆◆◆ ちなみに、たとえばMやNとまったく同じ「A.cpp」を作り、このように書いたとします。 -------A.cpp---------- #include "module.h" void A(void){ mod_1(); mod_2(); } ---------------------- そしてmain関数の中に、MやNと同様に『A();』を付け加えたとします。 すると、実行結果はこのようになります。 1>M.obj : error LNK2005: "void __cdecl mod_1(void)" (?mod_1@@YAXXZ) は既に A.obj で定義されています。 1>M.obj : error LNK2005: "void __cdecl mod_2(void)" (?mod_2@@YAXXZ) は既に A.obj で定義されています。 1>N.obj : error LNK2005: "void __cdecl mod_1(void)" (?mod_1@@YAXXZ) は既に A.obj で定義されています。 1>N.obj : error LNK2005: "void __cdecl mod_2(void)" (?mod_2@@YAXXZ) は既に A.obj で定義されています。 VC++はファイル名のアルファベット順にコンパイルするようですが、どちらにせよmain関数内で呼び出されていること以外何の関わりも無いはずのA、M、Nの中での出来事が、衝突する理由が、調べども思い当たりません。 お願いいたします。

  • Linuxカーネル sampleプログラムについて

    現在、linuxのsysfsについて勉強中です。 kernel/samples/kobjectの下にある、 kobject-example.c をカーネルにbuilt-inさせ、 ビルドを行い、uImageを作成しました。 具体的な手順は以下のとおりです。 make ARCH=arm CROSS_COMPILE=../prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- menuconfig Kernel hacking ---> [*] Sample kernel code ---> <M> Build kobject examples -- loadable modules only make ARCH=arm CROSS_COMPILE=../prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi- uImage サンプルソースの説明に * This module shows how to create a simple subdirectory in sysfs called * /sys/kernel/kobject-example In that directory, 3 files are created: * "foo", "baz", and "bar". If an integer is written to these files, it とあったので、 カーネルを起動させ、/sys/kernelの下をみにいったのですが、 存在していませんでした。 そこで、kobject-example.cをkernel/drivers/miscの下に移動させ、 カーネルモジュール(kobject-example.ko)を作成し、insmodしたところ、 下記のようにちゃんとフォルダkobject_exampleが生成されていました。 /sys/kernel # /sys/kernel # ls -l kobject_example/ total 0 -rw-rw-rw- 1 0 0 4096 Jan 1 00:00 bar -rw-rw-rw- 1 0 0 4096 Jan 1 00:02 baz -rw-rw-rw- 1 0 0 4096 Jan 1 00:00 foo ここで質問です。 kernel/samplesの下におかれているサンプルソースは、 このフォルダ直下においていては動作テストをすることができないのでしょうか? 上記のように、わざわざkernel/drivers/miscの下などに移動させて、モジュールの 作成を行わないといけないのでしょうか? ご教示のほどよろしくお願いします。

  • Linux C言語開発 インクルードについて

    C言語開発初心者です。 LinuxでC言語開発をするにあたり、どのディストリビューションにしても インクルードしたいヘッダファイルが既定の場所には無く別の場所にカーネルのバージョンごとに保存されているようなのです。 このままコンパイルを試みるとインクルードファイルが存在しませんとエラーが返ります。 既定のヘッダファイルの保存場所にはC言語開発に必要なヘッダファイルが存在しませんので、この問題を皆さんはどのように解決しておりますか?どなたかご教授お願いいたします。 C言語でincludeする場所は<>でくくった場合 /usr/include/ 以下を参照する設定になっていると思うのですが、 例えばmodule.h やinit.h などの開発用ヘッダファイル?を探してみると /usr/include/linux/ には存在せず、 find / -name module.h と入力して検索してみると /usr/src/kernels/2.6.32-131.21.1.el6.i686/include/linux/module.h と別な場所にあります。 ネットであれやこれや調べてみても コンパイル時にincludeの参照先を指定する方法はあるようなのですが、 コンパイルする度にいちいち指定するのは面倒だと思います。(gcc -I) かといって開発しているカレントディレクトリにヘッダファイルをコピーしても includeするヘッダファイルが別のヘッダファイルを参照することもあるようなので、 あまり現実的ではないようです。 一番安全な方法としてincludeする参照先が環境変数か何かで追加及び変更するのではないかと思います。 試してみましたがenvコマンドで表示されるOSの環境変数とは別のもののようなのです。 環境変数 C_INCLUDE_PATH とはどのようにして変更・追加するのでしょう? また、上記の方法以外で良い方法がございましたらそれでもかまいません。 よろしくお願いいたします。 開発環境 ・OS centos6 ・以下のパッケージはインストール済み kernel-headers-2.6.32-131.21.1.el6.i686 kernel-devel-2.6.32-131.21.1.el6.i686 make-3.81-19.el6.i686 gcc-4.4.5-6.el6.i686 ・GUI開発環境 netbeans ・uname -r 実行結果 2.6.32-131.21.1.el6.i686