Hello You

先の hello_world.c を修正して、課題だったパラメータを入力する、エラーコードを返す実装をしてみましょう。make 方法と Makefile は hello_world.c と変わらないので省略します。コンパイルが済んだと言う前提でこのページを書きます。

filehello_world.c
Expand allFold all
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 
 
 
 
 
 
 
 
 
 
 
 
-
|
|
|
!
 
-
|
!
 
-
|
|
!
 
-
!
 
 
 
 
 
 
 
#include <linux/kernel.h>
#include <linux/printk.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/stat.h>
 
static char *your_name = "Taro";
module_param(your_name, charp, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
 
static int return_value = 0;
module_param(return_value, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
 
/*
 * Tutorial hello world module init.
 * @return int == 0: Success. 
 *             < 0:  Fail, negative errno number.
 */
static int __init hello_world_init(void)
{       printk(KERN_INFO "%s: Hello %s san. return_value=%d\n", __func__, your_name, return_value);
        return return_value;
}
 
/*
 * Tutorial hello world module exit.
 * @return void
 */
static void __exit hello_world_exit(void)
{       printk(KERN_INFO "%s: Goodbye %s san.\n", __func__, your_name);
}
 
module_init(hello_world_init);
module_exit(hello_world_exit);
 
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Tutorial hello you.");
MODULE_AUTHOR("Your name or email address.");

パラメータを受け取る手段

モジュールはパラメータを受け取ることができます。主な手段は module_param() マクロ, DEVICE_ATTR マクロ, debugfs, procfs です。ここでは module_param を試します。次の表にそれぞれの説明をまとめておきます。パラメータ引き渡し方法にファイル・システム名が書かれている場合は、そのファイル・システム上に作られたノードを通して設定します。設定単位はノードと設定対象の対応です。.config は linux-stable ディレクトリ(ソース・コードの基底ディレクトリ)にある .config に書かれた構築条件です。=Y になっている場合に利用可能です。

手段パラメータ引き渡し方法設定単位.configドキュメント、特徴
module_paraminsmod or modprobe command line,
boot parameter,
sysfs node
モジュール毎CONFIG_SYSFSもっとも簡単です。変数名とパラメータ名を独立に指定できるmodule_param_named()、Call Back を実装できるmodule_param_cb()があります。アクセス用のノードが /sys/module/module_name/parameters/nameにできます。
DEVICE_ATTRsysfs nodeデバイス毎CONFIG_SYSFSドキュメントは Documentation/driver-model/device.txt, Documentation/filesystems/sysfs.txt に有ります。デバイス毎にパラメータを設定できます。デバイス毎ですので、モジュール・ロード時にデバイスが無い場合はパラメータを設定できません。実装か必要なコード量は多いです。ノードは /sys/devices/subsystem_base/subsystem/* にできます。バスやクラス構造的に追いやすい /sys/bus/* 以下、/sys/class/* 以下、/sys/block/* 以下からもシンボリックリンクを通じてアクセスできます。
debugfsdebugfs node任意構造CONFIG_DEBUG_FSドキュメントは debugfs にあります。主に使う関数は debugfs_create_dir(), debugfs_create_file(), debugfs_remove(), debugfs_remove_recursive() です。整数を扱う単純なノードであればドキュメントあるいは include/linux/debugfs.h から使用例を探して使うのが良いでしょう。
procfsprocfs node任意構造CONFIG_PROC_FSprocfs を中心にした使い方のドキュメントは有りません。include/linux/proc_fs.h より辿れる関数と Documentation/filesystems/seq_file.txt に使用例があるので参考にしてください。proc_create(), proc_create_data(), proc_mkdir(), remove_proc_entry() などの関数とマクロの使われ方を参考に使用して下さい。モジュールロード時にパラメータとして指定できません。module_init() で指定した関数内でノードを作成し、ロード直後にパラメータを設定することができます。

sysfs, procfs, debugfs は必ずあるのか?

sysfs と procfs は .config の記述により有無を選択できます。しかし、sysfs, procfs とも必ず存在すると仮定しても良いでしょう。sysfs または procfs を無くすと相当に不便です。system call に匹敵する機能を分担しています。
debufs はディストリビューションや評価環境によっては「無し」に設定されていることが有ります。debugfs で提供されるノードの機能は開発時は便利です。しかし、製品としてリリースできないようなセキュリティ・ホール、コンテンツ保護違反、NDA(機密保持契約)違反、動作が不安定になる機能が実装される傾向があります。debugfs (あるいはその一部ノード)を製品リリースに含めるかどうか精査した方が良いでしょう。

いずれの方法もノードができます。ノードは read/write が可能なので userland - kernel 双方向で更新して、情報交換できます。

パラメータを入力する

まず、パラメータ無しで insmod, rmmod を試します。ソース・コードに書かれたデフォルト値で動作しているのがわかります。

$ sudo insmod hello_world.ko
[sudo] password for user_name:password
$ sudo rmmod hello_world.ko
$ dmesg

dmesg が出力した最後は次のようになります。your_name と return_value の値がそのまま表示されました。

[355028.315777] hello_world: module verification failed: signature and/or required key missing - tainting kernel
[355028.319261] hello_world_init: Hello Taro san. return_value=0
[355036.306520] hello_world_exit: Goodbye Taro san.

パラメータを付けて起動しましょう。your_name=Hanako とします。

$ sudo insmod hello_world.ko your_name=Hanako
$ sudo rmmod hello_world.ko
$ dmesg

dmesg が出力した最後は次のようになります。your_name に指定した Hanako が表示されました。アプリケーション・プログラムと仕組みは違いますがパラメータを受け取る手段が有ります。

[355218.292794] hello_world_init: Hello Hanako san. return_value=0
[355236.027700] hello_world_exit: Goodbye Hanako san.

エラーを返してみよう

printk の長さ制限


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS