2012-08-10 12 views
6

私はLinuxカーネルについて学んでいますが、私はLinuxでユーザーモードからカーネルモードに切り替える方法を理解していません。それがどのように働きますか? あなたは私にいくつかの助言を与えることができますか、またはこれについてのいくつかの本を参照するためのリンクを私に教えてください? ありがとう!ユーザーモードからカーネルモードに切り替える方法は?

+0

あなたの質問の文脈は何ですか?特定のCPUまたは一般的なCPUメカニズムについて質問していますか?あなたが解決しようとしている問題はありますか? –

答えて

11

ユーザスペースアプリケーションが明示的に通常動作時にカーネルモードへの切り替えを開始することができる唯一の方法は、openreadなどのシステムコールを行うことであり、write

ユーザアプリケーションは、これらのシステムコールAPIを呼び出すたびに適切なパラメータでソフトウェア割り込み/例外(SWI)がトリガされます。

このSWIの結果として、コード実行の制御は、OSによって提供される割り込みベクタテーブル[IVT]の事前定義された場所にユーザアプリケーションからジャンプします。

このIVTには、ユーザーアプリケーションをカーネルモードに切り替えてユーザープロセスに代わってカーネル命令を実行するために必要なすべての必要な手順を実行するSWI例外ハンドラルーチンのアドレスが含まれています。

+2

x86では、ユーザーモードで発生した例外はすべて、カーネルモードでOSの適切な例外ハンドラに制御を移します。 –

+0

真。答えを投稿するとすぐに、ユーザーのアプリケーションが明示的にカーネルモードに切り替えることを望んでいることを反映して編集したかったのです。しかし、私はネットワーク問題のためにそうするように苦労しました。これを反映するように編集しました。 –

+0

@AmarnathRevanna OSは、SWIをサービスするときにカーネルモードに切り替わったことをOSはどのようにして知っていますか?スーパバイザ(リング0)/ユーザ(リング3)にモードを追跡し、SWIで更新される特定のハードウェアレジスタ/ビットはありますか?基本的には、ハードウェアレベルでのカーネルモードへの切り替えをアサートします。 – Shyam

0

私はこれを読んだだけで、かなり良いリソースです。ユーザーモードとカーネルモード、変更が起こる理由、高価であること、そして興味深い関連する読書について説明します。

http://www.codinghorror.com/blog/2008/01/understanding-user-and-kernel-mode.html

ここでの短い抜粋です:カーネルモードで

カーネルモード

は、実行中のコードは、基盤となるハードウェアへの完全かつ無制限のアクセスを持っています。任意のCPU命令を実行し、任意のメモリアドレスを参照することができます。カーネルモードは、通常、オペレーティングシステムの最も低レベルの、最も信頼できる機能用に予約されています。カーネルモードのクラッシュは致命的です。彼らはPC全体を停止させます。ユーザモードで

ユーザモード

、実行中のコードは、直接ハードウェアまたは基準メモリにアクセスする能力がありません。ユーザーモードで実行されるコードは、ハードウェアまたはメモリにアクセスするためにシステムAPIに委任する必要があります。このような分離によって保護されるため、ユーザーモードでのクラッシュは常に回復可能です。お使いのコンピュータで実行されているほとんどのコードは、ユーザーモードで実行されます。

1

ユーザモードからカーネルモードに切り替えるには、システムコールを実行する必要があります。

フードの中で何が起こっているのかを見たい場合は、TLDP is your new friendに行き、コードを参照してください(アセンブリコードを理解するには詳しい知識は必要ありません)。

あなたが興味を持っている:あなたが見ることができるように

movl $len,%edx   # third argument: message length 
    movl $msg,%ecx   # second argument: pointer to message to write 
    movl $1,%ebx    # first argument: file handle (stdout) 
    movl $4,%eax    # system call number (sys_write) 
    int  $0x80    # call kernel 

、システムコールは、このシステムコールのハンドラ中断を行いアセンブリコード、(0x80の)周囲および結果として単なるラッパーであります呼び出されます。

ちょっと騙して、ここでCプリプロセッサを使って実行可能ファイル(foo。S)を使用すると、下のリンクからコードを入れたファイルです:straceの経由

gcc -o foo -nostdlib foo.S 

は、ファイル名を指定して実行、それを私たちが書くものを手に入れるだろうことを保証するために:

$ strace -t ./foo 
09:38:28 execve("./foo", ["./foo"], 0x7ffeb5b771d8 /* 57 vars */) = 0 
09:38:28 stat(NULL, Hello, world! 
NULL)    = 14 
09:38:28 write(0, NULL, 14)  
関連する問題