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

このQ&Aのポイント
  • LKMの分割コンパイルに挑戦中です。コンパイルは通るが出力されない現象に悩んでいます。
  • /var/log/messagesに何も出力されず、lsmodではモジュールが正常に組み込まれていることが確認できました。
  • 解決方法をご存知の方はいらっしゃいませんか?
回答を見る
  • ベストアンサー

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で確認したところ、モジュールはカーネル内に正常に組み込まれているようでした。 どなたか解決方法をご存知の方教えていただけないでしょうか。 宜しくお願いします。

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

  • ベストアンサー
noname#136147
noname#136147
回答No.1

こんにちは。 前回と同じ回答になってしまいますが、 もう少し名前の付け方を工夫された方が良いかと。 obj-m <= lsmodするモジュール名を指定 (モジュール名)-objs <= モジュールを構成するオブジェクトファイル(ソース)を指定 のような感じになるので、 > obj-m := message.o > message-objs := message.o sample_func.o だと、message.ko は messege.c のみから構成されて sample_func.c がリンクされていない状況だと思います。 作りたいモジュールを message.ko だとするならば、 obj-m := message.o message-objs := message-main.o sample_func.o のようにして、message-main.c と sample_func.c を作るのが良いかと。 逆に、カーネルモジュールの名前を変更して、 obj-m := msg.o msg-objs := message.o sample_func.o のようにしても良いかと思います。

ftdr5v6bn
質問者

お礼

前回に続いて今回もお答えいただきありがとうございました。 この方法で無事に実行することができました。 ネーミングでひっかかってることに気がつかなかったので、 名前の付け方をもう一度見直そうと思います。

