I have run into an issue that I cannot figure out and I have been fighting for about a week now. It's time to ask for a push in the right direction.
From what I can tell from Bochs and QEMU, it appears that addresses are being sign-extended from bit 31, rather than from bit 47. My final GDT is located at address 0xc0102000. I would expect that canonical address to be 0x00000000_c0102000. However, Bochs and QEMU both report it as 0xffffffff_c0102000.
The following is the log from Bochs:
Code: Select all
00018229330i[BIOS ] Booting from 07c0:0000
00089457289e[CPU0 ] interrupt(long mode): vector must be within IDT table limits, IDT.limit = 0x0
00089457289e[CPU0 ] interrupt(long mode): vector must be within IDT table limits, IDT.limit = 0x0
00089457289i[CPU0 ] CPU is in long mode (active)
00089457289i[CPU0 ] CS.mode = 64 bit
00089457289i[CPU0 ] SS.mode = 64 bit
00089457289i[CPU0 ] EFER = 0x00000500
00089457289i[CPU0 ] | RAX=00000000c0101000 RBX=00000000000b8000
00089457289i[CPU0 ] | RCX=00000000e0000011 RDX=0000000000000000
00089457289i[CPU0 ] | RSP=00000000c0103000 RBP=0000000000000000
00089457289i[CPU0 ] | RSI=0000000000000000 RDI=0000000000007000
00089457289i[CPU0 ] | R8=0000000000000000 R9=0000000000000000
00089457289i[CPU0 ] | R10=0000000000000000 R11=0000000000000000
00089457289i[CPU0 ] | R12=0000000000000000 R13=0000000000000000
00089457289i[CPU0 ] | R14=0000000000000000 R15=0000000000000000
00089457289i[CPU0 ] | IOPL=0 ID vip vif ac vm RF nt of df if tf sf ZF af PF cf
00089457289i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00089457289i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 00000fff 1 0
00089457289i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 00000fff 1 0
00089457289i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 00000fff 1 0
00089457289i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 00000fff 1 0
00089457289i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 00000fff 1 0
00089457289i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 00000fff 1 0
00089457289i[CPU0 ] | MSR_FS_BASE:0000000000000000
00089457289i[CPU0 ] | MSR_GS_BASE:0000000000000000
00089457289i[CPU0 ] | RIP=00000000c010100b (00000000c010100b)
00089457289i[CPU0 ] | CR0=0xe0000011 CR2=0xffffffffc0102002
00089457289i[CPU0 ] | CR3=0x00001000 CR4=0x00000020
(0).[89457289] [0x00000010100b] 0008:00000000c010100b (unk. ctxt): lgdt ds:0xffffffffc0102000 ; 0f011425002010c0
00089457289e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00089457289i[SYS ] bx_pc_system_c::Reset(HARDWARE) called
I found a similar issue with the jump from compatibility mode to full long mode and I overcame the issue with the following code:
Code: Select all
xor rax,rax
lea eax,[StartHigherHalf]
push rax
ret
NOTE: The code says higher-half, but it is not really higher half -- I know there is a discrepancy and I don't believe it is relevant to my question. But I want to call it out anyway.
On one hand, I have been staring at my GDT descriptors for a while thinking that something in there is my problem. I'm losing confidence that that is really where my issue lies. I also wonder if I managed to get a flag wrong in a control register.
In short, can someone please shove me in the right direction to look in order to get the sign extension from bit 47 rather than at 31? Please let me know if there is anything in particular you would like to see.
Thanks if advance for the assistance!