I apologize for such a lenghty post but I sincerely appreciate anyone's help which might clear up this issue. I've worked on this for over a week and have made no progress.
I've attached the tarball of my code. It is heavily borrowed from Bran's tutorial to act as a skeleton while I rework his code and start on my additions. If you've fiddled with his tutorial any, the code will look familiar.
Code: Select all
/* gdt.c */
#include <gdt.h>
/* setup descriptor in gdt */
void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char granularity)
{
/* set up descriptor base addr */
gdt[num].base_lo = (base & 0xFFFF);
gdt[num].base_mid = (base >> 16) & 0xFF;
gdt[num].base_hi = (base >> 24) & 0xFF;
/* set up descriptor limits */
gdt[num].limit_lo = (limit & 0xFFFF);
gdt[num].granularity = ((limit >> 16) & 0x0F);
/* set up granularity and access flags */
gdt[num].granularity |= (granularity & 0xF0);
gdt[num].access = access;
}
/* called by main to set up gdt, first 3 entries in gdt, and call gdt_flush */
void gdt_install()
{
/* setup gdt pointer and limit */
gp.limit = (sizeof(struct gdt_entry) * 3) - 1;
gp.base = (unsigned int)(&gdt);
/* null descriptor */
gdt_set_gate(0, 0, 0, 0, 0);
/* cs - base addr is 0, limit is 4gb w/ 4kb gran, 32-bit opcodes */
gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
/* ds - same as code, but descriptor type is ds */
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
/* flush old gdt and install new */
gdt_flush();
}
Code: Select all
/* include/gdt.h */
#ifndef __GDT_H
#define __GDT_H
/* define gdt entry - packed prevents compiler from dorking it up */
struct gdt_entry
{
unsigned short limit_lo;
unsigned short base_lo;
unsigned char base_mid;
unsigned char access;
unsigned char granularity;
unsigned char base_hi;
} __attribute__ ((__packed__));
/* special pointer - max bytes taken by gdt - 1 */
struct gdt_ptr
{
unsigned short limit;
unsigned int base;
} __attribute__ ((__packed__));
/* a simple 3-entry gdt and pointer */
struct gdt_entry gdt[3];
struct gdt_ptr gp;
/* the extern function in loader.asm */
extern void gdt_flush();
void gdt_set_gate(int, unsigned long, unsigned long, unsigned char, unsigned char);
void gdt_install();
#endif
Code: Select all
; snippet from loader.asm
;; the gdt (global descriptor table)
[global gdt_flush] ; allow c code to link this
[extern gp] ; gp is in gdt.c
gdt_flush:
lgdt [gp]
jmp 0x08:gdt_flush2 ; 0x08 is offset to code seg - far jmp
gdt_flush2:
mov ax, 0x10 ; 0x10 is offset in gdt to ds
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
ret ; return back to c code
Code: Select all
;; the gdt (global descriptor table)
[global gdt_flush] ; allow c code to link this
[extern gp] ; gp is in gdt.c
gdt_flush:
lgdt [gp]
mov ax, 0x10 ; 0x10 is offset in gdt to ds
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
gdt_flush2:
ret ; return back to c code
My link.ld looks like:
Code: Select all
OUTPUT_FORMAT("elf32-i386")
ENTRY(start)
phys = 0x00100000;
SECTIONS
{
.text phys : AT(phys)
{
code = .;
*(.text)
*(.rodata*)
. = ALIGN(4096);
}
.data : AT(phys + (data - code))
{
data = .;
*(.data)
. = ALIGN(4096);
}
.bss : AT(phys + (bss - code))
{
bss = .;
*(.bss)
*(.COMMON*)
. = ALIGN(4096);
}
end = .;
}
Code: Select all
00079523319e[CPU ] fetch_raw_descriptor: GDT: index (f)1 > limit (0)
00079523319e[CPU ] interrupt(): gate descriptor is not valid sys seg
00079523319e[CPU ] interrupt(): gate descriptor is not valid sys seg
00079523319i[CPU ] protected mode
00079523319i[CPU ] CS.d_b = 32 bit
00079523319i[CPU ] SS.d_b = 32 bit
00079523319i[CPU ] | EAX=2badb002 EBX=0002cc80 ECX=00103000 EDX=00000001
00079523319i[CPU ] | ESP=00102fcc EBP=00067ebc ESI=000538f4 EDI=000538f5
00079523319i[CPU ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af pf cf
00079523319i[CPU ] | SEG selector base limit G D
00079523319i[CPU ] | SEG sltr(index|ti|rpl) base limit G D
00079523319i[CPU ] | CS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00079523319i[CPU ] | DS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00079523319i[CPU ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00079523319i[CPU ] | ES:0010( 0002| 0| 0) 00000000 000fffff 1 1
00079523319i[CPU ] | FS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00079523319i[CPU ] | GS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00079523319i[CPU ] | EIP=00100032 (00100032)
00079523319i[CPU ] | CR0=0x00000011 CR1=0 CR2=0x00000000
00079523319i[CPU ] | CR3=0x00000000 CR4=0x00000000
00079523319i[CPU ] >> jmp far 0008:00100039 : EA390010000800
00079523319p[CPU ] >>PANIC<< exception(): 3rd (13) exception with no resolution
Code: Select all
00074203321e[CPU ] fetch_raw_descriptor: GDT: index (17)2 > limit (0)
00074203321e[CPU ] interrupt(): gate descriptor is not valid sys seg
00074203321e[CPU ] interrupt(): gate descriptor is not valid sys seg
00074203321i[CPU ] protected mode
00074203321i[CPU ] CS.d_b = 32 bit
00074203321i[CPU ] SS.d_b = 32 bit
00074203321i[CPU ] | EAX=2bad0010 EBX=0002cc80 ECX=00103000 EDX=00000001
00074203321i[CPU ] | ESP=00102fcc EBP=00067ebc ESI=000538f4 EDI=000538f5
00074203321i[CPU ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf zf af pf cf
00074203321i[CPU ] | SEG selector base limit G D
00074203321i[CPU ] | SEG sltr(index|ti|rpl) base limit G D
00074203321i[CPU ] | CS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00074203321i[CPU ] | DS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00074203321i[CPU ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00074203321i[CPU ] | ES:0010( 0002| 0| 0) 00000000 000fffff 1 1
00074203321i[CPU ] | FS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00074203321i[CPU ] | GS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00074203321i[CPU ] | EIP=00100036 (00100036)
00074203321i[CPU ] | CR0=0x00000011 CR1=0 CR2=0x00000000
00074203321i[CPU ] | CR3=0x00000000 CR4=0x00000000
00074203321i[CPU ] >> mov ds, ax : 8ED8
00074203321p[CPU ] >>PANIC<< exception(): 3rd (13) exception with no resolution
1000 thanks!