From ee348973b0cb0f6481e4fd6e7494c63167c9759c Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Wed, 7 Apr 2010 11:37:21 +0200 Subject: More work on manager --- src/kernel/Makefile | 2 +- src/kernel/core/kmain.c | 5 ++-- src/kernel/core/loader_.asm | 2 +- src/kernel/ipc/object.c | 1 + src/kernel/ipc/object.h | 1 + src/kernel/ipc/request.c | 37 ++++++++++++++++++------ src/kernel/ipc/request.h | 2 +- src/kernel/ipc/shm.c | 6 ++-- src/kernel/mem/paging.c | 2 +- src/kernel/mem/seg.c | 1 + src/kernel/task/syscall.c | 3 +- src/kernel/task/task.c | 69 ++++++++++++++++++++++++++++++--------------- 12 files changed, 91 insertions(+), 40 deletions(-) (limited to 'src/kernel') diff --git a/src/kernel/Makefile b/src/kernel/Makefile index 6d0b7f3..d7a6a57 100644 --- a/src/kernel/Makefile +++ b/src/kernel/Makefile @@ -1,7 +1,7 @@ .PHONY: clean, mrproper CC = gcc -CFLAGS = -nostdlib -nostartfiles -nodefaultlibs -fno-builtin -fno-stack-protector -Wall -Wextra -I . -I ./lib +CFLAGS = -nostdlib -nostartfiles -nodefaultlibs -fno-builtin -fno-stack-protector -Wall -Wextra -I . -I ./lib -g LD = ld LDFLAGS = -T link.ld diff --git a/src/kernel/core/kmain.c b/src/kernel/core/kmain.c index 9fb1397..1577ac7 100644 --- a/src/kernel/core/kmain.c +++ b/src/kernel/core/kmain.c @@ -50,10 +50,11 @@ void kmain(struct multiboot_info_t* mbd, int32_t magic) { if (elf_check((uint8_t*)mods[i].mod_start)) { monitor_write(" : Invalid ELF file\n"); } else { - if (elf_exec((uint8_t*)mods[i].mod_start, PL_DRIVER) == 0) { + struct process *pr = elf_exec((uint8_t*)mods[i].mod_start, PL_DRIVER); + if (pr == 0) { monitor_write(" : Error loading\n"); } else { - monitor_write(" : OK\n"); + monitor_write(" : OK pid:"); monitor_writeDec(pr->pid); monitor_write("\n"); } } } diff --git a/src/kernel/core/loader_.asm b/src/kernel/core/loader_.asm index d3b92cf..5ee998a 100644 --- a/src/kernel/core/loader_.asm +++ b/src/kernel/core/loader_.asm @@ -31,7 +31,7 @@ loader: ;here, we load our false GDT, used for having the kernel in higher half section .text higherhalf: ; now we're running in higher half - mov esp, tasking_tmpStack+0x4000 ; set up the stack + mov esp, tasking_tmpStack+0x8000 ; set up the stack push eax ; pass Multiboot magic number add ebx, 0xE0000000 ; update the MB info structure so that it is in the new seg push ebx ; pass Multiboot info structure diff --git a/src/kernel/ipc/object.c b/src/kernel/ipc/object.c index e381c89..cfb9652 100644 --- a/src/kernel/ipc/object.c +++ b/src/kernel/ipc/object.c @@ -8,6 +8,7 @@ struct object* obj_new(struct process* owner) { ret->descriptors = 0; ret->busyMutex = MUTEX_UNLOCKED; ret->request = 0; + ret->wakeupOnRq = 0; return ret; } diff --git a/src/kernel/ipc/object.h b/src/kernel/ipc/object.h index 9dd3a1e..4577615 100644 --- a/src/kernel/ipc/object.h +++ b/src/kernel/ipc/object.h @@ -8,6 +8,7 @@ struct object { int descriptors; uint32_t busyMutex; //if busy, either a blocking request is being processed, or a sent message is waiting for being recieved struct request *request; + struct thread *wakeupOnRq; }; struct obj_descriptor { diff --git a/src/kernel/ipc/request.c b/src/kernel/ipc/request.c index 9ca724e..7fe8f2b 100644 --- a/src/kernel/ipc/request.c +++ b/src/kernel/ipc/request.c @@ -15,15 +15,19 @@ int request_get(int id, uint32_t ptr, int wait) { if (obj->request != 0 && obj->request->acknowledged != RS_PENDING) return -3; //if not (busymutex unlocked and request==0) && wait, then wait, else return -1 if (wait == 0 && obj->request == 0) return -1; - while (obj->busyMutex != MUTEX_LOCKED && (obj->request == 0 || obj->request->acknowledged != RS_PENDING)) thread_sleep(1); + while (obj->busyMutex != MUTEX_LOCKED && (obj->request == 0 || obj->request->acknowledged != RS_PENDING)) { + //set thread to be waked up on request + obj->wakeupOnRq = current_thread; + //go to sleep + thread_goInactive(); + } obj->request->acknowledged = RS_PROCESSED; //when request pending (wait finished), write it to ptr struct user_request *p = (struct user_request*)ptr; p->func = obj->request->func; for (i = 0; i < 3; i++) { p->params[i] = obj->request->params[i]; - if (obj->request->shm_sndr[i] != 0) p->shmsize[i] = obj->request->shm_sndr[i]->len; - else p->shmsize[i] = 0; + p->shmsize[i] = obj->request->shmsize[i]; } p->isBlocking = (obj->request->requester != 0); p->pid = obj->request->pid; @@ -69,15 +73,19 @@ void request_answer(int id, uint32_t answer, uint32_t answer2, int errcode) { obj->request->acknowledged = RS_FINISHED; switch (obj->request->func >> 30) { case PT_OBJDESC: - if ((int)answer <= 0) { + if ((int)answer < 0) { obj->request->answer.n = answer; } else { if (obj->owner == obj->request->requester->process) { obj->request->answer.n = answer; } else { - int n = objdesc_get(obj->request->requester->process, objdesc_read(obj->owner, answer)); - if (n == -1) { - n = objdesc_add(obj->request->requester->process, objdesc_read(obj->owner, answer)); + struct object *o = objdesc_read(obj->owner, answer); + int n = -1; + if (o != 0) { + n = objdesc_get(obj->request->requester->process, o); + if (n == -1) { + n = objdesc_add(obj->request->requester->process, o); + } } obj->request->answer.n = n; } @@ -110,11 +118,12 @@ int request_mapShm(int id, uint32_t pos, int number) { int n = (obj->request->func >> (28 - (2 * number))) & 3; if (n != PT_SHM) return -4; //check if sender process is different from receiver process, if not return -7 - if (obj->owner == obj->request->requester->process) return -7; + if (obj->request->requester != 0 && obj->owner == obj->request->requester->process) return -7; //check if sender sent a shm seg in parameter [number], if not return -5 if (obj->request->shm_sndr[number] == 0) return -5; //map shm to position obj->request->shm_rcv[number] = seg_map(obj->request->shm_sndr[number]->seg, obj->owner->pagedir, pos); + obj->request->shm_sndr[number]->seg->mappings--; //if request is nonblocking and no more shm is to be mapped, delete request and free object busymutex if (obj->request->requester != 0) return 0; for (i = 0; i < 3; i++) { @@ -161,7 +170,7 @@ static struct request *mkrequest(int id, struct thread *requester, uint32_t v = (i == 0 ? a : (i == 1 ? b : c)); switch (n) { case PT_OBJDESC: - if ((int)v <= 0) { + if ((int)v < 0) { rq->params[i] = v; } else { if (obj->owner == current_thread->process) { @@ -180,16 +189,25 @@ static struct request *mkrequest(int id, struct thread *requester, rq->params[i] = v; break; case PT_SHM: + rq->shmsize[i] = 0; if (obj->owner == current_thread->process) { rq->params[i] = v; + struct segment_map *t = shmseg_getByOff(current_thread->process, v); + if (t != 0) rq->shmsize[i] = t->len; } else { rq->shm_sndr[i] = shmseg_getByOff(current_thread->process, v); + rq->shm_sndr[i]->seg->mappings++; + if (rq->shm_sndr[i] != 0) rq->shmsize[i] = rq->shm_sndr[i]->len; } break; } } // reference request from object obj->request = rq; + if (obj->wakeupOnRq != 0) { + thread_wakeUp(obj->wakeupOnRq); + obj->wakeupOnRq = 0; + } // return request return rq; } @@ -230,5 +248,6 @@ int send_msg(int obj, uint32_t rq_ptr) { //if returned value is 0, return -1 else return 0 if (e != 0) return e; if (rq == 0) return -1; + urq->errcode = 0; return 0; } diff --git a/src/kernel/ipc/request.h b/src/kernel/ipc/request.h index 18eaf84..760a159 100644 --- a/src/kernel/ipc/request.h +++ b/src/kernel/ipc/request.h @@ -17,7 +17,7 @@ struct request { struct object *obj; struct thread *requester; //0 if nonblocking message - uint32_t func, params[3], obj_close[3]; //obj_close : object descriptors to close when requests yields an answer + uint32_t func, params[3], obj_close[3], shmsize[3]; //obj_close : object descriptors to close when requests yields an answer struct segment_map *shm_sndr[3], *shm_rcv[3]; int acknowledged; // (only for blocking requests) 0 : request is pending, 1 : request is being processes, 2 : finished, 3 : interrupted union { diff --git a/src/kernel/ipc/shm.c b/src/kernel/ipc/shm.c index 1cdacfb..e760a0f 100644 --- a/src/kernel/ipc/shm.c +++ b/src/kernel/ipc/shm.c @@ -2,6 +2,7 @@ #include #include #include +#include struct segment* shmseg_make(size_t len, struct process* owner) { struct shmseg *ss = kmalloc(sizeof(struct shmseg)); @@ -29,8 +30,9 @@ struct segment_map *shmseg_map(struct segment *seg, struct page_directory *paged void shmseg_unmap(struct segment_map *sm) { size_t i; - for (i = sm->start; i < sm->start + sm->len; i += 0x1000) { - page_unmap(pagedir_getPage(sm->pagedir, i, 0)); + for (i = 0; i < sm->len; i += 0x1000) { + struct page *page = pagedir_getPage(sm->pagedir, sm->start + i, 0); + if (page != 0) page_unmap(page); } } diff --git a/src/kernel/mem/paging.c b/src/kernel/mem/paging.c index 9972b2a..4992d5e 100644 --- a/src/kernel/mem/paging.c +++ b/src/kernel/mem/paging.c @@ -121,7 +121,7 @@ uint32_t paging_fault(struct registers *regs) { if (regs->err_code & 0x4) monitor_write("user "); if (regs->err_code & 0x8) monitor_write("rsvd "); if (regs->err_code & 0x10) monitor_write("instructionfetch "); - monitor_write("@"); monitor_writeHex(addr); monitor_write("\n"); + monitor_write("cr2:"); monitor_writeHex(addr); monitor_write("\n"); return 1; } return 0; diff --git a/src/kernel/mem/seg.c b/src/kernel/mem/seg.c index ffaa84c..e3eca67 100644 --- a/src/kernel/mem/seg.c +++ b/src/kernel/mem/seg.c @@ -1,5 +1,6 @@ #include "seg.h" #include "mem.h" +#include struct segment_map *seg_map(struct segment* seg, struct page_directory *pagedir, size_t offset) { struct segment_map *sm = seg->map(seg, pagedir, offset); diff --git a/src/kernel/task/syscall.c b/src/kernel/task/syscall.c index 9a1ce81..a5142eb 100644 --- a/src/kernel/task/syscall.c +++ b/src/kernel/task/syscall.c @@ -12,6 +12,7 @@ #define CALL1V(name, scname) static void scname(struct registers* r) { name(r->ebx); } #define CALL2V(name, scname) static void scname(struct registers* r) { name(r->ebx, r->ecx); } #define CALL3V(name, scname) static void scname(struct registers* r) { name(r->ebx, r->ecx, r->edx); } +#define CALL4V(name, scname) static void scname(struct registers* r) { name(r->ebx, r->ecx, r->edx, r->esi); } CALL0V(thread_exit, thread_exit_sc); CALL0V(tasking_switch, schedule_sc); @@ -27,7 +28,7 @@ CALL1(object_owned, object_owned_sc); CALL1V(object_close, object_close_sc); CALL3(request_get, request_get_sc); CALL1(request_has, request_has_sc); -CALL3V(request_answer, request_answer_sc); +CALL4V(request_answer, request_answer_sc); CALL3(request_mapShm, request_mapShm_sc); CALL2(request, request_sc); CALL2(send_msg, send_msg_sc); diff --git a/src/kernel/task/task.c b/src/kernel/task/task.c index f10ec6f..8afc609 100644 --- a/src/kernel/task/task.c +++ b/src/kernel/task/task.c @@ -28,7 +28,7 @@ static uint32_t nextpid = 1; struct process *processes = 0, *kernel_process; struct thread *threads = 0, *current_thread = 0, *idle_thread; -uint32_t tasking_tmpStack[0x4000]; +uint32_t tasking_tmpStack[KSTACKSIZE]; void tasking_init() { cli(); @@ -54,7 +54,9 @@ static struct thread *thread_next() { if (thread_runnable(ret)) { return ret; } - if (ret == current_thread) return idle_thread; + if (ret == current_thread) { + return idle_thread; + } } } @@ -110,8 +112,17 @@ uint32_t tasking_handleException(struct registers *regs) { "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(" at "); monitor_writeHex(regs->eip); - PANIC("kk"); + monitor_write(" eip:"); monitor_writeHex(regs->eip); + if (regs->eip >= 0xE0000000) { + monitor_write("\n Stack trace :"); + uint32_t *stack = (uint32_t*)regs->ebp, i; + for (i = 0; i < 5 && stack > 0xE0000000 && stack < (regs->useresp + 0x8000); i++) { + monitor_write("\nframe@"); monitor_writeHex(stack); + monitor_write(" next:"); monitor_writeHex(stack[0]); monitor_write(" ret:"); monitor_writeHex(stack[1]); + stack = (uint32_t*)stack[0]; + } + PANIC("Kernel error'd."); + } if (regs->int_no == 14) { monitor_write("\n>>> Process exiting.\n"); thread_exit_stackJmp(EX_PR_EXCEPTION); @@ -140,7 +151,7 @@ void thread_wakeUp(struct thread* t) { } int proc_priv() { - if (current_thread == 0) return PL_UNKNOWN; + if (current_thread == 0 || current_thread->process == 0) return PL_UNKNOWN; return current_thread->process->privilege; } @@ -151,20 +162,21 @@ void thread_exit2(uint32_t reason) { //See EX_TH_* defines in task.h * if reason is none of the two cases above, it is the whole process exiting (with error code = reason) */ struct thread *th = current_thread; + if (th == 0 || th->process == 0) goto retrn; struct process *pr = th->process; if ((reason == EX_TH_NORMAL || reason == EX_TH_EXCEPTION) && pr->threads > 1) { thread_delete(th); } else { process_delete(pr); } - sti(); + retrn: tasking_switch(); } void thread_exit_stackJmp(uint32_t reason) { - uint32_t *stack; cli(); - stack = tasking_tmpStack + 0x4000; + uint32_t *stack; + stack = tasking_tmpStack + (KSTACKSIZE / 4); stack--; *stack = reason; stack--; *stack = 0; asm volatile(" \ @@ -296,36 +308,49 @@ struct process *process_new(struct process* parent, uint32_t uid, uint32_t privi } static void thread_delete(struct thread *th) { - kfree(th->kernelStack_addr); - if (th->userStack_seg != 0) seg_unmap(th->userStack_seg); - th->process->threads--; if (threads == th) { threads = th->next; } else { struct thread *it = threads; - while (it->next != th && it->next != 0) it = it->next; - if (it->next == th) it->next = th->next; + while (it) { + if (it->next == th) { + it->next = th->next; + break; + } + it = it->next; + } } + if (current_thread == th) current_thread = 0; + th->process->threads--; + kfree(th->kernelStack_addr); + if (th->userStack_seg != 0) seg_unmap(th->userStack_seg); kfree(th); } static void process_delete(struct process *pr) { - struct thread *it; - while (threads != 0 && threads->process == pr) thread_delete(threads); - it = threads; - while (it != 0 && it->next != 0) { - while (it->next != 0 && it->next->process == pr) thread_delete(it->next); - it = it->next; + struct thread *it = threads; + while (it != 0) { + if (it->process == pr) { + thread_delete(it); + it = threads; + } else { + it = it->next; + } } obj_closeall(pr); - pagedir_delete(pr->pagedir); if (processes == pr) { processes = pr->next; } else { struct process *it = processes; - while (it != 0 && it->next != pr) it = it->next; - if (it != 0 && it->next == pr) it->next = pr->next; + while (it) { + if (it->next == pr) { + it->next = pr->next; + break; + } + it = it->next; + } } + pagedir_delete(pr->pagedir); kfree(pr); } -- cgit v1.2.3