From 2ad50cc62276d3a89001e63a306685ba874e465a Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Fri, 24 Aug 2012 14:45:27 +0200 Subject: [PATCH 1/2] DS & ES registers are used from our kernerl. => By entering/leaving the kernel, saving/restoring of these registers are required. --- arch/x86/include/asm/stddef.h | 5 +++++ arch/x86/kernel/entry32.asm | 18 ++++++++++++++---- arch/x86/kernel/gdt.c | 2 ++ arch/x86/mm/page32.c | 4 ++-- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/stddef.h b/arch/x86/include/asm/stddef.h index e83032e1..948b6935 100644 --- a/arch/x86/include/asm/stddef.h +++ b/arch/x86/include/asm/stddef.h @@ -83,9 +83,14 @@ typedef unsigned int wint_t; /** @brief This defines what the stack looks like after an ISR was called. * * All the interrupt handler routines use this type for their only parameter. + * Note: Our kernel doesn't use the GS and FS registers. */ struct state { #ifdef CONFIG_X86_32 + // ds register + uint32_t ds; + // es register + uint32_t es; /// EDI register uint32_t edi; /// ESI register diff --git a/arch/x86/kernel/entry32.asm b/arch/x86/kernel/entry32.asm index 7fe3338a..276b02b8 100644 --- a/arch/x86/kernel/entry32.asm +++ b/arch/x86/kernel/entry32.asm @@ -438,8 +438,6 @@ extern syscall_handler ; used to realize system calls isrsyscall: push ds - push fs - push gs push es push ebp push edi @@ -448,6 +446,10 @@ isrsyscall: push ecx push ebx push eax + mov ax, 0x10 + mov ds, ax + mov es, ax + mov eax, [esp] call syscall_handler add esp, 4 ; eax contains the return value ; => we did not restore eax @@ -458,8 +460,6 @@ isrsyscall: pop edi pop ebp pop es - pop gs - pop fs pop ds iret @@ -758,6 +758,7 @@ ALIGN 4 switch_context: ; create on the stack a pseudo interrupt ; afterwards, we switch to the task with iret + ; we already in kernel space => no pushing of SS required mov eax, [esp+4] ; on the stack is already the address to store the old esp pushf ; EFLAGS push DWORD 0x8 ; CS @@ -765,6 +766,8 @@ switch_context: push DWORD 0x0 ; Interrupt number push DWORD 0x00edbabe ; Error code pusha ; Registers... + push es + push ds jmp common_switch @@ -775,6 +778,11 @@ rollback: ALIGN 4 common_stub: pusha + push es + push ds + mov ax, 0x10 + mov es, ax + mov ds, ax ; use the same handler for interrupts and exceptions push esp @@ -798,6 +806,8 @@ common_switch: call finish_task_switch no_context_switch: + pop ds + pop es popa add esp, 8 iret diff --git a/arch/x86/kernel/gdt.c b/arch/x86/kernel/gdt.c index 9e1c30df..fe4024a2 100644 --- a/arch/x86/kernel/gdt.c +++ b/arch/x86/kernel/gdt.c @@ -99,6 +99,7 @@ int arch_fork(task_t* task) state->int_no = 0xB16B00B5; state->error = 0xC03DB4B3; state->cs = 0x08; + state->ds = state->es = 0x10; // store the current EFLAGS asm volatile ("pushf; pop %0" : "=m"(state->eflags)); // enable interrupts @@ -178,6 +179,7 @@ int create_default_frame(task_t* task, entry_point_t ep, void* arg) stptr->cs = 0x08; #ifdef CONFIG_X86_32 stptr->eflags = 0x1202; + stptr->ds = stptr->es = 0x10; // the creation of a kernel tasks didn't change the IOPL level // => useresp & ss is not required #else diff --git a/arch/x86/mm/page32.c b/arch/x86/mm/page32.c index 8fe6fc04..f867abab 100644 --- a/arch/x86/mm/page32.c +++ b/arch/x86/mm/page32.c @@ -682,8 +682,8 @@ static void pagefault_handler(struct state *s) default_handler: kprintf("PAGE FAULT: Task %u got page fault at %p (irq %d, cs:eip 0x%x:0x%x)\n", task->id, viraddr, s->int_no, s->cs, s->eip); - kprintf("Register state: eax = 0x%x, ebx = 0x%x, ecx = 0x%x, edx = 0x%x, edi = 0x%x, esi = 0x%x, ebp = 0x%x, esp = 0x%x\n", - s->eax, s->ebx, s->ecx, s->edx, s->edi, s->esi, s->ebp, s->esp); + kprintf("Register state: eax = 0x%x, ebx = 0x%x, ecx = 0x%x, edx = 0x%x, edi = 0x%x, esi = 0x%x, ebp = 0x%x, esp = 0x%xi, ds = 0x%x, es = 0x%x\n", + s->eax, s->ebx, s->ecx, s->edx, s->edi, s->esi, s->ebp, s->esp, s->ds, s->es); irq_enable(); abort(); From e22c14e6d2fff9a5282a66f854f4600dace9568b Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Sun, 26 Aug 2012 14:08:00 +0200 Subject: [PATCH 2/2] remove memory leak --- fs/fs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/fs.c b/fs/fs.c index 618dff58..90373c06 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -71,7 +71,7 @@ int open_fs(fildes_t* file, const char* name) uint32_t ret = 0, i, j = 1; vfs_node_t* file_node = NULL; /* file node */ vfs_node_t* dir_node = NULL; - char* fname = kmalloc(sizeof(char)*MAX_FNAME); + char fname[MAX_FNAME]; if (BUILTIN_EXPECT(!name, 0)) return ret;