diff --git a/arch/x86/include/asm/idt.h b/arch/x86/include/asm/idt.h index b506404d..97239c8a 100644 --- a/arch/x86/include/asm/idt.h +++ b/arch/x86/include/asm/idt.h @@ -24,6 +24,8 @@ #define IDT_FLAG_PRESENT 0x80 #define IDT_FLAG_RING0 0x00 +#define IDT_FLAG_RING1 0x20 +#define IDT_FLAG_RING2 0x40 #define IDT_FLAG_RING3 0x60 #define IDT_FLAG_16BIT 0x00 #define IDT_FLAG_32BIT 0x08 @@ -31,6 +33,9 @@ #define IDT_FLAG_TRAPGATE 0x07 #define IDT_FLAG_TASKGATE 0x05 +#define KERNEL_CODE_SELECTOR 0x08 +#define KERNEL_DATA_SELECTOR 0x10 + #ifdef __cplusplus extern "C" { #endif diff --git a/arch/x86/kernel/gdt.c b/arch/x86/kernel/gdt.c index d6d18a68..0b38d7b2 100644 --- a/arch/x86/kernel/gdt.c +++ b/arch/x86/kernel/gdt.c @@ -43,9 +43,23 @@ typedef struct { #error Too many GDT entries! #endif +#define GDT_FLAG_DATASEG 0x02 +#define GDT_FLAG_CODESEG 0x0a +#define GDT_FLAG_TSS 0x09 + +#define GDT_FLAG_SEGMENT 0x10 +#define GDT_FLAG_RING0 0x00 +#define GDT_FLAG_RING1 0x20 +#define GDT_FLAG_RING2 0x40 +#define GDT_FLAG_RING3 0x60 +#define GDT_FLAG_PRESENT 0x80 + +#define GDT_FLAG_4K_GRAN 0x80 +#define GDT_FLAG_32_BIT 0x40 + gdt_ptr_t gp; static tss_t task_state_segments[MAX_TASKS]; -static gdt_entry_t gdt[GDT_ENTRIES]; +static gdt_entry_t gdt[GDT_ENTRIES] = {[0 ... GDT_ENTRIES-1] = {0, 0, 0, 0, 0, 0,}}; static unsigned char kstacks[MAX_TASKS][KERNEL_STACK_SIZE]; /* @@ -149,7 +163,6 @@ void gdt_install(void) unsigned int i; memset(task_state_segments, 0x00, MAX_TASKS*sizeof(tss_t)); - memset(gdt, 0x00, GDT_ENTRIES*sizeof(gdt_entry_t)); /* Setup the GDT pointer and limit */ gp.limit = (sizeof(gdt_entry_t) * GDT_ENTRIES) - 1; @@ -163,31 +176,41 @@ void gdt_install(void) * is 0, the limit is 4 GByte, it uses 4KByte granularity, * uses 32-bit opcodes, and is a Code Segment descriptor. */ - gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); + gdt_set_gate(1, 0, 0xFFFFFFFF, + GDT_FLAG_SEGMENT | GDT_FLAG_CODESEG | GDT_FLAG_PRESENT, + GDT_FLAG_4K_GRAN | GDT_FLAG_32_BIT); /* * The third entry is our Data Segment. It's EXACTLY the * same as our code segment, but the descriptor type in * this entry's access byte says it's a Data Segment */ - gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); + gdt_set_gate(2, 0, 0xFFFFFFFF, + GDT_FLAG_SEGMENT | GDT_FLAG_DATASEG | GDT_FLAG_PRESENT, + GDT_FLAG_4K_GRAN | GDT_FLAG_32_BIT); /* * Create code segement for userspace applications (ring 3) */ - gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); + gdt_set_gate(3, 0, 0xFFFFFFFF, + GDT_FLAG_RING3 | GDT_FLAG_SEGMENT | GDT_FLAG_CODESEG | GDT_FLAG_PRESENT, + GDT_FLAG_4K_GRAN | GDT_FLAG_32_BIT); /* * Create data segement for userspace applications (ring 3) */ - gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); + gdt_set_gate(4, 0, 0xFFFFFFFF, + GDT_FLAG_RING3 | GDT_FLAG_SEGMENT | GDT_FLAG_DATASEG | GDT_FLAG_PRESENT, + GDT_FLAG_4K_GRAN | GDT_FLAG_32_BIT); /* * Create TSS for each task (we use these segments for task switching) */ - //gdt_set_gate(5, (unsigned long) task_state_segments, sizeof(tss_t)-1, 0x8B, 0x4F); - for(i=0; i