sysfs tips
GNU/Linux において、ユーザ/カーネル間でのメッセージのやりとりのインターフェイスの一つといて一般的に知られている sysfs だが。今日は、デバイスドライバ等で広く利用されている、sysfs エントリの追加/削除の手法について記載する。
sysfs のエントリ追加は block や bus といったエントリのサブエントリとして追加するようになり、各エントリの追加方法は、親エントリによってインターフェイスが変わってくる。以前にも、io スケジューラにおける sysfs エントリの扱いについて調べたが、今回はその方法とは違ったやり方で、エントリの更新を行う。
今回紹介するのは class へのサブエントリの追加/削除の方法になる。
多くのデバイスドライバにおいて、class エントリ配下に自前で宣言したディレクトリエントリの追加を行う際に、モジュールの
module_init マクロで指定したロード関数から class_create() [driver/base/class.c] を呼び出す。
第一引数には、登録を行う struct module * 型オブジェクトを指定する。これは THIS_MODULE
マクロによって、現在ロードするモジュールの struct module *
オブジェクトを指定できる。また、第二引数に追加するディレクトリエントリ表示名を指定する。
また、削除はアンロード関数から class_destroy() を指定する。
次に、class に追加したディレクトリに、属性 (attribute) を追加する処理を見て行く。ただ "属性" というのはあくまで内部的な扱で、見かけはオンメモリのファイルの追加である。
登録は class_create_file() 関数に struct class_attribute
*型オブジェクトを指定して行う。class_attribute *型オブジェクトの宣言については、io スケジューラの場合同様に __ATTR
マクロがそのまま使える。ただし、get/set 関数のプロトタイプ宣言は異なるので、struct class_attribute *
[include/linux/device.h] を確認しながら行う。
エントリに登録した属性の削除は、class_remove_file() によって行う。
以上より、これらの内容をコードにすると次のようになる。
struct class *foo_class;
static struct class_attribute foo_debug_file = __ATTR(hoge, S_IRUGO, NULL, NULL);
static int foo_init_module(void)
{
foo_class = class_create(THIS_MODULE, "foo");
if(IS_ERR(foo_class)){
return 1;
}
err = class_create_file(foo_class, &foo_debug_file);
if(err){
class_destroy(foo_class);
return 1;
}
return 0;
}
static void foo_cleanup_module(void)
{
class_remove_file(foo_class, &foo_debug_file);
class_destroy(foo_class);
}
module_init(foo_init_module);
module_exit(foo_cleanup_module);
これで、/sys/foo というエントリを追加し、/sys/foo/hoge というファイルが存在する事が確認できる。
注意:VM 等のサンドボックスで実行する事を強くお勧めする
- Category(s)
- GNU/Linux
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/ohyama/sysfs-tips/tbping