リスト7.6のコードの内容について
hnanabe opened this issue · 1 comments
p.167の以下のコードについて質問です。
main.cpp
SetIDTEntry(idt[InterruptVector::kXHCI], MakeIDTAttr(DescriptorType::kInterruptGate, 0),
reinterpret_cast<uint64_t>(IntHandlerXHCI), cs);
上記コードを周辺のコードを読んだうえで以下のように理解しました。まずこちらの理解はあっていますでしょうか?
第1引数:割り込みベクタ、ここではxHCIの割り込みベクタを0x40で定義し、その値をいれる
第2引数:MakeIDTAttr()を利用して作成したAttribute
第3引数:xHCIの割り込みハンドラを64bit整数に変換した値(つまりxHCI用割り込みハンドラのオフセット)
第4引数:セグメントセレクタの値(直前にGetCS()を利用して取得した値)
→この関数でもってidt[0x40]に割り込み記述子の内容(オフセット、Attribute, セグメントセレクタの値)を登録する
疑問点:
①main.cppで示したSetIDTEntryの第3引数においてIntHandlerXHCIの何を64bit整数にキャストしたのか?
②GetCS()の実装はどこで行なっているのか?
③オフセットとセグメントセレクタの違いがわからない。セグメントセレクタがコード実行時のメモリ上での割り込みハンドラの位置を指していて、オフセットはコードを実行していないときの割り込みハンドラの位置?
以上です。初歩的な質問とは思いますが、ご回答をお願いいたします。
お書きになっている「理解」はおおむね正しいように思います。
疑問への回答です。
①main.cppで示したSetIDTEntryの第3引数においてIntHandlerXHCIの何を64bit整数にキャストしたのか?
reinterpret_cast<uint64_t>(IntHandlerXHCI)
は、関数 IntHandlerXHCI
の先頭アドレスを整数にキャストしています。メモリ上で、この関数が置かれている番地を取得できます。
②GetCS()の実装はどこで行なっているのか?
③オフセットとセグメントセレクタの違いがわからない。セグメントセレクタがコード実行時のメモリ上での割り込みハンドラの位置を指していて、オフセットはコードを実行していないときの割り込みハンドラの位置?
今回話題となっているCS(コードセグメントセレクタ)では、セグメントセレクタは単なる番号で、メモリ上の位置については何も意味していません。オフセットこそが、メモリ上でのハンドラの位置を示しています。
ここでの「オフセット」は、オフセットという名前ではあるものの、メモリアドレスそのものを意味するのです。なぜなら、x86-64の64ビットモードにおいては、CSのベースアドレスは0に固定だからです。オフセット=メモリ0番地からのオフセット=メモリアドレス、ということです。