uchan-nos/os-from-zero

リスト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()の実装はどこで行なっているのか?

https://github.com/uchan-nos/mikanos/blob/b5f7740c04002e67a95af16a5c6e073b664bf3f5/kernel/asmfunc.asm#L22 にあります。

③オフセットとセグメントセレクタの違いがわからない。セグメントセレクタがコード実行時のメモリ上での割り込みハンドラの位置を指していて、オフセットはコードを実行していないときの割り込みハンドラの位置?

今回話題となっているCS(コードセグメントセレクタ)では、セグメントセレクタは単なる番号で、メモリ上の位置については何も意味していません。オフセットこそが、メモリ上でのハンドラの位置を示しています。

ここでの「オフセット」は、オフセットという名前ではあるものの、メモリアドレスそのものを意味するのです。なぜなら、x86-64の64ビットモードにおいては、CSのベースアドレスは0に固定だからです。オフセット=メモリ0番地からのオフセット=メモリアドレス、ということです。