DOS Extender を使用して、FreeDOS 用のプロテクト モード アプリケーションを開発しています。私のアプリケーションは集中的な I/O を行います。
すべての DOS エクステンダーは Ring3 (つまり CPL=3) でアプリケーションを実行し、Ring 0 (つまり CPL=0) で実行するため、I/O 保護に関するいくつかの疑問が頭に浮かびます。
x86 ドキュメントから、次の情報を取得します。
IOPL センシティブな命令: IN、INS、OUT、OUTS、CLI、および STI。
CPL <= IOPL の場合、例外は生成されず、IOPL センシティブ命令が実行されます。
CPL > IOPL であり、命令がこれらの命令 (IN、OUT、INS、または OUTS) のいずれかである場合、プロセッサは現在のタスクの IO 許可ビット マップ (TSS 内) をチェックして、現在のアプリケーションがそのタスクへのアクセスを許可されているかどうかを判断します。アドレス指定された IO ポート。タスクが指定された IO ポートへのアクセスを許可されていることをビットマップが示している場合、例外は生成されず、IO 命令が実行されます。それ以外の場合は、GP 例外が生成されます。
CPL > IOPL で、命令が CLI または STI の場合、プロセッサは GP 例外を生成します。
これは、アプリの場合を意味します。リング 3 で実行され、IN、OUT、INS、OUTS 命令を実行するには、CPL <= IOPL (この場合、これは IOPL=3 に変換されます)、または CPL > IOPL (これは IOPL <= 2 に変換されます) のいずれかでなければなりません。 、つまり IOPL = 0。通常、Ring1 と Ring2 は使用されません。) I/O パーミッション ビットマップは、(アプリの起動中に) DOS Extender によって設定する必要があります。すべてのI/O ポートにアクセスできます。
しかし後者の場合、Ring3 アプリケーションからの CLI および STI 命令は、CPL > IOPL として使用できません。
したがって、次の命令は CPL <= IOPL の場合にのみ実行できることがわかります: IN、INS、OUT、OUTS、CLI、および STI 。この場合、これは 3 <= IOPL、つまり IOPL = 3 に変換されます。
ここで私の質問は、すべての dos エクステンダーが、開始するタスク/アプリケーションの TSS で IOPL = 3 を設定するかどうかです。
そうでない場合は、Ring0 (CPL=0) でタスク/アプリケーションを実行する必要があります。そうしないと、アプリケーションは IOPL に依存する命令を実行できません。
ドキュメントには、次のようにも記載されています。
プログラムまたはタスクは、POPF および IRET 命令でのみ IOPL を変更できます。ただし、そのような変更には特権があります。特権レベル 0、つまり CPL=0 で実行されていない限り、現在の IOPL を変更する手順はありません。権限の低い手順で IOPL を変更しようとしても、例外は発生しません。IOPL は変更されません。
つまり、Ring 3 コードで POPF または IRET 命令が検出された場合、IOPL フィールドは変更/復元されず、CPU によって例外は生成されません。
IOPL フィールドを変更したくなく、DOS Extender で処理できるようにするため、これで問題ありません。しかし、それは他のフラグ( EFLAGS reg.のbit0からbit11まで)が復元されるということですか?
私のアプリ。POPF 命令と IRET も実行する必要があるかもしれません。
ドキュメントには次のようにも記載されています。
プロシージャは、CPL <= IOPL の場合にのみ、POPF 命令を使用して IF フラグの設定を変更できます。権限の低いプロシージャが IF フラグを変更しようとしても、例外は発生しません。IF フラグは変更されません。
つまり、Ring3 コードで POF 命令が検出された場合、CPL <= IOPL、つまり 3 <= IOPL または IOPL = 3 の場合にのみ IF フラグが変更されます。ここでも、IOPL を 3 にする必要があります。:)
私は一般的な回答を求めています-つまり、DOSエクステンダー固有ではありません。これはbecozです。実装は異なりますが、基本原則はb / w DOSエクステンダーと同じままです。たとえば、Ring3でアプリケーションを実行します。