Linuxなどのメモ書き

proc fs を使ったカーネル情報の表示


Rev.16を表示中。最新版はこちら

1.概要

Linuxでは/proc/配下に擬似ファイルシステム(proc fs)がマウントされており、ここの擬似的なファイルからカーネル内の様々な情報を簡単に取得できる。ここでは、proc fsにノードを作成して、カーネル内の情報を出力するモジュールの作り方をまとめる。Loadable Moduleとして作成する。

2. サンプルモジュール

proc fsにノードを作成して、そのノードからカーネル内の情報を出力するモジュールの例を以下に示す。

2.1 SouceとMakefile

以下のMakefileとSource(proctest.c)を同じディレクトリに置いてmakeするとLoadable Module proctestmod.koができる(Loadable Moduleの基本的な作りはLoadable Kernel Moduleの作り方を参照)。

このモジュールはカーネルにロードされると/proc/に'test'という名前の擬似ファイルを作成する。そして、/proc/testの中を見るとこのモジュール内の関数のアドレスを表示する。

Makefile

KERNELSRCDIR = /usr/src/linux
BUILD_DIR := $(shell pwd)
VERBOSE = 0

# モジュール名
obj-m := proctestmod.o

# <モジュール名>-objs にモジュールを構成するオブジェクトの一覧を列挙する
proctestmod-objs := proctest.o

all:
        make -C $(KERNELSRCDIR) SUBDIRS=$(BUILD_DIR) KBUILD_VERBOSE=$(VERBOSE) modules

clean:
        rm -f *.o
        rm -f *.ko
        rm -f *.mod.c
        rm -f *~

proctest.c

#include <linux/config.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>

MODULE_DESCRIPTION("Proc FS Test Module");
MODULE_AUTHOR("kztomita");
MODULE_LICENSE("GPL");

#define PROC_NAME "test"

static int proctest_read(char *, char **, off_t, int, int *, void *);

static struct proc_dir_entry *dirp;

static int proctest_init_module(void)
{
        /*
         * Create a proc file.
         */
        dirp = (struct proc_dir_entry *)
                create_proc_entry(PROC_NAME, 0444, (struct proc_dir_entry *) 0);
        if (dirp == 0)
                return(-EINVAL);

        dirp->read_proc = (read_proc_t *) proctest_read;

        return 0;
}

static void proctest_cleanup_module(void)
{
        remove_proc_entry(PROC_NAME, (struct proc_dir_entry *) 0);
}

static int proctest_read(char *buffer, char **start, off_t offset,
                         int count, int *peof, void *dat)
{
        int len = 0;
        len += sprintf(buffer + len,
                       "proctest_init_module()::    0x%08x\n",
                       (unsigned int) proctest_init_module);
        len += sprintf(buffer + len,
                       "proctest_cleanup_module():: 0x%08x\n",
                       (unsigned int) proctest_cleanup_module);

        return len;
}

module_init(proctest_init_module);
module_exit(proctest_cleanup_module);

2.2 実行結果

作成したモジュールをロードして/proc/testを読みだした結果は以下のとおり。
# /sbin/insmod proctestmod.ko    モジュールをロード
# ls /proc/ | grep test
test                             testファイルができている
# more /proc/test                カーネル内の情報(関数アドレス)が確認できる
proctest_init_module()::    0xf88ee000
proctest_cleanup_module():: 0xf88ee03c
#       

3. 解説

3.1 ノードの作成

モジュールが読みこまれた時にproc fs上に擬似ファイル/proc/testを作成している。ファイルの作成にはcreate_proc_entry()を使用する。

create_proc_entry()のプロトタイプ
struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
                                         struct proc_dir_entry *parent)

引数nameはファイル名、modeはパーミッション、parentはファイルを作る親ディレクトリのディレクトリエントリを指定する(*1)。NULLを指定すると、/proc直下に作成される。返り値は作成したノードのディレクトリエントリであるstruct proc_dir_entryへのポインタを返す。

ファイルを作成した後は、ファイルをRead/Writeした時にファイルシステムから呼び出されるハンドラを登録する。ハンドラはRead/Writeでそれぞれ、proc_dir_entry.read_proc,write_procに登録する。上記のサンプルではReadのみ処理するためread_procのみ指定している。

(*1) ディレクトリを作成したい場合は、proc_mkdir()を使用する。ディレクトリを指定するにはproc_mkdir()で返されたstruct proc_dir_entry をcreate_proc_entry()のparentに渡せばよい。

3.2 Readハンドラ

File SystemからよびだされるReadルーチン。関数のプロトタイプは以下のとおり。

int f(char *buffer, char **start, off_t offset, int count, int *peof, void *dat)

各引数の意味は表1の通り。


表1 Readハンドラの引数
引数
説明
buffer データ格納用Bufferの先頭アドレス。ハンドラはこの領域にデータを格納して返す。
start
呼び出し時の初期値は *start == NULL。*startに後に示す値を入れてリターンすることで、呼び出したFile SystemとReadハンドラ間のインタフェースが決まる。
offset
Readすべきデータのoffset。
count
bufferが指しているバッファのサイズ
peof
データがもうない(EOF)ことを呼び出し側に知らせるのに使用する。
*peof = 1としてリターンする。
dat



作成中

3.3 File SystemとReadハンドラのインタフェース


関連ページ

Loadable Kernel Moduleの作り方


最終更新 2006/11/28 16:27:49 - kztomita
(2006/11/16 01:14:09 作成)
添付ファイル
buffer.png - kztomita


リンク

その他のWiki
Linuxメモ
Xnuメモ

会社
(有)ビットハイブ
受託開発やってます。

よくやる仕事

・Webシステム開発(LAMP環境)
・Linuxサーバー設定関連
サーバー移転作業代行

開発事例にデジタルカタログ/マンガビューワーを追加しました。

draggable.jsのスマホ対応版デモページを追加しました。説明はこちら

検索

Adsense
最近のコメント