47

私はインテルプロテクトモードを勉強しています。コールゲート、割り込みゲート、トラップゲートはほぼ同じであることがわかりました。実際、Call Gateにはパラメーターcounterのフィールドがあり、これら3つのゲートには異なるタイプのフィールドがあることを除けば、他のすべてのフィールドで同じです。

それらの機能に関しては、それらはすべて、コード制御をいくつかのコードセグメント内のいくつかのプロシージャに転送するために使用されます。

これらの3つのゲートにはすべて、特権の境界を越えた呼び出しに必要な情報が含まれているので、疑問に思います。なぜ3種類必要なのですか?1だけで十分ではありませんか?

お手数をおかけしますが、よろしくお願いいたします。

アップデート1

関連する質問:割り込みゲートまたはトラップゲートをいつ使用するか?

アップデート2

今日私はこの考えを思いついた:

さまざまな目的、さまざまなゲート、さまざまなCPU動作の詳細が実行されます。IFフラグ処理など。

4

3 に答える 3

67

ゲート(呼び出し、割り込み、タスク、またはトラップ)は、セグメント間で実行の制御を移すために使用されます。特権レベルのチェックは、宛先のタイプと使用される命令に応じて異なる方法で実行されます。

コールゲートはCALLおよびJMP命令を使用します。コールゲートは、制御を低い特権コードから高い特権コードに移します。ゲートDPLは、どの特権レベルがゲートにアクセスできるかを決定するために使用されます。コールゲートは、より高速なSYSENTER / SYSEXITメカニズムを優先して、徐々に放棄されています(またはおそらく廃止されています)。

タスクゲートは、ハードウェアマルチタスクのサポートに使用されます。ハードウェアタスク切り替えは、自発的に発生するか(CALL / JMPからタスクゲート記述子へ)、またはNTフラグが設定されている場合は割り込みまたはIRETを介して発生します。割り込みゲートまたはトラップゲートでも同じように機能します。カーネルは通常、タスク切り替え時に追加の作業を行う必要があるため、私の知る限り、タスクゲートは使用されません。

割り込みおよびトラップゲートは、タスクゲートとともに、割り込み記述子テーブルとして知られています。これらは、ある特権スタックから別の特権スタックへのパラメーターの転送を除いて、コールゲートと同じように機能します。1つの違いは、割り込みゲートはEFLAGSのIFビットをクリアしますが、トラップゲートはクリアしないことです。これにより、ハードウェア割り込みを処理するのに理想的です。トラップは、ハードウェア支援仮想化で広く使用されています。

詳細については、関心のあるプロセッサに関するインテルアーキテクチャーのマニュアルを参照してください。

アップデート

コメントに答えるには:

割り込みとトラップを区別する理由はたくさんあります。1つはスコープの違いです。ユーザースペースでトラップが呼び出されている間、割り込みゲートはカーネルスペース(結局のところ、ハードウェアを管理するのはカーネルです)を指します。割り込みハンドラはハードウェアイベントに応答して呼び出され、トラップはCPU命令に応答して実行されます。

割り込みゲートとトラップゲートがEFLAGSを異なる方法で処理する理由をよりよく理解するための単純な(しかし非現実的な)例として、ユニプロセッサシステムでハードウェアイベントの割り込みハンドラを記述していて、IFビットをクリアできなかった場合にどうなるかを考えてみましょう。 1つを提供していた。最初のサービスで忙しい間に、2番目の割り込みが到着する可能性があります。次に、IH実行中のランダムな時点で、プロセッサによって割り込みハンドラが呼び出されます。これは、データの破損、デッドロック、またはその他の悪い魔法につながる可能性があります。実際には、割り込みの無効化は、一連のカーネルステートメントがクリティカルセクションのように扱われるようにするためのメカニズムの1つです。

ただし、上記の例では、マスク可能な割り込みを想定しています。とにかく、NMIを無視したくないでしょう。

今日もほとんど関係ありません。現在、高速割り込みハンドラーと低速割り込みハンドラーの区別はほとんどありません(「高速および低速ハンドラー」を検索)。割り込みハンドラーはネストされた方法で実行でき、SMPプロセッサでは、ローカル割り込みの無効化とスピンロックの結合が必須になります。

現在、トラップゲートは、ソフトウェア割り込み、例外などを処理するために実際に使用されています。プロセッサのページフォールトまたはゼロ除算例外は、おそらくトラップゲートを介して処理されます。トラップゲートを使用してプログラムの実行を制御する最も簡単な例は、デバッガーにブレークポイントを実装するために使用されるINT3命令です。仮想化を行うと、ハイパーバイザーはリング0で実行され、ゲストカーネルは通常リング1で実行されます。この場合、特権コードは一般的な例外エラーで失敗します。WitchelとRosenblumはバイナリ翻訳を開発しました、これは基本的に、その効果をシミュレートするために命令を書き直すことです。重要な命令が発見され、トラップに置き換えられます。次に、トラップが実行されると、VMM /ハイパーバイザーに制御が渡されます。VMM/ハイパーバイザーは、リング0の重要な命令をエミュレートします。

