Linuxカーネルプログラミング

7654 ワード

1.Hello, world.. 3
Exhello.c.. 3
1.1カーネルモジュールのコンパイルファイル...4
1.2マルチファイル・カーネル・モジュール...5
 
1.Hello, world
最初の穴居の原始人プログラマーが壁に最初の「洞窟コンピュータ」のプログラムを切り出したとき、カモシカの角の図案で表される「Hello world」を印刷するプログラムだった.ローマのプログラミング教科書では「Salut,Mundi」というプログラムで始まります.もし人々がこの伝統を破ったらどうなるか分かりませんが、この結果を発見しないほうが安全だと思います.
1つのカーネルモジュールには、少なくとも2つの関数が含まれます.init_module、このモジュールがカーネルを挿入するときに呼び出されます.cleanup_moduleは、モジュールが削除されたときに呼び出されます.典型的にはinit_moduleは、カーネル内の何かにハンドルを登録したり、カーネル内のプログラムを独自のコードに変換したりします(通常は、いくつかの作業を行ってから元の作業を呼び出すコードです).Clean_moduleモジュール要求取り消しinit_moduleが行ったすべての処理は、モジュールを安全にアンインストールできるようにします.
 
Exhello.c
/* hello.c
* Copyright (C) 1998 by Ori Pomerantz
*
* "Hello, world"- the kernel module version.
*/
 
/* The necessary header files */
 
/* Standard in kernel modules */
#include /* We're doing kernel work */
#include /* Specifically, a module */
 
 
 
/* Deal with CONFIG_MODVERSIONS */
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include
#endif
 
 
 
/* Initialize the module */
int init_module()
{
printk("Hello, world - this is the kernel speaking/n");
 
/* If we return a non zero value, it means that
* init_module failed and the kernel module
* can't be loaded */
return 0;
}
 
 
/* Cleanup - undid whatever init_module did */
void cleanup_module()
{
 printk("Short is the life of a kernel module/n");
}

 
1.1カーネルモジュールのコンパイルファイル
カーネルモジュールは、独立して実行できるファイルではなく、実行時にカーネルに接続するターゲットファイルが必要です.したがって、-cオプションでコンパイルする必要があります.また、すべてのカーネルモジュールには、特定のフラグが含まれている必要があります.
l __KERNEL__——このフラグは、ユーザプロセスではなくカーネルモジュールで実行されるヘッダファイルに通知します.
l MODULE--このフラグは、ヘッダファイルに適切なカーネルモジュールの定義を与えることを示します.
l LINUX--技術的には、このマークは必要ありません.しかし、比較的正規のカーネルモジュールを書き、複数のオペレーティングシステムでコンパイルしたい場合は、このフラグが便利になります.オペレーティングシステムとは独立した部分で通常のコンパイルを行うことができます.
コンパイルモジュールのオプションに応じて、フラグを含むように選択できるものもあります.カーネルがどのようにコンパイルされるかを明確にできない場合は、in/usr/include/linux/config.hで調べました.
l __SMP__——対称マルチスレッド.カーネルが対称マルチスレッドをサポートするようにコンパイルされる(1台のプロセッサで実行されるにもかかわらず)ことは定義されなければならない.もしそうであれば、他のことをする必要があります(12章参照).
l CONFIG_MODVERSIONS-CONFIG_の場合MODVERSIONSがアクティブになります.コンパイル時に定義し、ファイル/usr/include/linux/modversionsを含める必要があります.h.これはコードが自動的に完了することができます.
 
ex Makefile
 
# Makefile for a basic kernel module
 
CC=gcc
MODCFLAGS := -Wall -DMODULE -D__KERNEL__ -DLINUX
 
hello.o: hello.c /usr/include/linux/version.h
 $(CC) $(MODCFLAGS) -c hello.c
 echo insmod hello.o to turn it on
 echo rmmod hello to turn if off
 echo
 echo X and kernel programming do not mix.
 echo Do the insmod and rmmod from outside 

 
