Ftrace はデバッグ fs ファイルを操作して制御されます。しかし、これはどのように可能ですか?カーネルはこのファイルの書き込みをどのように知って必要な作業を開始しますか?たとえば、tracing_onに1を書き込むと、カーネルはトレースをオンにします。特別なファイル構造やdebugfsのカーネルサブスクリプションの変更に関連していますか?それとも明らかなものが欠けていますか?
答え1
見つけたと思います。これによると協会 カーネルでは、文字型デバイスは、システムに登録するために使用される struct cdev で表されます。ほとんどのドライバ操作は、構造体ファイル操作、構造体ファイル、構造体inodeという3つの重要な構造を使用します。前述のように、キャラクターデバイスドライバはデバイスタイプファイルを介してユーザーが発行した変更されていないシステムコールを受け取ります。したがって、文字デバイスドライバの実装は、ファイル固有のシステムコール(開く、閉じる、読み取り、書き込み、lseek、mmapなど)を実装することを意味します。これらの操作については、struct file_Operations 構造のフィールドで説明されています。
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
[...]
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
[...]
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *, fl_owner_t id);
int (*release) (struct inode *, struct file *);
[...]
これにより、必要な関数で上記の関数ポインタを初期化できます。たとえば、tracing_on の場合、これは kernel/trace/trace.c の初期化であり、これらの関数は同じファイルに実装されます。
static const struct file_operations rb_simple_fops = {
.open = tracing_open_generic_tr,
.read = rb_simple_read,
.write = rb_simple_write,
.release = tracing_release_generic_tr,
.llseek = default_llseek,
};
これはこのディレクトリを生成するコードでもあります。
trace_create_file("tracing_on", 0644, d_tracer,
tr, &rb_simple_fops);