another triple fault loading the GDT!
Posted: Sun Aug 10, 2008 9:41 pm
For what's probably the 5th thread in the same number of weeks...
I'm restarting my kernel (again) and following JamesM's guide so I can get up to speed quickly. I get a triple fault when I load my new GDT:
to which Bochs tells me:
I've noticed that whichever order I put the segments in, it will always error on the instruction immediately after mov 0x10, %ax.
My GDT is defined as:
Sorry for being repetitive, but it's quite frustrating to be stuck at something that seems so simple.
Thanks for any help.
I'm restarting my kernel (again) and following JamesM's guide so I can get up to speed quickly. I get a triple fault when I load my new GDT:
Code: Select all
DT_LoadGDT:
mov 4(%esp), %eax // put gdt pointer in eax
lgdt (%eax)
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss
// jump into the new code segment
ljmp $0x08,$.flush
.flush:
ret
Code: Select all
00061636687e[CPU0 ] fetch_raw_descriptor: GDT: index (17)2 > limit (0)
00061636687i[CPU0 ] CPU is in protected mode (active)
00061636687i[CPU0 ] CS.d_b = 32 bit
00061636687i[CPU0 ] SS.d_b = 32 bit
00061636687i[CPU0 ] EFER = 0x00000000
00061636687i[CPU0 ] | RAX=0000000000100010 RBX=000000000002bdc0
00061636687i[CPU0 ] | RCX=00000000000000ff RDX=0000000000000002
00061636687i[CPU0 ] | RSP=0000000000109fcc RBP=0000000000109fe8
00061636687i[CPU0 ] | RSI=000000000002bf2e RDI=000000000002bf33
00061636687i[CPU0 ] | R8=0000000000000000 R9=0000000000000000
00061636687i[CPU0 ] | R10=0000000000000000 R11=0000000000000000
00061636687i[CPU0 ] | R12=0000000000000000 R13=0000000000000000
00061636687i[CPU0 ] | R14=0000000000000000 R15=0000000000000000
00061636687i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af pf cf
00061636687i[CPU0 ] | SEG selector base limit G D
00061636687i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00061636687i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00061636687i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00061636687i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00061636687i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 000fffff 1 1
00061636687i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00061636687i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00061636687i[CPU0 ] | MSR_FS_BASE:0000000000000000
00061636687i[CPU0 ] | MSR_GS_BASE:0000000000000000
00061636687i[CPU0 ] | RIP=0000000000100a77 (0000000000100a77)
00061636687i[CPU0 ] | CR0=0x00000011 CR1=0x0 CR2=0x0000000000000000
00061636687i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00061636687i[CPU0 ] >> mov ds, ax : 8ED8
00061636687e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
My GDT is defined as:
Code: Select all
extern void DT_LoadGDT(uint32_t gdt);
#define NUM_GDT_ENTRIES 3
typedef struct
{
uint16_t lowLimit;
uint16_t lowBase;
uint8_t middleBase;
uint8_t access;
uint8_t granularity;
uint8_t highBase;
} __attribute__((packed)) gdtEntry_t;
static gdtEntry_t gdtEntries[NUM_GDT_ENTRIES];
typedef struct
{
uint16_t limit;
uint32_t base;
} __attribute__((packed)) gdt_t;
static gdt_t gdt;
static void gdtSet(int32_t i, uint32_t base, uint32_t limit, uint8_t access, uint8_t granularity)
{
memset(&gdtEntries, 0, sizeof(gdtEntries) * 5);
gdtEntries[i].lowBase = base & 0xffff;
gdtEntries[i].middleBase = (base >> 16) & 0xff;
gdtEntries[i].highBase = (base >> 24) & 0xff;
gdtEntries[i].lowLimit = limit & 0xffff;
gdtEntries[i].granularity = (limit >> 16) & 0xffff;
gdtEntries[i].granularity |= granularity & 0xf0;
gdtEntries[i].access = access;
}
gdt.limit = (sizeof(gdtEntry_t) * NUM_GDT_ENTRIES) - 1;
gdt.base = (uint32_t)&gdtEntries;
gdtSet(0, 0, 0, 0, 0); /* null segment */
gdtSet(1, 0, 0xffffffff, 0x9a, 0xcf); /* code segment */
gdtSet(2, 0, 0xffffffff, 0x92, 0xcf); /* data segment */
DT_LoadGDT((uint32_t)&gdt);
Thanks for any help.