From 0ea68568372b7b7b20bca6985ae4b36e8c99c0e9 Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Fri, 13 Feb 2015 18:53:36 +0100 Subject: Implement switching to usermode. --- src/kernel/core/gdt.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'src/kernel/core/gdt.c') diff --git a/src/kernel/core/gdt.c b/src/kernel/core/gdt.c index eadde5f..97e6661 100644 --- a/src/kernel/core/gdt.c +++ b/src/kernel/core/gdt.c @@ -60,6 +60,7 @@ typedef struct tss_entry tss_entry_t; static gdt_entry_t gdt_entries[GDT_ENTRIES]; static gdt_ptr_t gdt_ptr; +static tss_entry_t tss_entry; /* For internal use only. Writes one entry of the GDT with given parameters. */ static void gdt_set_gate(int num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran) { @@ -84,7 +85,27 @@ void gdt_init() { gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); //User code segment 0x18 gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); //User data segment 0x20 - asm volatile ("lgdt %0"::"m"(gdt_ptr):"memory"); + // Write TSS + memset(&tss_entry, 0, sizeof(tss_entry)); + + tss_entry.ss0 = 0x10; + tss_entry.esp0 = 0; + + tss_entry.cs = 0x0b; + tss_entry.ss = tss_entry.ds = tss_entry.es = tss_entry.fs = tss_entry.gs = 0x13; + + uint32_t tss_base = (uint32_t)&tss_entry; + uint32_t tss_limit = tss_base + sizeof(tss_entry_t); + + gdt_set_gate(5, tss_base, tss_limit, 0xE9, 0x00); + + asm volatile("lgdt %0"::"m"(gdt_ptr):"memory"); + + asm volatile("movw $0x2b, %%ax; ltr %%ax":::"%eax"); +} + +void set_kernel_stack(void* addr) { + tss_entry.esp0 = (uint32_t)addr; } /* vim: set ts=4 sw=4 tw=0 noet :*/ -- cgit v1.2.3