プロセスがカーネルモードまたはユーザーモードにあることを決定する責任は誰にありますか?カーネルはどのプロセスがどのスペースに属しているかを知っていますが、CPUはそれをどのように決定しますか?つまり、CPUはプロセスのモードまたはステートメントの実行を認識している必要がありますか?はいの場合、どのように?そうでない場合、ユーザーが禁止されていることをしたい場合はどうなりますか?ユーザーアプリケーションがマシンリソースのサブセットしか見ることができないと言うとき、それはアプリケーションがたとえばCPUで特定のタスクを実行できないことを意味しますが、誰がそのようなことを行うためにアプリケーションを停止し、さらに重要なのはどのようにですか?
うーん、かなり興味深い質問です。私は助けようとします...
プロセスがカーネルモードまたはユーザーモードにあることを決定する責任は誰にありますか?
OSの設計者はそれを決定します:-)。最新のOSはすべて、すべてのプロセスをユーザーモード(x86アーキテクチャの「保護モード」の「リング3」)で実行します。これは、メモリ保護や仮想メモリなどの機能を使用するために必要だからです。古いOSや単純なOSは、すべてのプロセスをカーネルモード(x86の「リアルモード」など)で実行する場合があります。これはOSの設計によって異なります。たとえば、MS-DOSはこのように機能しました。
プロセッサモードの実際の名前とタイプは、アーキテクチャ(x86、Sparc、PowerPC ...)によって異なることに注意してください。ただし、最近のすべてのプロセッサには、「ユーザー」モードと呼ばれる可能性のある同様の「保護」モードがあります。
カーネルはどのプロセスがどのスペースに属しているかを知っていますが、CPUはそれをどのように決定しますか?
CPUはプロセスについて何も知らないため、CPUはそれを「認識」しません。これらはOSによって提供される抽象化です。 CPUは、供給されたコードを実行するだけです。 CPUには異なるモードを切り替える命令があり、OSはこれらの命令を使用して、必要に応じてCPUを適切なモードにします。
たとえば、x86では、コンピュータは「リアルモード」で起動します(互換性の理由から)。 LinuxやWindows(NT以降)などのOSが起動すると、最初に行うことの1つは、「保護モード」に切り替えることです。次に、「リング」機能を使用して、すべてのプログラムのハードウェアへのアクセスを制御します。 OSカーネルはリング0(完全な特権)で実行されます。ユーザーソフトウェアはリング3(制限付き)で実行されます。 OSがユーザーソフトウェアに制御を渡すとき(つまり、ユーザープロセスを開始または再開するとき)は常に、最初にリング3に切り替わります。次に、制御がカーネルに戻り、CPUはリング0に戻ります。
モード/リング間の切り替えがどの程度正確に機能するかは、CPUアーキテクチャによって異なります。ほとんどのアーキテクチャは、スイッチングのための特別な命令またはメカニズムを提供します。 CPUが特定のモード/リングに切り替えられると、CPUはそれ自体でそのモード(および関連する制限)を追跡します。
これがx86アーキテクチャでどのように機能するかについての詳細は、次の記事を参照してください。 http://duartes.org/gustavo/blog/post/cpu-rings-privilege-and-protection
余談ですが、制限付きCPUモードでの保護/制限は、ほとんどの場合、CPUの メモリ管理ユニット によって実装されます。古いプロセッサや単純なプロセッサ(AmigaやAtariSTで使用されているMotorola68000やC64の6510など)にはMMUがありません。したがって、カーネルモードとユーザーモードを区別するOSを実行することはできません。そのため、たとえばLinux m68kポートを実行するには、少なくともMotorola68020プロセッサが必要です。以前の68000および68010にはMMUがありません。
つまり、CPUはプロセスのモードまたはステートメントの実行を認識している必要がありますか?はいの場合、どのように?
はい、CPUは、現在どのモードで実行されているかを認識しているという意味でそれを認識しています(理由はわかりませんが)。
そうでない場合、ユーザーが禁止されていることをしたい場合はどうなりますか?ユーザーアプリケーションがマシンリソースのサブセットしか見ることができないと言うとき、それはアプリケーションがたとえばCPUで特定のタスクを実行できないことを意味しますが、誰がそのようなことを行うためにアプリケーションを停止し、さらに重要なのはどのようにですか?
とても良い質問です。 CPU自体がアプリケーションを停止します。
コード(アプリケーション)が制限された特権を持つモード(x86のプロテクトモードのリング3など)で実行されている場合、コードが実行できないことがあります(割り当てられた領域外のメモリにアクセスするなど)。 CPUはこれを認識しており、実行する前にすべての命令で違反の可能性をチェックします。違反が検出されると、CPUは問題のあるコードの実行を停止し(これは「例外」またはハードウェア割り込みと呼ばれます)、特別なエラー処理コード(OSによって事前に設定されたもの)にジャンプします。
これにより、制御が効果的にOSに戻され、適切と思われる場合に実行できます。例外がディスクにスワップアウトされたメモリへのアクセスによるものである場合は、ディスクからメモリをフェッチし(これが「ページング」の仕組みです)、プロセスを終了します。不正にメモリにアクセスした(恐ろしい「保護違反」または「セグメンテーション違反」)など。
カーネルモードとユーザーモードは、CPUの異なるセキュリティモードです。多くの場合、CPUは、OSレベルで実装されるこれら2つのモードよりも多くを提供します。
詳細については、を参照してください。
そして
あなたの質問に対する基本的な答えは、「割り込みが発生すると、CPUはカーネルモードに切り替わります。」です。 OS自体が設定しているので、ブートプロセスでは、割り込みのベクトル(ハンドラー)が、これらすべてがカーネルを指しています。プロセスによって行われるすべてのシステムコールは、(ソフトウェア)割り込みに他なりません。つまり、カーネル自体(レジスタで指定されたパラメータを使用)に他ならない割り込みハンドラを呼び出すことを意味します。
カーネルは、ユーザープロセスに制御を与える前に、しばらくして割り込みを生成するようにタイマーを設定し、プロセッサをユーザーモードに設定してから、ユーザープロセスに制御を与えます。しばらくすると、タイマーが割り込みを生成し、制御がカーネルに戻ります。
もちろん、タイマーで遊んだり、割り込みベクトル(ハンドラー)で遊んだり、CPUモードで遊んだりすることはすべて特権命令であり、カーネルモードプロセス(つまりカーネル自体)に許可されています。