だから、残りのことはrootではありません(rootにコンパイルするのではなく、エッジにあります(注1.1).そうですか.コアコンテンツにhelloを挿入または削除します.そうするときは、新しいモジュールが/proc/modulesにあることに注意してください.
また、コンパイルファイルがXから挿入されることを推奨しないのは、カーネルにprintkで印刷する必要があるメッセージがあり、コンソールに送信されるためです.Xを使用しないと、使用している仮想端末(Alt-Fで選択したもの)に届き、見ることができます.逆に、Xを使ったら、二つの可能性があります.xterm–Cでコンソールを開くと、出力はどこに送られますか.もしなかったら、出力は仮想端末7--Xによって「上書き」されたものに送られる.
カーネルが不安定になると、Xなしでデバッグメッセージを得ることができます.Xの外でprintkはカーネルからコンソールに直接出力できます.Xでprintkがユーザ状態のプロセス(xterm–C)に出力される場合.プロセスがCPU時間を受信すると、Xサーバプロセスに送信されます.その後、XサーバプロセスがCPU時間を受信すると表示されますが、不安定なカーネルはシステムがクラッシュしたり、再起動したりすることを意味するので、エラーのメッセージを表示したくないので、エラーが発生したことを説明されるかもしれませんが、正しい時間を超えています.
1.2マルチファイルカーネルモジュール
いくつかのソースファイルの間でカーネルモジュールを分けることは意味があります.この場合、次のことをする必要があります.
1.1つ以外のすべてのソースファイルに、1行#define__を追加NO_VERSION__.これは重要です.moduleのためです.hは一般にkernel_を含むモジュールコンパイルされたカーネルバージョンを含むグローバル変数です.versionが必要ならh、あなたは自分を含まなければなりません.もし_があれば.NO_VERSION__そうしたらhは自動的に含まれません.
2.通常のようにソースファイルをコンパイルします.
3.すべてのターゲットファイルを1つにまとめます.X 86でld-m elf_を使用i386 –r –o .o <1st source file>
ここでは、このようなカーネルモジュールの例を示す.
ex start.c
 
/* start.c
* Copyright (C) 1999 by Ori Pomerantz
*
* "Hello, world"- the kernel module version.
* This file includes just the start routine
*/
 
/* The necessary header files */
 
/* Standard in kernel modules */
#include /* We're doing kernel work */
#include /* Specifically, a module */
 
 
 
/* Deal with CONFIG_MODVERSIONS */
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include
#endif
 
 
 
/* Initialize the module */
int init_module()
{
printk("Hello, world - this is the kernel speaking/n");
 
/* If we return a non zero value, it means that
* init_module failed and the kernel module
* can't be loaded */
return 0;
}
ex stop.c
 
/* stop.c
* Copyright (C) 1999 by Ori Pomerantz
*
* "Hello, world"- the kernel module version. This
* file includes just the stop routine.
*/
 
/* The necessary header files */
 
/* Standard in kernel modules */
#include /* We're doing kernel work */
 
#define __NO_VERSION__/* This isn't "the"file
* of the kernel module */
#include /* Specifically, a module */
 
#include /* Not included by
* module.h because
* of the __NO_VERSION__ */
 
 
 
/* Deal with CONFIG_MODVERSIONS */
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include
#endif
 
 
 
 
/* Cleanup - undid whatever init_module did */
void cleanup_module()
{
printk("Short is the life of a kernel module/n");
}
ex Makefile
 
# Makefile for a multifile kernel module
 
CC=gcc
MODCFLAGS := -Wall -DMODULE -D__KERNEL__ -DLINUX
 
hello.o: start.o stop.o
ld -m elf_i386 -r -o hello.o start.o stop.o
 
start.o: start.c/usr/include/linux/version.h
$(CC) $(MODCFLAGS) -c start.c
 
stop.o: stop.c/usr/include/linux/version.h
$(CC) $(MODCFLAGS) -c stop.c