2017-09-27 4 views
5

ユーザーコードがシステムコードを呼び出す私の趣味のx86_64 UEFIカーネルのポイントに達しましたが、0x1B:0x0(0x1Bはユーザーモードのコードセグメントセレクター)でエラーコード0の一般保護違反を生成します。私はSYSRETがRCXに保持されているアドレスに戻らず、代わりにゼロに戻ることを理解しました。私はqemu-system-x86_64をKVMの有無にかかわらずデバッグします。この現象について2つのスクリーンショットを添付しました。誰もこれを説明して、何が間違っているのか教えてもらえますか?なぜRCXが正しいリターンアドレスを保持しているときにSYSRETはアドレス0に戻りますか?

MSR 0xC0000080 = 0x0000000000000501 
MSR 0xC0000081 = 0x001B00083D906D79 
MSR 0xC0000082 = 0x000000003D906D79 
MSR 0xC0000083 = 0x000000003D906D79 
MSR 0xC0000084 = 0x0000000000000300 

cliとローカルAPICの両方のエントリを使用して割り込みを無効にします。

Before the deadly step

After

GDT:

{ 0, 0, 0, 0x9A, 0x20, 0 }; // 0x08 ring 0 code 
{ 0, 0, 0, 0x92, 0x00, 0 }; // 0x10 ring 0 data 
{ 0, 0, 0, 0xFA, 0x20, 0 }; // 0x1B ring 3 code 
{ 0, 0, 0, 0xF2, 0x00, 0 }; // 0x23 ring 3 data 
{ 0, 0, 0, 0xFA, 0x20, 0 }; // 0x2B ring 3 code 
{ 0, 0, 0, 0xF2, 0x00, 0 }; // 0x33 ring 3 data 

typedef struct PACKED ENTRY 
{ 
    U16 limit_0_15; 
    U16 base_0_15; 
    U8 base_16_23; 
    U8 access; 
    U8 granularity; 
    U8 base_24_31; 
} ENTRY, *PENTRY; 

EDIT:もう一度、取扱説明書を読んだ後、私は、ロングモードでの復帰は、CSが(STAR.SYSRET_CS + 16)になることに気づきました| 3ので、私はユーザーモードのセグメント記述子を複製しただけですが、結果は同じです。

+0

解決策はありますか?私は同じ問題に直面しています。 –

+0

私は今のところ割り込みを使用しています。 – YaniMan

答えて

0

SYSEXITでは、RCX ==リターンRSPとRDX ==リターンRIP。インテルの命令セットのリファレンスを参照してください。

+0

[Intelのマニュアル]に書かれているように(https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction- set-reference-manual-325383.pdf)4-668 Vol。 2B RCX < - RIP。 RDXとRSPは言及されていません。 – YaniMan

関連する問題