I know this is somewhat of a noob question but it's been driving me insane for a day and can't seem to firgure out what the problem is.
I'm trying to load my GDT but it crashes while updating the segment registers (SS to be specific).
Also, when examining the bochs output something strange cought my eye: The base and limit are both at 0xffffffff? Hmm. that can't be right....
The GDT structs (gdt.h):
Code: Select all
struct gdt_entry {
uint16_t limit_low;
uint16_t base_low;
uint8_t base_middle;
uint8_t access;
uint8_t flags;
uint8_t base_high;
} __attribute__ ((packed));
typedef struct gdt_entry gdt_entry_t;
struct gdt_ptr {
uint16_t limit;
uint32_t base;
} __attribute__ ((packed));
typedef struct gdt_ptr gdt_ptr_t;
Code: Select all
#include "gdt.h"
extern void gdt_flush(uint32_t);
static void gdt_set_gate(int32_t, uint32_t, uint32_t, uint8_t, uint8_t);
gdt_entry_t gdt_entries[5];
gdt_ptr_t gdt;
void init_gdt()
{
gdt.limit = (sizeof(gdt_entry_t) * 5) - 1;
gdt.base = (uint32_t)&gdt_entries;
gdt_set_gate(0, 0, 0, 0, 0);
gdt_set_gate(1, 0x40000000, 0xFFFFFFFF, 0x9A, 0xCF);
gdt_set_gate(2, 0x40000000, 0xFFFFFFFF, 0x92, 0xCF);
gdt_set_gate(3, 0x40000000, 0xFFFFFFFF, 0xFA, 0xCF);
gdt_set_gate(4, 0x40000000, 0xFFFFFFFF, 0xF2, 0xCF);
gdt_flush((uint32_t)&gdt);
}
static void gdt_set_gate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t flags)
{
gdt_entries[num].base_low = (base & 0xFFFF);
gdt_entries[num].base_middle = (base >> 16) & 0xFF;
gdt_entries[num].base_high = (base >> 24) & 0xFF;
gdt_entries[num].limit_low = (limit & 0xFFFF);
gdt_entries[num].flags = (limit >> 16) & 0x0F;
gdt_entries[num].flags |= flags & 0xF0;
gdt_entries[num].access = access;
}
Code: Select all
[GLOBAL gdt_flush]
gdt_flush:
mov eax, [esp+4]
lgdt [eax]
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax ; Crashes here
jmp 0x08:.flush2
.flush2:
ret
Code: Select all
00670455802p[CPU0 ] >>PANIC<< exception(): 3rd (13) exception with no resolution
00670455802i[CPU0 ] CPU is in protected mode (active)
00670455802i[CPU0 ] CS.d_b = 32 bit
00670455802i[CPU0 ] SS.d_b = 32 bit
00670455802i[CPU0 ] EFER = 0x00000000
00670455802i[CPU0 ] | RAX=0000000000100010 RBX=000000000002d000
00670455802i[CPU0 ] | RCX=0000000000000004 RDX=0000000000102f90
00670455802i[CPU0 ] | RSP=0000000000067e60 RBP=0000000000067e8c
00670455802i[CPU0 ] | RSI=0000000000053c9d RDI=0000000000053c9e
00670455802i[CPU0 ] | R8=0000000000000000 R9=0000000000000000
00670455802i[CPU0 ] | R10=0000000000000000 R11=0000000000000000
00670455802i[CPU0 ] | R12=0000000000000000 R13=0000000000000000
00670455802i[CPU0 ] | R14=0000000000000000 R15=0000000000000000
00670455802i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af PF cf
00670455802i[CPU0 ] | SEG selector base limit G D
00670455802i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00670455802i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 ffffffff 1 1
00670455802i[CPU0 ] | DS:0010( 0002| 0| 0) ffffffff ffffffff 1 1
00670455802i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00670455802i[CPU0 ] | ES:0010( 0002| 0| 0) ffffffff ffffffff 1 1
00670455802i[CPU0 ] | FS:0010( 0002| 0| 0) ffffffff ffffffff 1 1
00670455802i[CPU0 ] | GS:0010( 0002| 0| 0) ffffffff ffffffff 1 1
00670455802i[CPU0 ] | MSR_FS_BASE:00000000ffffffff
00670455802i[CPU0 ] | MSR_GS_BASE:00000000ffffffff
00670455802i[CPU0 ] | RIP=00000000001007cb (00000000001007cb)
00670455802i[CPU0 ] | CR0=0x60000011 CR2=0x0000000000000000
00670455802i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00670455802i[CPU0 ] 0x00000000001007cb>> mov ss, ax : 8ED0
00670455802i[CMOS ] Last time is 1405492339 (Wed Jul 16 08:32:19 2014)
00670455802i[ ] restoring default signal behavior
00670455802i[CTRL ] quit_sim called with exit code 1