Tag List for Linux

HelloWorldソースコード解説

今回は、以前の記事にて作成したHelloWorldのソースコードについて見ていきます。 hello.c #include <linux/module.h> #include <linux/init.h> MODULE_LICENSE(“Dual BSD/GPL”); static int hello_init(void) { printk(KERN_ALERT “driver loaded\n”); printk(KERN_ALERT “Hello World\n”); return 0; } static void hello_exit(void) { printk(KERN_ALERT “driver unloaded\n”); } module_init(hello_init); module_exit(hello_exit); まずは上記コードをビルドし、生成されたドライバはどのような動作をするのか確認します。 このドライバはinsmodコマンドなどによりロードされるとsyslogに「driver loaded」と「Hellow World」という文字列を出力します。 # insmod hello.ko # tail -n 2 /var/log/messages Aug 17 05:31:03 localhost kernel: driver loaded Aug 17 05:31:03 localhost kernel: Hello World tailコマンドはファイルの末尾部分を出力するコマンドです。 -nオプションをつけることで、出力する行数を指定できます。 今度はドライバ「hello」をアンロードします。 # rmmod hello # tail -n 1 /var/log/messages Aug 17 19:07:17 localhost kernel: driver unloaded アンロードすると、syslogに「driver unloaded」という文字列が出力されます。 では、ソースコードの解説に移ります。 #include <linux/module.h> #include <linux/init.h> アプリケーションを開発する場合、インクルードするヘッダファイルは「stdio.h」や「string.h」などになると思いますが、それらはユーザー空間で使用するライブラリであり、ドライバ開発ではインクルードしません。 代わりに、「linux/module.h」や「linux/init.h」などをインクルードします。 MODULE_LICENSE(“Dual BSD/GPL”); この行はMODULE_LICENSEマクロでドライバのライセンスを定義しています。 この行を記述することによりこのドライバは「GPLである」と明示したことになり、GPL規約に準拠する必要があります。 この行がなくてもコンパイルは通りますが、警告が出力されます。 static int hello_init(void) { printk(KERN_ALERT “driver loaded\n”); printk(KERN_ALERT “Hello World\n”); return 0; } 上記で定義している「hello_init」関数はドライバロード時、つまりinsmodコマンド実行時などに呼び出されるエントリポイントです。 ロード時のエントリポイントの指定は「module_init」マクロで行います。 アプリケーションのエントリポイントは必然的にmain関数となりますが、ドライバの場合は「module_init」マクロでエントリポイントを指定することになります。 戻り値に「0」を返すことで、insmodコマンドは成功します。ロード時の処理で何らかのエラーが発生した場合は0以外を返します。(上記サンプルでは、無条件で「0」を返しています。) 関数内ではprintk関数を呼び出しています。 似た関数としておなじみのprintf関数がありますが、ドライバでは標準ライブラリをインクルードしていないので当然使えません。 というよりそもそも、カーネル空間で動作するドライバはコンソール画面(標準出力)がないので、使いようがありません。 しかし、それではデバックが大変なので代わりに用意されたのがprintk関数です。 […]