Procによるカーネルとユーザ状態のデータ交換

4475 ワード

最近、プログラムを書くにはカーネルがユーザー状態のパラメータを得る必要があります.幸いなことに、ioctrlは使えませんが、procで実現することができます.procファイルシステムはカーネルとユーザー状態のインタラクションの方法を提供しています.
procファイルシステムの詳細インタフェースは
主に注目しなければならないのは、これらの関数です.
struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent)
struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, struct proc_dir_entry *parent);
void remove_proc_entry(const char *name, struct proc_dir_entry *parent);

 
関数proc_mkdirはprocファイルシステムの下でフォルダを作成するために使用され、proc_mkdirの最初のパラメータは作成するディレクトリの名前で、2番目のパラメータは親ディレクトリ構造へのポインタです.いくつかの点に注意してください.
1.作成プロセスは名前のチェックがなく、proc_を完全に呼び出すことができます.mkdirは同じ名前のファイルをたくさん作成しました(チェックすると死ぬでしょう!)
2.名前には、「dev/new_proc」などのパスを含めることができます.devディレクトリが存在する場合、関数はdevディレクトリの下にnew_を作成します.procディレクトリ.
3.2番目のパラメータがNULLの場合、ルートディレクトリ、すなわち/proc/ディレクトリの下にディレクトリが作成されます.
関数の戻り値は、新規作成ディレクトリに対応するproc_です.dir_entry、これを保存すればこのディレクトリの下でファイルを作成することができますが、実際には保存しなくても、上記の2点目の性質を利用してディレクトリの下でファイルを作成することができ、ディレクトリを削除するにはパスを知るだけでいいのです~
 
関数create_proc_entryはファイルを作成するために使用され、modeパラメータがNULLの場合、デフォルトのファイルアクセス権は755で、他のパラメータはproc_mkdir類似
 
関数remove_proc_entryは作成したディレクトリやファイルを削除するために使用されます.興味深いことに、この関数は名前と親ディレクトリを知るだけで削除できます.
 
こんなにたくさん言ったのに、どうやってデータを交換しますか?
proc_を理解する必要がありますdir_entryの構造だ
struct proc_dir_entry {
	unsigned int low_ino;
	unsigned short namelen;
	const char *name;
	mode_t mode;
	nlink_t nlink;
	uid_t uid;
	gid_t gid;
	loff_t size;
	struct inode_operations * proc_iops;
	const struct file_operations * proc_fops;
	get_info_t *get_info;
	struct module *owner;
	struct proc_dir_entry *next, *parent, *subdir;
	void *data;
	read_proc_t *read_proc;
	write_proc_t *write_proc;
	atomic_t count;		/* use count */
	int deleted;		/* delete flag */
	void *set;
};

他のパラメータは無視できます.ここで注意しなければならないのは、2つのメンバー変数です.
read_procとwrite_proc
この2つの変数のタイプは次のとおりです.
typedef	int (read_proc_t)(char *page, char **start, off_t off, int count, int *eof, void *data);
typedef	int (write_proc_t)(struct file *file, const char __user *buffer, unsigned long count, void *data);

 
Procファイルの読み書き操作は、最終的にread_に変換されます.procとwrite_procの呼び出し.
カーネルにprocファイルを登録すればread_が実現するprocとwrite_proc関数を設定し、proc_を設定します.dir_entryはメンバー変数の値に対応し,ユーザ状態で読み書きを行うことでカーネルと対話できる.
 
この2つの関数のパラメータを説明します.
read_の場合proc_t
1.最初のパラメータ:なぜpageと呼ばれますか?答えはprocファイルに対して読み取り操作を呼び出すと、カーネルにページサイズのバッファが割り当てられます.1ページより大きいデータをどのように出力するかは、2番目と3番目のパラメータに依存します.
2、3番目のパラメータを理解するために、ファイル操作に関連するシステム呼び出しを思い出します.
int open(const char *pathname, int flags);
off_t lseek(int fildes, off_t offset, int whence);
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
procファイルの場合、1回のread操作で最大1つのpageのデータしか読み込めません.1ページ以上のデータを読み込む必要がある場合はreadの戻り値を保存し、lseekを使用してoffsetを設定し、readを再度呼び出します.パラメータの説明に戻ります.
2.startとoffパラメータ:offはlseekの中のoffset(lseek whenceはSEEK_END、offsetが負の場合、伝わるoffはゼロで、具体的な原因は考古学的である).
*startの値を設定しない場合、offの値は[0,count-1]の間でのみ、読み取り可能なデータサイズはcount-offです.システムは[page+off,page+count-1]間のデータをユーザのbufferにコピーしたことが理解できる.offの値が範囲を超えている場合、readはデータを読めません.
*startの値が設定されている場合、*startが指すアドレスはoffが指定したアドレスであり、offの値は無視され、[start,start+count-1]間のデータがユーザ空間にコピーされると考えられます.もちろんstartアドレスの位置決めを実現するにはoffの値が必要になる場合があります.
3.countパラメータはreadのcountと一致する
4.eofパラメータは、このパラメータを設定してデータを提供したくないことを示しています.神馬の意味は?
このパラメータを設定しないと、上記のstartが空の場合、read_Procが戻ると、システムが発見(count-off)たとえば、次のような読み込み操作があります.
lseek(fd, 2, SEEK_SET); read(fd, buff_r, 30)

最初の呼び出しread_proc,off=2,count=30,startの値を設定していないため、28バイトのデータを読み出し、*eofを設定していないため、システムは再びread_を送信します.proc
2回目の呼び出しread_proc,off=30,count=2,パラメータstartの説明では,この呼び出しに対してシステムはデフォルトでデータを読めない(怨念,なぜ送信するのか)と述べている.
そしてreadは28に戻る
このパラメータを設定すれば2回目のダウンはありません.
5.dataパラメータ、これはドライバに予約したパラメータです.
write_の場合Proc関数、パラメータは簡単で、説明する必要があるのはただ1点だけで、write_ですProcの2番目のパラメータbufferはユーザー状態のアドレスで、copy_を使う必要がありますfrom_userはユーザ状態からカーネル状態のバッファにデータをコピーする.
作者:ziziwu 2011-10-20 14:40:08に発表
テキストリンク
読書:7コメント:0
コメントの表示