ikemonn's blog

技術ネタをちょこちょこと

はじめて読む486 6章

保護機能

  • プロテクトモードでは下記のチェックをCPU内部で行っている

    • セグメントの属性
    • セグメントリミット
    • 特権レベル
    • タスク
  • セグメントリミット

    • アクセスしようとするメモリのオフセットアドレスがリミット値を超えていないかをチェックする
  • セグメントの属性

    • TYPE: セグメントの種類
    • S: セグメントの場合は1
    • DPL: セグメントの特権レベル
    • P: セグメントが存在するか(1→物理メモリに存在、0→物理メモリに存在しない)
    • A: セグメントがアクセスされた(アクセスされると1をセットし、アクセスされているかを定期的にチェックする)
  • 特権レベル

  • DPL

    • Descriptor Privilege Level
    • セグメントの特権レベル
  • CPL

    • Current Privilege Level
    • プログラム実行中の動作レベル
    • CPLはプログラムの置かれているセグメントの特権レベルで決まる
    • 動作レベルを変更するためには異なるセグメントにジャンプしなければならない
  • 特権命令

    • 特権レベル0の動作レベルでのみ実行可能なマシン語は下記
      • MOV CR0, レジスタ CR0にレジスタの値をロードする
      • LGDT メモリ GDTRにメモリの値をロードする
      • LIDT メモリ IDTRにメモリの値をロードする
      • LLDT メモリorレジスタ LDTRにメモリまたはレジスタの値をロードする
      • LTR メモリorレジスタ TRにメモリまたはレジスタの値をロードする
      • HLT CPUの動作を停止する
  • 特権レベルとセグメントのリード/ライト

    • 動作レベル(CPL)より低い特権レベルのセグメントは読み書きできる
    • セグメントアクセスのチェックはセグメントレジスタセレクタ値をロードする瞬間に行われる
    • セグメントレジスタにロードしようとしたセレクタ値の指すセグメントの特権レベルが動作レベルよりも高い場合はフォールトを発生させる
  • IOPL

    • I/Oポートの特権レベル(I/O Privilege Level)
    • I/OポートにはディスクリプタがないのでDPLを持たないが、特権レベルを設定することができる
    • CPU内のEFLAGSレジスタの中のIOPLフィールドに設定する
    • CPL = 0のとき、IOPLを設定することができる

ゲート

  • 実行するコードセグメントを変更するには、セグメント間JMP命令やCALL命令を実行する

    • この際、異なる特権レベルを持つコードセグメントを直接呼び出せない
    • 唯一許されているのは、特権レベルの低いコードセグメントから高いものをコールゲートを介して呼び出すこと
  • コールゲート

    • 486に組み込まれた動作レベル移行のためのしくみ
    • 典型的な用途はOSの呼び出し口
      • アプリケーションがコールゲートを呼び出すことでOSが呼び出される

ゲートディスクリプタとゲートの呼び出し方法

  • コールゲートはゲートと呼ばれるシステムオブジェクトの一種
  • ゲートディスクリプタもセグメントと同様に動作レベル(DPL)を設定しておく場所がある
    • ゲートを呼び出す命令を実行する時に、動作レベルと(CPL)とゲートの特権レベルが比較される
    • 動作レベルがゲートの特権レベル以上だと実行できる
    • ポイントは、動作レベルがゲートの特権レベル以上であれば、ゲートが指すどんな特権をもつコードセグメントも実行できるということ