CPUがユーザー モードからカーネル モードに切り替わります: 正確には何をしますか? この移行はどのように行われますか?
編集:
アーキテクチャに依存する場合でも、答えを教えてください。アーキテクチャはあなた次第です。あなたが知っている建築を教えてください。
私は、すべてのものがそれに関与することについて考えたいと思っています。
CPUがユーザー モードからカーネル モードに切り替わります: 正確には何をしますか? この移行はどのように行われますか?
編集:
アーキテクチャに依存する場合でも、答えを教えてください。アーキテクチャはあなた次第です。あなたが知っている建築を教えてください。
私は、すべてのものがそれに関与することについて考えたいと思っています。
注: これは主に x86 アーキテクチャに関連しています。ここでは、やや単純化した説明を示します。
通常、移行は次のいずれかによって発生します。
通常、システムは割り込み記述子テーブル (IDT) をチェックします。各例外 (割り込み、障害など) には、このテーブルにインデックスを付けるために使用される番号が関連付けられています。
このテーブルから、CPU は実行する割り込みハンドラを決定できます。
移行の一環として、次の変更が (一般的に) 有効になります。
これで、カーネル モードになりました。
それが役立つことを願っています:)
これはシステムに依存しますが、通常のメカニズムでは、ユーザーランド操作によってソフトウェア割り込みが発生します。その割り込みにより、プロセッサはモードを切り替えてカーネルコードにジャンプし、プログラムが何をしようとしていたか (システムコール?) をチェックし、要求されたアクションを実行してユーザーモードコードに戻ります。ソフトウェア割り込み以外のメカニズムも遷移を引き起こす可能性があります。たとえば、プリエンプティブ マルチタスク システムでは、タイマー割り込みがスケジューラの実行をトリガーする場合があります。
私の理解では、セグメント レジスタの 2 つの LSB がゼロのプログラムはカーネル モードで実行され、セグメント レジスタの 2 つの LSB が 1 のプログラムはユーザー モードで実行されます。実際、セグメント rgeisters の 2 つの LSB が特権レベルを定義します (最高 0 から最低 3 まで)。
したがって、プログラムをカーネル モードで実行するには、セグメント レジスタを 16 進数の 0010 に設定する必要があります (私は信じています)。他の何かを上書きせずにそのメモリ空間にプログラムを配置する方法がわかりません-つまり、リンカはどのようにしてそれを保証しますか? また、ユーザー モードのコードからカーネル モードのコードを呼び出したい場合は、パラメーターを渡す方法を理解する必要があります。これらは同じメモリ ソースを使用していないため、メモリ参照によってデータを渡すことはできません。レジスターで渡す必要があると思います。
上記のギャップを埋めることができる人がいれば、とても感謝しています。
Windows では、システムコールを行うと、ライブラリ ルーチンがオペレーティング システムのアドレス空間にあるカーネル エントリポイントを呼び出します。次に、 sysenterなどのこの目的に固有の命令を実行することにより、CPU をスーパーバイザー モードにします。それが行うことは、基本的にフラグレジスタにビットを設定することです。これにより、OS は特権命令を使用できるようになります。