/procファイルシステムとカーネルを使用する(1)-初歩的な関係の確立
/procファイルシステムはLinuxカーネルの仮想ファイルシステムで、仮想とはディスクパーティション上のファイルシステムとは異なり、カーネルが起動した後、動作したときにのみ動的に作成されます.
/procの下の内容はカーネルの配置と動作の状態によって変化して、例えば/proc/meminfoというファイル、中の内容はメモリ情報で、異なる機械は自然に違います;また、/procディレクトリの下に数字で命名されたサブディレクトリもあり、各サブディレクトリの名前は数字であり、現在システムが実行しているプロセスに対応し、サブディレクトリの内容はプロセスに対応する情報である.
procには他にもたくさんの情報がありますが、ここでは一つ一つ説明しません.興味があればグーグルで話してもいいです.
Linuxカーネルは長年の発展を経て、/procディレクトリの下の林林林総、すでに非常に多くて、すでに新しい/sysファイルシステムの代替/procを開発しましたが、多くの伝統的なプログラムは依然として/procファイルシステムをカーネルとユーザープログラムのインタフェースとして使用しています.
カーネルをより効率的にするには、カーネル開発者のことです.カーネルを使用する開発者として、/procファイルシステムの使用方法を把握することも役に立ち、/sysファイルシステムの組織が厳密な構造に比べて、/procを使用するのは便利な場合があります.
くだらないことを言わないで、まずドアに入って、/procの最も基本的な操作を紹介します.
このセットでは、操作/procファイルシステムの3つの最も基本的な関数について説明します.
コードクリップ1は、カーネルコードの
まず、この例のすべてのコードはカーネルバージョン2.6.38.2を使用しています.システムはubuntu 11.04 amd 64です.注意してください.
この3つの関数は、関数名から意味が理解できます.最初のcreate_proc_entry()関数は、ノードを作成するために使用されます.つまり、ファイルを作成します.
2番目のproc_mkdir()関数はディレクトリを作成します.
3番目のremove_proc_entry()関数はノードを削除することですが、実際にはノードだけでなくproc_も削除できます.mkdir()関数で作成されたディレクトリ.
注意すべきは、procに関連する関数であり、操作の目標は/procディレクトリの下にある.では、関数パラメータを見てみましょう.
create_proc_entry()関数:nameはノードの名前で、文字列です.modeアクセス権は、8進数で表すことができ、chmodコマンドが使用する権限と同じです.parent親ディレクトリ、struct proc_であることに注意dir_entry構造で、NULLと書けば/procディレクトリを表します.
proc_mkdir()関数:nameサブディレクトリ名、文字列;parent親ディレクトリは、上記の説明と同じです.
remove_proc_entry()関数:パラメータは上と同じです.
関数の説明が終わりました.この3つの関数があれば着工できます.くだらないことは言わないで、コードを貼ってください.
コードクリップ2は自分で書いた小さなモジュールで、削除/procノードを確立する方法を示します.
標準的な2.6カーネルモジュールの書き方.proc_test_Init()関数はエントリ、proc_test_exit()関数は出口です.
最初は4つのヘッダファイルが導入され、そのうち3つはカーネルモジュールが標準化されたヘッダファイルで、4つ目は主役、proc_fs.h,前述したように,操作/procの関数は定義されている.
9行目、USER_ROOT_DIRは、/procディレクトリの下で作成するサブディレクトリ名を定義し、ユーザーのルートディレクトリでもあります.10行目、USER_ENTRY 1はUSERで定義したROOT_DIRの下に作成されたノード名.
13行目、14行目はそれぞれUSER_を定義していますROOT_DIRとUSER_ENTRY 1対応ディレクトリ構造pt_rootとpt_entry1.
操作したデータを紹介して、流れを話しましょう.
proc_test_Init()関数:
この関数は、モジュールをロードするときに実行されるエントリ関数で、カーネルによって自動的に呼び出されます.19行目、関数は最初からproc_を呼び出します.mkdir()関数、/procディレクトリの下にサブディレクトリを作成し、proc_に注意します.mkdir()関数の2番目のパラメータ、NULLは/procをルートディレクトリとして表します.
サブディレクトリUSER_ROOT_DIRが正常に確立されると、create_が呼び出されます.proc_entry()関数はファイルノードを確立し、関数の3番目のパラメータparentに注意し、NULLではなくpt_root,表示はUSER_ROOT_DIRをルートディレクトリとして使用します.
ファイルの作成に成功したらpt_を設定する必要がありますentry 1の読み書きコールバック関数はNULLであり、このような目的は、このファイルノードの読み書き操作を処理しないことである.
proc_test_exit()関数:
ユーザがrmmodを呼び出してカーネルモジュールをアンインストールするとカーネルに呼び出されます.この関数は、確立されたノードを削除します.remove_に注意してください.proc_entry()関数のparent実パラメータです.ここではエラーが発生しやすく、カーネルエラーが発生します.
最後にMakefileを貼ります.
実行の効果を確認します.
次に、モジュールをロードした後にファイルノードをリストします.
次はファイル読み込みノード/proc/pt/pt_entry1
コールバック関数がNULLに設定されているので、何の結果もありません.
書き込みファイルノード/proc/pt/pt_entry1
書くのはあまり理想的ではないようですが、新聞を間違えました.pt_entry 1はあまり協力していませんね.そうですね.前はNULLに設定されていますから、人のせいにするわけにはいきません.ははは.次回は、自分の読み書き操作の仕方をご紹介します.
/procの下の内容はカーネルの配置と動作の状態によって変化して、例えば/proc/meminfoというファイル、中の内容はメモリ情報で、異なる機械は自然に違います;また、/procディレクトリの下に数字で命名されたサブディレクトリもあり、各サブディレクトリの名前は数字であり、現在システムが実行しているプロセスに対応し、サブディレクトリの内容はプロセスに対応する情報である.
procには他にもたくさんの情報がありますが、ここでは一つ一つ説明しません.興味があればグーグルで話してもいいです.
Linuxカーネルは長年の発展を経て、/procディレクトリの下の林林林総、すでに非常に多くて、すでに新しい/sysファイルシステムの代替/procを開発しましたが、多くの伝統的なプログラムは依然として/procファイルシステムをカーネルとユーザープログラムのインタフェースとして使用しています.
カーネルをより効率的にするには、カーネル開発者のことです.カーネルを使用する開発者として、/procファイルシステムの使用方法を把握することも役に立ち、/sysファイルシステムの組織が厳密な構造に比べて、/procを使用するのは便利な場合があります.
くだらないことを言わないで、まずドアに入って、/procの最も基本的な操作を紹介します.
このセットでは、操作/procファイルシステムの3つの最も基本的な関数について説明します.
コードクリップ1は、カーネルコードの
- struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
- struct proc_dir_entry *parent);
-
- struct proc_dir_entry *proc_mkdir(const char *name,
- struct proc_dir_entry *parent);
-
- void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
-
まず、この例のすべてのコードはカーネルバージョン2.6.38.2を使用しています.システムはubuntu 11.04 amd 64です.注意してください.
この3つの関数は、関数名から意味が理解できます.最初のcreate_proc_entry()関数は、ノードを作成するために使用されます.つまり、ファイルを作成します.
2番目のproc_mkdir()関数はディレクトリを作成します.
3番目のremove_proc_entry()関数はノードを削除することですが、実際にはノードだけでなくproc_も削除できます.mkdir()関数で作成されたディレクトリ.
注意すべきは、procに関連する関数であり、操作の目標は/procディレクトリの下にある.では、関数パラメータを見てみましょう.
create_proc_entry()関数:nameはノードの名前で、文字列です.modeアクセス権は、8進数で表すことができ、chmodコマンドが使用する権限と同じです.parent親ディレクトリ、struct proc_であることに注意dir_entry構造で、NULLと書けば/procディレクトリを表します.
proc_mkdir()関数:nameサブディレクトリ名、文字列;parent親ディレクトリは、上記の説明と同じです.
remove_proc_entry()関数:パラメータは上と同じです.
関数の説明が終わりました.この3つの関数があれば着工できます.くだらないことは言わないで、コードを貼ってください.
コードクリップ2は自分で書いた小さなモジュールで、削除/procノードを確立する方法を示します.
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/version.h>
- #include <linux/proc_fs.h>
-
- MODULE_LICENSE("Dual BSD/GPL");
- MODULE_AUTHOR("<[email protected]>");
-
- #define USER_ROOT_DIR "pt"
- #define USER_ENTRY1 "pt_entry1"
-
- // user defined directory
- static struct proc_dir_entry *pt_root;
- static struct proc_dir_entry *pt_entry1;
-
- static int proc_test_init(void)
- {
- // Create user root dir under /proc
- pt_root = proc_mkdir(USER_ROOT_DIR, NULL);
- if (NULL==pt_root)
- {
- printk(KERN_ALERT "Create dir /proc/%s error!
",
- USER_ROOT_DIR);
- return -1;
- }
- printk(KERN_INFO "Create dir /proc/%s
", USER_ROOT_DIR);
-
- // Create a test entry under USER_ROOT_DIR
- pt_entry1 = create_proc_entry(USER_ENTRY1,
- 0666, pt_root);
- if (NULL == pt_entry1)
- {
- printk(KERN_ALERT "Create entry %s under /proc/%s error!
",
- USER_ENTRY1, USER_ROOT_DIR);
- goto err_out;
- }
- printk(KERN_INFO "Create /proc/%s/%s
",
- USER_ROOT_DIR, USER_ENTRY1);
-
- pt_entry1->read_proc = NULL;
- pt_entry1->write_proc = NULL;
-
- return 0;
-
- err_out:
- remove_proc_entry(USER_ROOT_DIR, pt_root);
- return -1;
- }
-
- static void proc_test_exit(void)
- {
- // Remove all entries
- remove_proc_entry(USER_ENTRY1, pt_root);
- remove_proc_entry(USER_ROOT_DIR, NULL);
- printk(KERN_INFO "All Proc Entry Removed!
");
- }
-
- module_init(proc_test_init);
- module_exit(proc_test_exit);
標準的な2.6カーネルモジュールの書き方.proc_test_Init()関数はエントリ、proc_test_exit()関数は出口です.
最初は4つのヘッダファイルが導入され、そのうち3つはカーネルモジュールが標準化されたヘッダファイルで、4つ目は主役、proc_fs.h,前述したように,操作/procの関数は定義されている.
9行目、USER_ROOT_DIRは、/procディレクトリの下で作成するサブディレクトリ名を定義し、ユーザーのルートディレクトリでもあります.10行目、USER_ENTRY 1はUSERで定義したROOT_DIRの下に作成されたノード名.
13行目、14行目はそれぞれUSER_を定義していますROOT_DIRとUSER_ENTRY 1対応ディレクトリ構造pt_rootとpt_entry1.
操作したデータを紹介して、流れを話しましょう.
proc_test_Init()関数:
この関数は、モジュールをロードするときに実行されるエントリ関数で、カーネルによって自動的に呼び出されます.19行目、関数は最初からproc_を呼び出します.mkdir()関数、/procディレクトリの下にサブディレクトリを作成し、proc_に注意します.mkdir()関数の2番目のパラメータ、NULLは/procをルートディレクトリとして表します.
サブディレクトリUSER_ROOT_DIRが正常に確立されると、create_が呼び出されます.proc_entry()関数はファイルノードを確立し、関数の3番目のパラメータparentに注意し、NULLではなくpt_root,表示はUSER_ROOT_DIRをルートディレクトリとして使用します.
ファイルの作成に成功したらpt_を設定する必要がありますentry 1の読み書きコールバック関数はNULLであり、このような目的は、このファイルノードの読み書き操作を処理しないことである.
proc_test_exit()関数:
ユーザがrmmodを呼び出してカーネルモジュールをアンインストールするとカーネルに呼び出されます.この関数は、確立されたノードを削除します.remove_に注意してください.proc_entry()関数のparent実パラメータです.ここではエラーが発生しやすく、カーネルエラーが発生します.
最後にMakefileを貼ります.
- obj-m += proc_test1.o
-
- all:
- make -C /usr/src/linux-headers-2.6.38-8-generic M=`pwd` modules
-
- clean:
- make -C /usr/src/linux-headers-2.6.38-8-generic M=`pwd` clean
実行の効果を確認します.
次に、モジュールをロードした後にファイルノードをリストします.
- root@iscsia:~/proc_test# ll /proc/pt/
- total 0
- -rw-rw-rw- 1 root root 0 2011-07-01 15:04 pt_entry1
次はファイル読み込みノード/proc/pt/pt_entry1
- root@iscsia:~/proc_test# cat /proc/pt/pt_entry1
- root@iscsia:~/proc_test#
コールバック関数がNULLに設定されているので、何の結果もありません.
書き込みファイルノード/proc/pt/pt_entry1
- root@iscsia:~/proc_test# echo "hello,entry" > /proc/pt/pt_entry1
- -bash: echo: write error: Input/output error
書くのはあまり理想的ではないようですが、新聞を間違えました.pt_entry 1はあまり協力していませんね.そうですね.前はNULLに設定されていますから、人のせいにするわけにはいきません.ははは.次回は、自分の読み書き操作の仕方をご紹介します.