From aba6ed4b91aff5d914be11704e34de75bfd4d003 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Fri, 10 Sep 2010 18:46:00 +0200 Subject: Each thread has its own stack. Added simple unit tests for kmalloc,kfree Found a bug in heap_contract (not sure) but didn't fix it. --- src/kernel/task/idt.c | 8 +++----- src/kernel/task/syscall.c | 2 +- src/kernel/task/task.c | 29 ++++++++++++++++------------- src/kernel/task/task.h | 5 ++--- 4 files changed, 22 insertions(+), 22 deletions(-) (limited to 'src/kernel/task') diff --git a/src/kernel/task/idt.c b/src/kernel/task/idt.c index 6aa16e0..be5d152 100644 --- a/src/kernel/task/idt.c +++ b/src/kernel/task/idt.c @@ -75,11 +75,9 @@ static struct irq_waiter { void idt_isrHandler(struct registers regs) { if ((regs.int_no == 14 && paging_fault(®s) != 0) || regs.int_no != 14) { if (tasking_handleException(®s) == 0) { - monitor_write("\n >> >> SOMETHING BAD HAPPENNED << <<\n"); - monitor_write("Unhandled exception "); - monitor_writeHex(regs.int_no); - monitor_write(" @"); monitor_writeHex(regs.eip); - monitor_put('\n'); + monitor_write("\nREALLY BAD THIS TIME\t\tUnhandled exception\t#"); + monitor_writeDec(regs.int_no); + monitor_write("\t@"); monitor_writeHex(regs.eip); PANIC("Unhandled Exception"); } } diff --git a/src/kernel/task/syscall.c b/src/kernel/task/syscall.c index 41cd0ea..b490987 100644 --- a/src/kernel/task/syscall.c +++ b/src/kernel/task/syscall.c @@ -35,7 +35,7 @@ CALL2(send_msg, send_msg_sc); CALL2(process_setheapseg, proc_setheap_sc); static void thread_new_sc(struct registers* r) { - thread_new(current_thread->process, (thread_entry)r->ebx, (void*)r->ecx); + thread_new(current_thread->process, (thread_entry)r->ebx, (void*)r->ecx, (void*)r->edx); } int_callback syscalls[NUMBER_OF_SYSCALLS] = { diff --git a/src/kernel/task/task.c b/src/kernel/task/task.c index 7153d85..b8a72ce 100644 --- a/src/kernel/task/task.c +++ b/src/kernel/task/task.c @@ -39,7 +39,7 @@ void tasking_init() { kernel_process->pagedir = kernel_pagedir; kernel_process->next = 0; current_thread = 0; - idle_thread = thread_new(kernel_process, task_idle, 0); + idle_thread = thread_new(kernel_process, task_idle, 0, 0); kernel_process->threads = idle_thread; sti(); monitor_write("[Tasking] "); @@ -99,15 +99,15 @@ void tasking_switch() { Ends the thread for most exceptions, ends the whole process for page faults. */ uint32_t tasking_handleException(struct registers *regs) { if (current_thread == 0) return 0; //No tasking yet - NL; WHERE; monitor_write("Unhandled exception : "); + NL; WHERE; monitor_write("exception:`"); char *exception_messages[] = {"Division By Zero","Debug","Non Maskable Interrupt","Breakpoint", "Into Detected Overflow","Out of Bounds","Invalid Opcode","No Coprocessor", "Double Fault", "Coprocessor Segment Overrun","Bad TSS","Segment Not Present","Stack Fault","General Protection Fault", "Page Fault","Unknown Interrupt","Coprocessor Fault","Alignment Check","Machine Check"}; monitor_write(exception_messages[regs->int_no]); - monitor_write(" eip:"); monitor_writeHex(regs->eip); + monitor_write("'\teip:"); monitor_writeHex(regs->eip); if (regs->eip >= 0xE0000000) { - monitor_write("\n Exception stack trace :"); + monitor_write("\n Exception stack trace :\n"); stack_trace(regs->ebp); PANIC("Kernel error'd."); } @@ -194,10 +194,10 @@ void process_exit(uint32_t retval) { /* For internal use only. This is called when a newly created thread first runs (its address is the value given for EIP). It switches to user mode if necessary and calls the entry point. */ -static void thread_run(struct thread *thread, thread_entry entry_point, void *data) { +static void thread_run(void* u_esp, struct thread *thread, thread_entry entry_point, void *data) { pagedir_switch(thread->process->pagedir); if (thread->process->privilege >= PL_SERVICE) { //User mode ! - uint32_t *stack = (uint32_t*)(thread->userStack_seg->start + thread->userStack_seg->len); + uint32_t *stack = u_esp; stack--; *stack = (uint32_t)data; stack--; *stack = 0; @@ -239,16 +239,13 @@ static void thread_run(struct thread *thread, thread_entry entry_point, void *da /* Creates a new thread for given process. Allocates a kernel stack and a user stack if necessary. Sets up the kernel stack for values to be passed to thread_run. */ -struct thread *thread_new(struct process *proc, thread_entry entry_point, void *data) { +struct thread *thread_new(struct process *proc, thread_entry entry_point, void *data, void *u_esp) { struct thread *t = kmalloc(sizeof(struct thread)); t->process = proc; t->next = 0; proc->thread_count++; - if (proc->privilege >= PL_SERVICE) { //We are running in user mode - proc->stacksBottom -= USER_STACK_SIZE; - t->userStack_seg = seg_map(simpleseg_make(proc->stacksBottom, USER_STACK_SIZE, 1), proc->pagedir, 0); - } + if (u_esp == 0) u_esp = (void*)proc->stack; t->kernelStack_addr = kmalloc(KSTACKSIZE); t->kernelStack_size = KSTACKSIZE; @@ -259,6 +256,7 @@ struct thread *thread_new(struct process *proc, thread_entry entry_point, void * stack--; *stack = (uint32_t)data; stack--; *stack = (uint32_t)entry_point; stack--; *stack = (uint32_t)t; + stack--; *stack = (uint32_t)u_esp; stack--; *stack = 0; t->esp = (uint32_t)stack; t->ebp = t->esp + 8; @@ -287,9 +285,15 @@ struct process *process_new(struct process* parent, uint32_t uid, uint32_t privi p->parent = parent; p->pagedir = pagedir_new(); p->next = processes; - p->stacksBottom = 0xDF000000; p->heapseg = 0; + p->stack = 0; + if (p->privilege >= PL_SERVICE) { //We are running in user mode + size_t stacksBottom = 0xDF000000; + seg_map(simpleseg_make(stacksBottom, USER_STACK_SIZE, 1), p->pagedir, 0); + p->stack = stacksBottom + USER_STACK_SIZE - 4; + } + p->next_objdesc = 0; p->objects = 0; struct object* o = obj_new(p); @@ -318,7 +322,6 @@ static void thread_delete(struct thread *th) { if (current_thread == th) current_thread = 0; th->process->thread_count--; kfree(th->kernelStack_addr); - if (th->userStack_seg != 0) seg_unmap(th->userStack_seg); kfree(th); } diff --git a/src/kernel/task/task.h b/src/kernel/task/task.h index 0a95e57..171a9fd 100644 --- a/src/kernel/task/task.h +++ b/src/kernel/task/task.h @@ -26,7 +26,7 @@ struct process { uint32_t pid, uid, privilege, thread_count; struct process *parent; struct page_directory *pagedir; - size_t stacksBottom; + size_t stack; struct obj_descriptor *objects; uint32_t next_objdesc; @@ -44,7 +44,6 @@ struct thread { uint32_t timeWait; void* kernelStack_addr; uint32_t kernelStack_size; - struct segment_map *userStack_seg; struct thread *next, *queue_next; //queue_next is used in sched.c }; @@ -59,7 +58,7 @@ uint32_t tasking_handleException(struct registers *regs); void thread_goInactive(); //Blocks the current thread. it is then waked up by another thread or a system event. void thread_wakeUp(struct thread *t); int proc_priv(); //Returns current privilege level -struct thread * thread_new(struct process *proc, thread_entry entry_point, void *data); +struct thread * thread_new(struct process *proc, thread_entry entry_point, void *data, void *u_esp); struct process* process_new(struct process *parent, uint32_t uid, uint32_t privilege); void thread_exit(); //syscall -- cgit v1.2.3