ハードウェア支援仮想化では、トラップアンドエミュレート技術の使用は多少制限されていますが(特に動的な場合は非常に高価であるため)、バイナリ変換の実践は依然として広く使用されています。

詳細については、以下を確認することをお勧めします。

お役に立てれば!

于 2010-08-06T15:40:40.763 に答える
27

建築とデザイン

保護の観点から、x86アーキテクチャは階層リングに基づいており、プロセッサによって提供されるすべての実行スペースが4つの階層保護ドメインに分割され、それぞれに独自のレベルの特権が割り当てられます。この設計では、ほとんどの場合、コードが最も特権の低いドメインで実行され、場合によってはより特権の高いセキュリティドメインからのサービスが要求され、このサービスがより特権の低いアクティビティをスタックにプリエンプトし、次のような方法で復元することを前提としています。特権の低いコードでは、プリエンプション全体が表示されなくなります。

階層的保護ドメインの設計では、異なるセキュリティドメイン間で制御を任意に渡すことはできないとされています。

ゲートは、特権の低いコードセグメントから特権の高いコードセグメントへの制御転送のためのx86アーキテクチャの機能ですが、その逆はありません。さらに、制御が渡される特権の低いセグメントのポイントは任意ですが、制御が渡される特権の高いセグメントのポイントは厳密に指定されます。特権の低いセグメントに渡される後方制御は、命令によってのみ許可されIRETます。これに関して、インテルソフトウェア開発者マニュアルは次のように主張しています。

