GDT Misconfigured?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
n0ax
Posts: 10
Joined: Thu May 01, 2014 11:43 pm

Re: GDT Misconfigured?

Post by n0ax »

Ok I went back to [org 0x00], but now I get another triple fault the same as before I changed org [0x00] to [0x1000], I feel as though my gdt is not aligned correctly still or for some reason an invalid address is being passed, any ideas?

Code: Select all

(0).[14260274] [0x000000010048] 1000:0000000000000048 (unk. ctxt): jmp far 0008:004d         ; ea4d000800
00014260274i[MEM0 ] allocate_block: block=0xd used 0x3 of 0x20
00014260274e[CPU0 ] jump_protected: gate type 0 unsupported
CPU 0: Exception 0x0d - (#GP) general protection fault occured (error_code=0x0008)
CPU 0: Interrupt 0x0d occured (error_code=0x0008)
00014260274e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d)
CPU 0: Exception 0x0d - (#GP) general protection fault occured (error_code=0x006a)
CPU 0: Exception 0x08 - (#DF) double fault occured (error_code=0x0000)
CPU 0: Interrupt 0x08 occured (error_code=0x0000)
00014260274e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08)
CPU 0: Exception 0x0d - (#GP) general protection fault occured (error_code=0x0042)
00014260274i[CPU0 ] CPU is in protected mode (active)
00014260274i[CPU0 ] CS.mode = 16 bit
00014260274i[CPU0 ] SS.mode = 16 bit
00014260274i[CPU0 ] EFER   = 0x00000000
00014260274i[CPU0 ] | EAX=60000011  EBX=00000000  ECX=00090000  EDX=00000000
00014260274i[CPU0 ] | ESP=0000ffc6  EBP=00000000  ESI=000e0025  EDI=0000ffac
00014260274i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00014260274i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00014260274i[CPU0 ] |  CS:1000( 0004| 0|  0) 00010000 0000ffff 0 0
00014260274i[CPU0 ] |  DS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00014260274i[CPU0 ] |  SS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00014260274i[CPU0 ] |  ES:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00014260274i[CPU0 ] |  FS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00014260274i[CPU0 ] |  GS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00014260274i[CPU0 ] | EIP=00000048 (00000048)
00014260274i[CPU0 ] | CR0=0x60000011 CR2=0x00000000
00014260274i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
(0).[14260274] [0x000000010048] 1000:0000000000000048 (unk. ctxt): jmp far 0008:004d         ; ea4d000800
00014260274e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00014260274i[SYS  ] bx_pc_system_c::Reset(HARDWARE) called
00014260274i[CPU0 ] cpu hardware reset
]
Octocontrabass
Member
Member
Posts: 5604
Joined: Mon Mar 25, 2013 7:01 pm

Re: GDT Misconfigured?

Post by Octocontrabass »

First, you need to make sure you understand where in memory your code is loaded. You have a jump to 0x1000:0x0000 in there, which is a jump to linear address 0x10000. If that is wrong, go back and change the jump to point to the correct location before doing anything else!

After that, you have a few options.

The first is to set the real mode segment registers to 0. You would then use "jmp 0:(linear address)" and "org (linear address)". This requires the code that jumps to protected mode to be within the first 64k of memory, but you're free to put the rest of your code elsewhere.

Another option is to use an org statement that is correct for the protected mode part but not the real mode part, and then correct all of the offsets in the real mode part manually. Since the real mode portion only contains one offset (in the lgdt instruction), this is quite simple: change it to "org (linear address)" and "lgdt [gdtr_descr - (linear address)]".

A third option is to load a temporary GDT with a base address that matches what you're using in real mode, and then later replace it with the correct values. I recommend avoiding this and using one of the previous two solutions.
n0ax
Posts: 10
Joined: Thu May 01, 2014 11:43 pm

Re: GDT Misconfigured?

Post by n0ax »

My code has already successfully jumped to the 2bl (second stage) and has initialised protected mode as well as hopefully loaded the gdt. The problem is when I attempt to reset the code segment with the [descriptor:offset] memory addressing model (by jumping jmp 0x8:pm_reset) bochs triple faults. The data segment is set to zero as in the bochs debug dump (since lgdt[gdtr] only accepts linear addresses) and the code segment is set to 0x1000. It seems as though something is wrong with my gdt's alignment, but I don't know what, considering the data segment was set to zero at time of the load gdt instruction and it should be a linear address?
Octocontrabass
Member
Member
Posts: 5604
Joined: Mon Mar 25, 2013 7:01 pm

Re: GDT Misconfigured?

Post by Octocontrabass »

Whoops, I missed something.

Your "lgdt" opcode loads the GDT descriptor from the data segment, not the code segment. You either need to override it to use CS (i.e. "lgdt [cs:gdtr_descr]") or adjust your code so that CS and DS have the same value. (Due to the previously mentioned issues with segmentation, I recommend using 0 for all of your segment registers in real mode, but that is not possible if any of your code is loaded above 64k.)
User avatar
Bender
Member
Member
Posts: 449
Joined: Wed Aug 21, 2013 3:53 am
Libera.chat IRC: bender|
Location: Asia, Singapore

Re: GDT Misconfigured?

Post by Bender »

Why not just set all the segment registers equivalent to CS?

Code: Select all

mov ax, cs
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
"In a time of universal deceit - telling the truth is a revolutionary act." -- George Orwell
(R3X Runtime VM)(CHIP8 Interpreter OS)
Post Reply