関連する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を用いたカーネル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' から出ます 長文で申し訳ありませんが、お力をお貸しください。 宜しくお願いします。

  • [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 ...というエラーが直せなくて困っております。 どなたかお分かりになる方、お力をお貸しください 宜しくお願いします。

  • 仮想関数でのオーバーライドでの質問

    仮想関数でのオーバーライドでの質問 二つの派生クラスを定義したのですが、一つ目のクラスのメソッドが実行されないで困っています。 下記にソースを載せておきます。 どこが原因でそうなるのかご指摘お願いします。 /* 継承 */ #include <iostream> using namespace std; class Var { private: int value; static Var* re; public: // 静的関数 static bool func() { // 内部で同一の関数を呼び出す re->show(); return true; } virtual show() { cout << "message00" << "moji" << endl; } // 自身のポインタを取得 Var() { re = this; } }; Var* Var::re = NULL; class Msg01 : public Var { private: int value; public: show(void) { cout << "message01" << "moji" << endl; } }; class Msg02 : public Var { private: int value; public: show(void) { cout << "message02" << "moji" << endl; } }; int main() { Msg01 val; Msg02 msva; val.func(); msva.func(); getchar(); return 0; } /------------------------------------------------------/ 実行結果 message02moji message02moji /------------------------------------------------------/ message01mojiが表示されるはずなんですが表示されないでいます。 Msg02を宣言したためこのようになってしまったんでしょうか?

  • DLLをGetProcAddress()で実行できない。

    dllの操作の練習をしております。以下のソースのどこがおかしいのでしょうか? add.dllの内容は単にa+bの結果をメッセージボックスに表示させるだけの処理です。add.lib(インポートライブラリ)をリンクさせればうまく動きます。 しかし、GetProcAddress()を使って明示的にdllを呼び出そうとすると、コンパイルエラーで ADD(hWnd,5,5); の行に 「int (__stdcall *)(void)' : 実引数が多すぎます。」 となります。このメッセージの意味もわかりません。 以下のソースのどこがおかしいのでしょうか?コンパイラはVC++6.0でOSはWin2000です。 #include<windows.h> void CALLBACK ADD(HWND hwnd,int a, int b); //ウィンドウプロージャ(ここは別に普通) LRESULT CALLBACK WndProc(HWND hWnd , UINT msg , WPARAM wp , LPARAM lp) { switch (msg) { case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hWnd , msg , wp , lp); } int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance , PSTR lpCmdLine , int nCmdShow) { static FARPROC ADD;  //あやしい HWND hWnd; MSG msg; WNDCLASS winc;     //ウィンドウを作る処理 //~(省略)~ /****明示的にdllを呼び出す****/ ADD = GetProcAddress( LoadLibrary(TEXT("add.dll")) , TEXT("ADD")); ADD(hWnd,5,5); /****************************/ while (GetMessage(&msg , NULL , 0 , 0 )) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } お願いします。

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

    以下に何もしない何もしないカーネルモジュールを組み込みたいのですが、うまくいきません。 以下のソースをコンパイルします。 #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

  • 複数ファイルに分割した時の構成について

    大学の卒論にむけてプログラムを書いていて、一つのmain.cでは長くなってきたので、関数を func1.h func1.c のような別ファイルに記述することにしました。 その現在の構成を、質問欄の下部に簡単に書いたので、構成が自然かどうか意見をお聞きしたいです。特に、 「include文、define文をヘッダファイルにまとめて、各ファイルからincludeしている構造」がコードの記述方法として、きもちわるくないか、一般的かどうか、教えてください。 このようにした理由は、 ・defineマクロを多くのサブ関数で利用している。 ・define定義の値を細かく変えながら実行し、結果の違いを出力したい。 ・その為、各ファイルの頭にdefine定義を置いた場合、定義の値を  いちいち全てのファイルで変更しなければならなくなり、面倒…。 →defineマクロをdefine.hにまとめた。ついでに、<stdio.h>,<math.h>なども置いてしまえばスッキリするかも~。 という経緯です。 理学の学科でまわりに詳しい人がいなく、 プログラム知識もほぼ独学なので、不安に感じて質問しました。 よろしくおねがいします。 +++++++++++++ 以下が、簡単なファイル構成です +++++++++++++ -----define.h----- #include <stdio.h> #include <math.h> #define A_MAX 3 #define B_MAX 5 -----main.c---- #include "define.h" int main() { func1(); func2(); func3(); } -----func1.h---- #include "define.h" void func1(int hoge); //プロトタイプ宣言 -----func1.c---- #include "func1.h" void func1() { hogehoge; } ------func2以下、func1と同構造

  • 分割コンパイルの手順と方法について

    Visual Studio 2010でファイルを分割してコンパイル、リンクする方法がわかりません。以下のような3つのファイルです。 [myfunc.h] /* max関数の宣言 */ int max(int x, int y); [myfunc.c] int max(int x, int y) { if (x > y) return x; else return y; } [Sample13.c] #include <stdio.h> #include "myfunc.h" int main(void) { int num1, num2, ans; printf("1番目の整数を入力してください。\n"); scanf("%d", &num1); printf("2番目の整数を入力してください。\n"); scanf("%d", &num2); ans = max(num1, num2); printf("最大値は%dです。\n", ans); return 0; } 以上3つのファイルはあくまでも便宜的なもので、複数のファイルのコンパイル・リンクの手順を具台的に理解するために 用意したものです。

  • C言語の基本的な質問ですが、関数へのポインタの宣言

    関数へのポインタの質問です。 下のように、関数へのポインタを使ったプログラムを書きました。 (関数へのポインタを理解するためのものなので、実用的な意味はありません。(*^_^*) また、このプログラムはコンパイルもリンクも実行も問題なく出来ます。) #include <stdio.h> int add_func(int,int); (*func_p0) (int,int); int main(void) { int (*func_p1) (int,int); int (*func_p2) ( ); int hoge0,hoge1,hoge2; func_p0=add_func; hoge0=func_p0(3,5); printf("0 : 3+5は%d\n",hoge0); func_p1=add_func; hoge1=func_p1(3,5); printf("1 : 3+5は%d\n",hoge1); func_p2=add_func; hoge2=func_p2(3,5); printf("2 : 3+5は%d\n",hoge2); return(0); } int add_func(int x, int y) { return(x+y); } func_p0のように戻り値の型を書かない場合と、func_p1やfunc_p2のように戻り値の型を書くのとでは何が違うのでしょうか。 func_p0は外部変数ですが、自動変数にする(main関数の中で同様に宣言。)とコンパイルエラーになります。 それはなぜですか。 func_p1のように引数の型が書いてあるのと、func_p2のように引数の型が書いていないのでは何が違うのでしょうか。 int (*func_p2) ( );というのは、int (*func_p2) (void);とは違うんですよね?

  • 分割コンパイル

    分割コンパイルでsub.c をコンパイルしても fraction.h:10: two or more data types in declaration of `kiyaku' と出てきます 分数計算するプログラムの一部で,規約分数を求める部分なのですがどうもうまくコンパイルできません。 構造体とポインタについていまいち分かっていないのでそれが原因だとおもうんですけど,どこがわるいか分かりません。エラーも何を意味してるかわかりません。どなたか教えてくださるとうれしいです。 ******sub.c****** #include "fraction.h" struct fraction *kiyaku(struct fraction *a){ int aa,bb,temp; if(a->denominator < a->numerator){ aa = a->numerator; bb = a->denominator; } else { aa = a->denominator; bb = a->numerator; } while(bb !=0){temp = aa%bb; aa = bb; bb=temp;} a->numerator /= aa; a->denominator /= aa; return(a); } ******fraction.h******* struct fraction{ int numerator;//bunsi int denominator;//bunbo } extern struct fraction *kiyaku(); extern struct fraction *add(); extern void output();