低い特権セグメントのコードモジュールは、ゲートと呼ばれる厳密に制御および保護されたインターフェイスを使用して、高い特権セグメントで動作するモジュールにのみアクセスできます。保護ゲートを通過せず、十分なアクセス権を持たずに、より高い特権セグメントにアクセスしようとすると、一般保護例外(#GP)が生成されます。

つまり、ゲートは、必要なアクセス権とターゲットアドレスを備えた特権ドメインエントリポイントです。このように、すべてのゲートは類似しており、ほぼ同じ目的で使用され、すべてのゲート記述子には、プロセッサがアクセス権を制御するために使用するDPLフィールドが含まれています。ただし、プロセッサは、呼び出しのソースがソフトウェア、、、または命令である場合にのみゲートのDPLをチェックし、CALL呼び出しJMPINTソースがハードウェアである場合はこのチェックをバイパスすることに注意してください。

ゲートの種類

すべてのゲートが類似しているという事実にもかかわらず、元々Intelのエンジニアは異なるゲートが異なる目的に使用されると考えていたため、いくつかの違いがあります。

タスクゲート

タスクゲートはIDTとGDTにのみ保存でき、INT命令によって呼び出されます。非常に特殊なタイプのゲートで、他のゲートとは大きく異なります。

当初、Intelのエンジニアは、タスク切り替え用のCPUベースの機能を提供することで、マルチタスクに革命を起こすと考えていました。彼らは、タスクのレジスタ状態を保持し、ハードウェアタスク切り替えに使用できるTSS(タスク状態セグメント)を導入しました。ハードウェアタスク切り替えをトリガーする方法は2つあります。TSS自体を使用する方法と、タスクゲートを使用する方法です。ハードウェアタスクを切り替えるには、CALLまたはJMP命令を使用できます。JMP私が正しく理解していれば、タスクゲートが導入された主な理由は、TSSセレクターへのaによってハードウェアタスクスイッチをトリガーできないため、割り込みの到着に応答してハードウェアタスクスイッチをトリガーできるようにすることでした。

実際には、誰もそれを使用せず、ハードウェアコンテキストスイッチングも使用しません。実際には、この機能はパフォーマンスの観点から最適ではなく、使用するのに便利ではありません。たとえば、TSSはGDTにのみ格納でき、GDTの長さは8192を超えることはできないことを考慮すると、ハードウェアの観点からは8kを超えるタスクを持つことはできません。

トラップゲート

トラップゲートはIDTにのみ格納でき、INT命令によって呼び出されます。基本的なタイプのゲートと考えることができます。より特権のあるセグメントのトラップゲート記述子で指定された特定のアドレスに制御を渡すだけで、それ以上のことはありません。さまざまな目的で積極的に使用されるトラップゲート。これには次のものが含まれます。

  • システムコールの実装(たとえば、この目的でのLinuxの使用INT 0x80とWindowsの使用)INT 0x2E
  • 例外処理の実装(例外の場合に割り込みを無効にする理由はありません)。
  • APICを備えたマシンでの割り込み処理の実装(カーネルスタックをより適切に制御できます)。

割り込みゲート

割り込みゲートはIDTにのみ格納でき、INT命令によって呼び出すことができます。これはトラップゲートと同じですが、さらに割り込みゲート呼び出しは、EFLAGSレジスタのIFフラグを自動的にクリアすることにより、将来の割り込み受け入れをさらに禁止します。

特にPICベースのマシンでの割り込み処理の実装に積極的に使用される割り込みゲート。その理由は、スタックの深さを制御するための要件です。PICには、割り込みソースの優先順位機能はありません。これがデフォルトであるため、PICはプロセッサですでに処理中の割り込みのみを無効にします。ただし、別の割り込みが途中で到着し、割り込み処理をプリエンプトする可能性があります。したがって、カーネルスタックには同時に15個の割り込みハンドラが存在する可能性があります。その結果、カーネル開発者は、メモリペナルティにつながるカーネルスタックサイズを大幅に増やすか、散発的なカーネルスタックオーバーフローに直面する準備をすることを余儀なくされました。割り込みゲートは、同時に1つのハンドラーのみがカーネルスタックに存在できることを保証できます。

コールゲート

コールゲートはGDLとLDTに保存できCALLJMP命令によって呼び出されます。トラップゲートに似ていますが、さらに、ユーザーモードのタスクスタックからカーネルモードのタスクスタックに多数のパラメーターを渡すことができます。渡されるパラメーターの数は、コールゲート記述子で指定されます。

コールゲートは決して人気がありませんでした。その理由はいくつかあります。

  • それらはトラップゲート(オッカムの剃刀)に置き換えることができます。
  • 彼らはあまりポータブルではありません。他のプロセッサにはそのような機能がありません。つまり、システムコールのコールゲートのサポートは、オペレーティングシステムを移植するときに負担になります。これは、これらのコールを書き換える必要があるためです。
  • スタック間で渡すことができるパラメーターの量が制限されているため、柔軟性はあまり高くありません。
  • パフォーマンスの観点からは最適ではありません。

1990年代の終わりに、IntelとAMDは、システムコール用の追加の命令SYSENTER/ SYSEXIT(Intel)とSYSCALL/ SYSRET(AMD)を導入しました。コールゲートとは対照的に、新しい命令はパフォーマンス上の利点を提供し、採用されています。

概要

MichaelFoukarakisには同意しません。IF申し訳ありませんが、フラグに影響を与えることを除いて、割り込みとトラップの間に違いはありません。

  • 理論的には、各タイプのゲートは、任意のレベルの特権を持つセグメントを指すインターフェイスとして機能できます。実際には、使用中の最新のオペレーティングシステムでは、割り込みゲートとトラップゲートのみが使用されます。これは、IDTでシステムコール、割り込み、および例外処理に使用され、これらすべてがカーネルエントリポイントとして機能します。

  • 命令を使用して、ソフトウェアで任意のタイプのゲート(割り込み、トラップ、タスクを含む)を呼び出すことができますINT。特定のゲートへのユーザーモードコードアクセスを禁止できる唯一の機能はDPLです。たとえば、オペレーティングシステムがIDTを構築する場合、特定のゲートのタイプに関係なく、ハードウェアイベント処理に使用されるゲートのカーネルセットアップDPLは0になり、このゲートへのアクセスはカーネルスペースからのみ許可されます。 (ほとんどの特権ドメインで実行されます)が、システムコールのゲートを設定するときに、DPLを3に設定して、任意のコードからそのゲートにアクセスできるようにします。その結果、ユーザーモードタスクはDPL = 3のゲートを使用してシステムコールを行うことができますが、たとえば、キーボード割り込みハンドラーを呼び出そうとすると、一般保護違反が発生します。

  • IDTの任意のタイプのゲートは、ハードウェアによって呼び出すことができます。人々は、同期を実現したい場合にのみ、このハードウェアイベント処理に割り込みゲートを使用します。たとえば、カーネルスタックオーバーフローが不可能であることを確認します。たとえば、APICベースのシステムでのハードウェア割り込み処理のためのトラップゲートの使用に成功した経験があります。

  • 同様に、IDTの任意のタイプのゲートをソフトウェアで呼び出すことができます。システムコールと例外にトラップゲートを使用する理由は単純です。割り込みを無効にする理由はありません。割り込みを無効にすると、割り込み処理の待ち時間が長くなり、割り込みが失われる可能性が高くなるため、悪いことです。このため、深刻な理由がない限り、誰もそれらを無効にすることはできません。

  • 通常、厳密なリエントラントスタイルで記述された割り込みハンドラ。このように、割り込みハンドラーは通常、データを共有せず、相互に透過的にプリエンプトできます。割り込みハンドラー内のデータへの同時アクセスを相互に除外する必要がある場合でも、cliおよびsti命令を使用することにより、共有データへのアクセスのみを保護できます。割り込みハンドラ全体をクリティカルセクションと見なす理由はありません。PICベースのシステムでカーネルスタックオーバーフローが発生するのを防ぎたい場合を除いて、割り込みゲートを使用する理由はありません。

トラップゲートは、カーネルインターフェイスのデフォルトのソリューションです。重大な理由がある場合は、トラップゲートの代わりに割り込みゲートを使用できます。

于 2012-12-23T09:03:22.827 に答える
9

IFフラグが自動的にクリアされるため、割り込みゲートは特別です。コールゲートは、割り込みベクタを介してアクティブ化されないため、特別です。タスクゲートは、プロセッサの状態を自動的に保存するため、特別です。4つの名前を持つ4つの異なる動作が便利です。

于 2010-08-06T17:23:59.260 に答える