カスタムLinuxカーネルモジュールの作成
1.簡単なカーネルモジュールを開始する
私たちもハローワールドから始めましょう.ここでは、カーネルモジュールの基本フレームワークと、生成方法、ロード方法について説明します.くだらないことは言わないで、Coding:
コンパイルしましょう、もちろんgccです:gcc-c-o hello.o -I/usr/src/linux/include -D__KERNEL__ -DMODULE hello.c説明:-Iカーネルモジュールの作業環境のカーネルのヘッダファイルパスを指定します.指定しないと、通常kernelバージョンと一致しない警告が発生し、問題が発生することがあります.-Dマクロを定義し、カーネルモジュールは2つのマクロMacro:_を使用するKERNEL__ およびMODULE
モジュールファイルがあります.ロードしましょう.コマンドを使用します.insmod hello.o問題がなければ、今ロードに成功しました.カーネルモジュールがカーネルに入っているかどうかを確認し、コマンド:lsmodを使用して、出力リストにhelloモジュールがあるかどうかを確認します.では、ロード時に「Hello,World!」と出力するモジュールがあります.終了時に出力"Bye!「見ていません.コマンド:dmesgを使用して、出力メッセージに「Hello,World!「.今すぐ終了しましょう.このモジュールをカーネルから外して、コマンドを使用します:rmmod hello今モジュールhelloはカーネルから行って、コマンドdmesgで、「Bye!」を見ることができます.
はい、これもカーネルモジュールです.でももっと言えばstatic int init_module()はモジュールロード時にシステムが呼び出す関数で,Oh,man,構造関数のように見える.成功した場合は、0を返す必要があります.そうしないと、エラー番号です.
static void cleanup_module()は、モジュールのアンインストール時に呼び出される関数であり、構造関数の想像です.
カーネルプログラミングでは標準ライブラリは使用できません.カーネルモジュールではカーネル関数、すなわち/proc/ksymsで見つけられる関数しか使用できません.例えばprintf-->printk
OK、私たちはやはりMakefileに来て、毎回いつもの命令を避けるようにしましょう:#######################Makefile CC=gcc
KERNELSRC =/usr/src/linux-2.4////if different, change it.
CFLAGS = -O2 -Wall -I$(KERNELSRC)/include -D__KERNEL__ -DMODULE
object = test.osource = test.c
$(object): $(CC) $(CFLAGS) -c $(source)
.PHONY: cleanclean: rm -f *.o
2.複雑な「Hello World」は簡単すぎて、モジュールファイルの生成方法、ロード方法、アンインストール方法について説明しました.モジュールのロードとアンインストール時の関数も分かりました.しかし、私たちはもっと知りたいです.複雑なものをください.
はい、ちょっと複雑なものをください.
このカーネルには文字デバイスが登録されており、file_を介してoperations構造は、その様々な操作を指定します.
さあ、makeさん、カーネルファイルをコンパイルして生成します.またロードしましょう.コマンド:dmesgで、得られたプライマリ・デバイス番号を見てください.(私のシステムでは268)コマンド:lsmodでカーネルがモジュールをロードしているかどうかを確認します.
3.テストしてみましょう.テストしてみましょう.テストの前に、デバイスファイルが作成されているかどうかを確認します./devの下にtestデバイスファイルがあるかどうかを確認し、ない場合は手動で作成します.前に見たメインデバイス番号で、コマンド「mknod test c 268 0」で作成したデバイスファイルを使用して、私のテストプログラムを開始しましょう.
Makefileをもう1つ書いて、makeは実行ファイルを得て、私たちのテストを開始します.見えましたか、カーネルから正しい結果が得られました.
4.ちょっとしたまとめここでは、簡単な文字ドライバを示し、プログラムを使用してテストしました.私たちの主な仕事はopen,read,write,ioctlを実現することですシステム呼び出しの処理.これらの関数ポインタはfileoperations構造に割り当てられている.もちろん、これらの関数には固定的な形式があります.それに従ってください.
もう1つは,カーネル2.4と2.6のカーネルに対する処理が大きく変化したことである.ここで言うのはすべて2.4版です.
もう一つはバージョンの問題で、『Linux Device Driver』に紹介されています.この本はカーネルを書く人はみな勉強しなければならないかもしれない.
5.駆動の違いは何ですか.うん、これは言いにくい.ドライバはカーネルモジュールであってもよいが、カーネルモジュールはドライバではない.したがって、ドライバはカーネルモジュールのサブセットです.これはカーネルモジュールの役割に依存します.カーネルモジュールは、主にカーネルを容易に追加し、カーネル空間で動作させるためです.ドライバは、カーネルモジュールであり、カーネルモジュールのプロパティがありますが、最も主要な目的は「ハードウェアを定義された内部プログラミングインタフェースに応答させ、デバイスの動作の詳細を完全に隠す」ことです.主にハードウェアの可用性の問題を解決します.一般的には、ハードウェアと直接関係します.
ソース:http://blog.csdn.net/firststp/archive/2005/06/15/395009.aspx
私たちもハローワールドから始めましょう.ここでは、カーネルモジュールの基本フレームワークと、生成方法、ロード方法について説明します.くだらないことは言わないで、Coding:
- //////////hello.c
- #include <linux/config.h>
- #include <linux/module.h>
-
- #include <linux/kernel.h> /* printk() */
-
- static int init_module()
- {
- printk("Hello,World!/n");
- return 0; /* , 0 */
- }
-
- static void cleanup_module()
- {
- printk("Bye!/n");
- }
コンパイルしましょう、もちろんgccです:gcc-c-o hello.o -I/usr/src/linux/include -D__KERNEL__ -DMODULE hello.c説明:-Iカーネルモジュールの作業環境のカーネルのヘッダファイルパスを指定します.指定しないと、通常kernelバージョンと一致しない警告が発生し、問題が発生することがあります.-Dマクロを定義し、カーネルモジュールは2つのマクロMacro:_を使用するKERNEL__ およびMODULE
モジュールファイルがあります.ロードしましょう.コマンドを使用します.insmod hello.o問題がなければ、今ロードに成功しました.カーネルモジュールがカーネルに入っているかどうかを確認し、コマンド:lsmodを使用して、出力リストにhelloモジュールがあるかどうかを確認します.では、ロード時に「Hello,World!」と出力するモジュールがあります.終了時に出力"Bye!「見ていません.コマンド:dmesgを使用して、出力メッセージに「Hello,World!「.今すぐ終了しましょう.このモジュールをカーネルから外して、コマンドを使用します:rmmod hello今モジュールhelloはカーネルから行って、コマンドdmesgで、「Bye!」を見ることができます.
はい、これもカーネルモジュールです.でももっと言えばstatic int init_module()はモジュールロード時にシステムが呼び出す関数で,Oh,man,構造関数のように見える.成功した場合は、0を返す必要があります.そうしないと、エラー番号です.
static void cleanup_module()は、モジュールのアンインストール時に呼び出される関数であり、構造関数の想像です.
カーネルプログラミングでは標準ライブラリは使用できません.カーネルモジュールではカーネル関数、すなわち/proc/ksymsで見つけられる関数しか使用できません.例えばprintf-->printk
OK、私たちはやはりMakefileに来て、毎回いつもの命令を避けるようにしましょう:#######################Makefile CC=gcc
KERNELSRC =/usr/src/linux-2.4////if different, change it.
CFLAGS = -O2 -Wall -I$(KERNELSRC)/include -D__KERNEL__ -DMODULE
object = test.osource = test.c
$(object): $(CC) $(CFLAGS) -c $(source)
.PHONY: cleanclean: rm -f *.o
2.複雑な「Hello World」は簡単すぎて、モジュールファイルの生成方法、ロード方法、アンインストール方法について説明しました.モジュールのロードとアンインストール時の関数も分かりました.しかし、私たちはもっと知りたいです.複雑なものをください.
はい、ちょっと複雑なものをください.
- // TestModule.c
- #define _NO__VERSION__
-
- #include <linux/module.h>
- #include <linux/version.h>
- #include <linux/kernel.h>
- #include <linux/types.h>
- #include <linux/fs.h>
- #include <linux/mm.h>
- #include <linux/errno.h>
- #include <asm/segment.h>
- #include <linux/sched.h>
- #include <asm/uaccess.h>
-
- #define DATA_LENGTH 10
- /* Module parameters */
-
- MODULE_AUTHOR("sss <[email protected]>");
- MODULE_DESCRIPTION("test driver");
- MODULE_LICENSE("GPL");
-
-
- char kernel_version[]=UTS_RELEASE;
-
- unsigned int test_major=0; //
-
- ssize_t read_test(struct file *file, char *buf, size_t count, loff_t *f_ops)
- {
- int left,i,*p;
- int data[DATA_LENGTH];
- p=data;
- for(i=0;i<10;i++)
- data[i]=61; // ”= “ 。
-
- for(left=count;left>0;left--)
- {
- //
- __copy_to_user(buf,p,1);
- buf++;
- p++;
- }
- return 0; // must reture 0;
- }
-
- ssize_t write_test(struct file *file, const char *buf, size_t count, loff_t *f_ops)
- {
- return 0; // must reture 0;
- }
-
- static int open_test(struct inode *inode, struct file *file)
- {
- MOD_INC_USE_COUNT;
- return 0; // must reture 0;
- }
-
- static int release_test(struct inode *inode, struct file *file)
- {
- MOD_DEC_USE_COUNT;
- return 0; // must reture 0;
- }
-
-
- // , linux/fs.h
- struct file_operations test_fops ={
- read: read_test,
- write: write_test,
- open: open_test,
- release:release_test
- };
-
-
- /* insmod, call it */
- int init_module(void)
- {
- int result;
- result=register_chrdev(0,"test",&test_fops);
- if(result<0)
- {
- /*printf("can't get major number");*/
- printk(KERN_INFO "test:Can't get major number/n");
- return result;
- }
- if(test_major==0)
- test_major=result;
- printk("test major:%d/r/n",result);
- return 0;//
- }
-
- /* rmmod, call it */
- void cleanup_module(void)
- {
- unregister_chrdev(test_major,"test");// ,
- }
このカーネルには文字デバイスが登録されており、file_を介してoperations構造は、その様々な操作を指定します.
さあ、makeさん、カーネルファイルをコンパイルして生成します.またロードしましょう.コマンド:dmesgで、得られたプライマリ・デバイス番号を見てください.(私のシステムでは268)コマンド:lsmodでカーネルがモジュールをロードしているかどうかを確認します.
3.テストしてみましょう.テストしてみましょう.テストの前に、デバイスファイルが作成されているかどうかを確認します./devの下にtestデバイスファイルがあるかどうかを確認し、ない場合は手動で作成します.前に見たメインデバイス番号で、コマンド「mknod test c 268 0」で作成したデバイスファイルを使用して、私のテストプログラムを開始しましょう.
- // TestApp.c
- #include "stdio.h"
- #include "sys/stat.h"
- #include "fcntl.h"
-
- int main()
- {
- char buf[20]={0,};
- int i=0;
- int p = open("/dev/test",O_RDWR);
- if (p == -1)
- {
- printf("Can't open /dec/test /r/n");
- exit(0);
- }
- //
- printf("buf addr:%ui/r/n",buf);
- //
- read(p,buf,10);
- for (i=0;i<10;i++)
- {
- printf("%s/r/n",buf+i);
- }
- close(p);
- //
- return 1;
- }
Makefileをもう1つ書いて、makeは実行ファイルを得て、私たちのテストを開始します.見えましたか、カーネルから正しい結果が得られました.
4.ちょっとしたまとめここでは、簡単な文字ドライバを示し、プログラムを使用してテストしました.私たちの主な仕事はopen,read,write,ioctlを実現することですシステム呼び出しの処理.これらの関数ポインタはfileoperations構造に割り当てられている.もちろん、これらの関数には固定的な形式があります.それに従ってください.
もう1つは,カーネル2.4と2.6のカーネルに対する処理が大きく変化したことである.ここで言うのはすべて2.4版です.
もう一つはバージョンの問題で、『Linux Device Driver』に紹介されています.この本はカーネルを書く人はみな勉強しなければならないかもしれない.
5.駆動の違いは何ですか.うん、これは言いにくい.ドライバはカーネルモジュールであってもよいが、カーネルモジュールはドライバではない.したがって、ドライバはカーネルモジュールのサブセットです.これはカーネルモジュールの役割に依存します.カーネルモジュールは、主にカーネルを容易に追加し、カーネル空間で動作させるためです.ドライバは、カーネルモジュールであり、カーネルモジュールのプロパティがありますが、最も主要な目的は「ハードウェアを定義された内部プログラミングインタフェースに応答させ、デバイスの動作の詳細を完全に隠す」ことです.主にハードウェアの可用性の問題を解決します.一般的には、ハードウェアと直接関係します.
ソース:http://blog.csdn.net/firststp/archive/2005/06/15/395009.aspx