2013-05-24 15 views
6

read()システムコールを使用してHDDにアクセスするなど、ユーザ空間で許可されない機能へのアクセスを提供するシステムコールが存在することを理解しています。また、これらは、ハードウェア間の互換性を提供するために、fread()などのライブラリ呼び出しの形式でユーザーモードレイヤーによって抽象化されていることも理解しています。Linuxシステムコールとカーネルモード

したがって、アプリケーション開発者の観点からは、何かが好きです。

//library //syscall //k_driver //device_driver 
fread() -> read() -> k_read() -> d_read() 

私の質問は、 fread()read()のすべての命令をインライン展開するのを私のプログラムに直接止めるのは何ですか?命令は同じなので、CPUは同じように動作するはずです。私はそれを試していないが、私は何か理由でこれが動作しないと仮定します。さもなければ、任意のアプリケーションが任意のカーネルモード操作を得ることができます012:DR:システムコールがアプリケーションによってコピーできないカーネルモードを「入力」できるようにするものは何ですか?

答えて

8

システムコールはカーネル自体には入力しません。より正確には、例えば、あなたが呼び出すread関数は、アプリケーションに関する限り、ライブラリ呼び出しです。 read(2)が内部的に中断を使用して実際のシステムコールを呼び出しているか、またはsyscall(2)アセンブリ命令がCPUアーキテクチャとOSによって異なります。

これは、ユーザランドコードが実行される特権コードを持つ唯一の方法ですが、間接的な方法です。ユーザーランドとカーネルコードは異なるコンテキストで実行されます。

つまり、カーネルソースコードをユーザーランドコードに追加することはできず、何か便利な操作を行うと予想されますが、クラッシュする可能性があります。特に、カーネルコードは、ハードウェアと対話するために必要な物理メモリアドレスにアクセスできます。ユーザーランドコードは、この機能を持たない仮想メモリ空​​間にアクセスするために制限されています。また、ユーザランドコードの実行が許可される命令は、CPUがサポートする命令のサブセットです。いくつかのI/O、中断、および仮想化関連の命令は、禁止されたコードの例です。これらは特権命令として知られており、CPUアーキテクチャに応じてリングモードまたはスーパバイザモードを使用する必要があります。

+0

ああ、それは、メモリマッピング、興味深いです。感謝して、何かに読んでください。 – lynks

+0

ユーザーモード(回答が更新されたとき)で禁止される特権命令はもちろん。 – jlliagre

+0

まあ、私はまだスイッチがどのように起こっているのかはっきりしていませんし、手動で 'スイッチ命令'を実行できない理由は:<*switch*> 'シェルコード、なぜカーネルモードの実行を得られないのですか? – lynks

0

あなたはそれらをインライン化することができます。 syscall(2)から直接システムコールを発行することはできますが、すぐにそれは乱雑になります。システムコールのオーバヘッド(前後のコンテキストスイッチ、カーネルチェック、...)は、システムコール自体にかかる時間はもちろんのこと、ノイズにインライン展開することで利益を上げています(ゲインがあれば、より多くのコードは、キャッシュがそれほど有用ではなく、パフォーマンスが低下することを意味します)。本当に測定可能な利得であれば、libc/kernelの人々が問題を研究し、あなたの背後にあるインライン化を(関連する*.hファイルで)実行していることを信頼してください。

+1

私は 'read()'の内容をインライン展開することを意味していますが、これはうまくいきません。そうでなければ、私のプログラムがリング0に入り、いくつかのマルウェアに分岐します。 – lynks

関連する問題