LinuxカーネルモジュールのファイルI / O
-
07-07-2019 - |
質問
ファイルを開いて読み取る必要があるLinuxカーネルモジュールを書いています。それを達成する最良の方法は何ですか?
解決
なぜファイルを開こうとしているのか尋ねてもいいですか?
Linuxの開発(好奇心から、私はカーネル開発者ではありません、私はJavaを使用しています)をフォローしたいと思います。私はこれについて LKMLメッセージを見つけることができました。それは通常悪い考えです。 LWNが昨年この記事を取り上げたことはほぼ肯定的ですが、記事を見つけるのに苦労しています。
これがプライベートモジュールである場合(カスタムハードウェアなど、モジュールが配布されない場合)、これを行うことができますが、メインラインにコードを送信する場合は、受け入れられない可能性があります。
Evan Teranはsysfsについて言及しましたが、これは私にとっては良い考えのようです。もっと難しいカスタム作業が本当に必要な場合は、常に新しいioctrlを作成できます。
編集:
OK、探している記事は Linux Journal にあります。この種のことを行うのが一般的に悪い考えである理由を説明し、その後、とにかくそれを行う方法を正確に説明します。
他のヒント
open
/ read
/ close
システムコールへの関連関数ポインタへのポインタを取得できると仮定すると、このようなことができます:
mm_segment_t fs = get_fs();
set_fs(KERNEL_DS);
fd = (*syscall_open)(file, flags, mode);
if(fd != -1) {
(*syscall_read)(fd, buf, size);
(*syscall_close)(fd);
}
set_fs(fs);
" syscall _ *
"を作成する必要があります。私が示した関数ポインタ。もっと良い方法があると確信していますが、これはうまくいくと思います。
一般的に言って、カーネルモジュールからファイルを読み書きする必要がある場合、アーキテクチャ上何か間違ったことをしていることになります。
カーネルモジュールがユーザー空間ヘルパープロセスと通信できるようにするメカニズム(たとえば、netlink-またはキャラクターデバイスを登録する)が存在します。そのユーザー空間ヘルパープロセスは、必要な処理を実行できます。
システムコール(など)を実装して、ユーザー空間で開かれたファイル記述子を取得し、カーネルから読み取り/書き込みすることもできます。
これはおそらく、カーネルスペースでファイルを開こうとするよりも適切です。
カーネルスペースから既にファイルを開いているものがいくつかあります。それらを見ることができます(ループドライバーが思い浮かびますか?)。
/ procファイルシステムは私的使用にも適していて、簡単です。
http://www.linuxtopia.org/online_books/Linux_Kernel_Module_Programming_Guide/x773.html
すべてのカーネル開発者は、カーネルスペースからのファイルI / Oが悪いと言います(特にこれらのファイルをパスで参照している場合)が、主流のカーネルはファームウェアをロードするときにこれを行います。ファイルから読み取る必要がある場合は、
kernel_read_file_from_path(const char *path, void **buf, loff_t *size, loff_t max_size, enum kernel_read_file_id id)
include / linux / fs.h
で宣言されている、ファームウェアローダーコードが使用する関数。この関数はエラー時に負の値を返します。
最後に id
変数のポイントが本当にわかりません。実際に使用されていないコードを見ると、 READING_FIRMWARE
あります(引用符なし)。
buf
はnullで終端されていません。代わりに、 size
でそのサイズを参照します。ヌル終端する必要がある場合は、文字列 size + 1
バイトを作成してコピーするか、 kernel_read_file()
関数( kernel_read_file_from_path(で使用) )
、 fs / exec.c
)で定義され、メモリが割り当てられている i_size
に追加します。 (これを行う場合は、モジュール内の kernel_read_file()
関数を別の関数名で再定義して、カーネル全体の変更を回避できます。)
ファイルに書き込む必要がある場合、 kernel_write()
関数( kernel_read_file()<によって使用される
kernel_read()
に類似)があります。 / code>したがって、 kernel_read_file_from_path()
)によっても、 kernel_write_file()
または kernel_write_file_from_path()
関数はありません。 kernel_read_file()
および kernel_read_file_from_path()
があるLinuxカーネルソースツリーの fs / exec.c
ファイルのコードを見ることができます。モジュールに含めることができる独自の kernel_write_file()
および kernel_write_file_from_path()
関数を記述するように定義されています。
そしていつものように、この関数をキャストすることにより、この関数を使用して、ファイルの内容をvoidポインターの代わりにcharポインターに格納できます。