diff options
author | Alexis211 <alexis211@gmail.com> | 2010-03-30 19:22:23 +0200 |
---|---|---|
committer | Alexis211 <alexis211@gmail.com> | 2010-03-30 19:22:23 +0200 |
commit | ad1ec29070e1ffba7461687cd268e64be06aa78b (patch) | |
tree | 309ca65d46f1a6164c048d9ba2060275d6d63538 /src/kernel | |
parent | 50152369119ffc92d7790ddcfd26f32613366ede (diff) | |
download | TCE-ad1ec29070e1ffba7461687cd268e64be06aa78b.tar.gz TCE-ad1ec29070e1ffba7461687cd268e64be06aa78b.zip |
More work on IPC and userland tools.
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/ipc/request.c | 36 | ||||
-rw-r--r-- | src/kernel/ipc/request.h | 4 | ||||
-rw-r--r-- | src/kernel/linker/elf.c | 6 | ||||
-rw-r--r-- | src/kernel/mem/paging.c | 1 | ||||
-rw-r--r-- | src/kernel/mem/paging.h | 2 | ||||
-rw-r--r-- | src/kernel/mem/seg.c | 21 | ||||
-rw-r--r-- | src/kernel/mem/seg.h | 1 | ||||
-rw-r--r-- | src/kernel/task/idt.h | 1 | ||||
-rw-r--r-- | src/kernel/task/idt_.asm | 6 | ||||
-rw-r--r-- | src/kernel/task/syscall.c | 2 | ||||
-rw-r--r-- | src/kernel/task/task.c | 24 | ||||
-rw-r--r-- | src/kernel/task/task.h | 3 |
12 files changed, 84 insertions, 23 deletions
diff --git a/src/kernel/ipc/request.c b/src/kernel/ipc/request.c index 9e42d6a..e59a66c 100644 --- a/src/kernel/ipc/request.c +++ b/src/kernel/ipc/request.c @@ -47,7 +47,7 @@ int request_has(int id) { return 2; } -void request_answer(int id, uint32_t answer, uint32_t answer2) { +void request_answer(int id, uint32_t answer, uint32_t answer2, int errcode) { int i; //check if we own the object, if not return (also return if descriptor does not exist) struct object *obj = objdesc_read(current_thread->process, id); @@ -64,22 +64,27 @@ void request_answer(int id, uint32_t answer, uint32_t answer2) { obj->request->acknowledged = RS_FINISHED; switch (obj->request->func >> 30) { case PT_OBJDESC: - if (obj->owner == obj->request->requester->process) { + if ((int)answer <= 0) { 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)); + 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)); + } + obj->request->answer.n = n; } - obj->request->answer.n = n; } break; case PT_LONG: obj->request->answer.n = answer; break; case PT_LONGLONG: - obj->request->answer.ll = (uint64_t)((uint64_t)answer << 32) | answer2; + obj->request->answer.ll = (uint64_t)((uint64_t)answer2 << 32) | answer; } + obj->request->errcode = errcode; //wake up receiver thread (thread_wakeUp) thread_wakeUp(obj->request->requester); //dereference request from object, unlock objects busymutex @@ -150,15 +155,19 @@ 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 (obj->owner == current_thread->process) { + if ((int)v <= 0) { rq->params[i] = v; } else { - int d = objdesc_get(obj->owner, objdesc_read(current_thread->process, v)); - if (d == -1) { - d = objdesc_add(obj->owner, objdesc_read(current_thread->process, v)); - rq->obj_close[i] = d; + if (obj->owner == current_thread->process) { + rq->params[i] = v; + } else { + int d = objdesc_get(obj->owner, objdesc_read(current_thread->process, v)); + if (d == -1) { + d = objdesc_add(obj->owner, objdesc_read(current_thread->process, v)); + rq->obj_close[i] = d; + } + rq->params[i] = d; } - rq->params[i] = d; } break; case PT_LONG: @@ -201,6 +210,7 @@ int request(int obj, uint32_t rq_ptr) { case PT_LONGLONG: urq->answerll = rq->answer.ll; } + urq->errcode = rq->errcode; kfree(rq); return 0; } diff --git a/src/kernel/ipc/request.h b/src/kernel/ipc/request.h index 0b60a5c..0afc48b 100644 --- a/src/kernel/ipc/request.h +++ b/src/kernel/ipc/request.h @@ -24,6 +24,7 @@ struct request { int64_t ll; uint32_t n; } answer; + int errcode; //returned when function has finished }; struct user_request { @@ -35,12 +36,13 @@ struct user_sendrequest { uint32_t func, a, b, c; uint32_t answeri; int64_t answerll; + int errcode; }; //syscalls int request_get(int obj, uint32_t ptr, int wait); int request_has(int obj); -void request_answer(int obj, uint32_t answer, uint32_t answer2); //answer2 used for long long. +void request_answer(int obj, uint32_t answer, uint32_t answer2, int errcode); //answer2 used for long long. int request_mapShm(int obj, uint32_t pos, int number); int request(int obj, uint32_t rq_ptr); diff --git a/src/kernel/linker/elf.c b/src/kernel/linker/elf.c index bbf4906..6ad5d34 100644 --- a/src/kernel/linker/elf.c +++ b/src/kernel/linker/elf.c @@ -16,6 +16,8 @@ thread_entry elf_load(uint8_t *data, struct process* process) { int i; if (elf_check(data)) return 0; + struct page_directory *r = current_pagedir; + cli(); pagedir_switch(process->pagedir); phdr = (struct elf_phdr*)((uint8_t*)(data + ehdr->e_phoff)); @@ -28,6 +30,10 @@ thread_entry elf_load(uint8_t *data, struct process* process) { } } } + + pagedir_switch(r); + sti(); + return (thread_entry)ehdr->e_entry; } diff --git a/src/kernel/mem/paging.c b/src/kernel/mem/paging.c index 8996162..9972b2a 100644 --- a/src/kernel/mem/paging.c +++ b/src/kernel/mem/paging.c @@ -22,7 +22,6 @@ void frame_free(uint32_t id) { bitset_clear(&frames, id); } - void paging_init(size_t totalRam) { uint32_t i; diff --git a/src/kernel/mem/paging.h b/src/kernel/mem/paging.h index cb76cd6..ec10560 100644 --- a/src/kernel/mem/paging.h +++ b/src/kernel/mem/paging.h @@ -26,7 +26,7 @@ struct page_directory { struct segment_map *mappedSegs; }; -extern struct page_directory *kernel_pagedir; +extern struct page_directory *kernel_pagedir, *current_pagedir; uint32_t frame_alloc(); void frame_free(uint32_t id); diff --git a/src/kernel/mem/seg.c b/src/kernel/mem/seg.c index aa71564..ffaa84c 100644 --- a/src/kernel/mem/seg.c +++ b/src/kernel/mem/seg.c @@ -71,3 +71,24 @@ int simpleseg_handleFault(struct segment_map* sm, size_t addr, int write) { void simpleseg_delete(struct segment* seg) { } + +int simpleseg_resize(struct segment_map *map, size_t len) { + size_t i; + + if (map == 0) return -1; + if (map->seg->delete != simpleseg_delete) return -2; + + struct simpleseg *s = (struct simpleseg*)map->seg->seg_data; + if (len & 0xFFF) len = (len & 0xFFFFF000) + 0x1000; + if (len < map->len) { + for (i = map->start + len; i < map->start + map->len; i += 0x1000) { + page_unmapFree(pagedir_getPage(map->pagedir, i, 0)); + } + map->len = len; + s->len = len; + } else if (len > map->len) { + map->len = len; + s->len = len; + } + return 0; +} diff --git a/src/kernel/mem/seg.h b/src/kernel/mem/seg.h index 4d6660f..26664dc 100644 --- a/src/kernel/mem/seg.h +++ b/src/kernel/mem/seg.h @@ -37,5 +37,6 @@ struct segment_map* simpleseg_map(struct segment* seg, struct page_directory* pa void simpleseg_unmap(struct segment_map*); void simpleseg_delete(struct segment *seg); int simpleseg_handleFault(struct segment_map* map, size_t addr, int write); +int simpleseg_resize(struct segment_map *map, size_t len); #endif diff --git a/src/kernel/task/idt.h b/src/kernel/task/idt.h index ed37eb0..b12d6c5 100644 --- a/src/kernel/task/idt.h +++ b/src/kernel/task/idt.h @@ -17,7 +17,6 @@ struct idt_ptr { } __attribute__((packed)); struct registers { - uint32_t cr3; //page directory physical address uint32_t ds; // Data segment selector uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha. uint32_t int_no, err_code; // Interrupt number and error code (if applicable) diff --git a/src/kernel/task/idt_.asm b/src/kernel/task/idt_.asm index 1a594ca..95878c0 100644 --- a/src/kernel/task/idt_.asm +++ b/src/kernel/task/idt_.asm @@ -47,14 +47,8 @@ idt_flush: mov fs, ax mov gs, ax - mov eax, cr3 - push eax - call idt_%1Handler - pop eax - mov cr3, eax - pop eax ; reload the original data segment descriptor mov ds, ax mov es, ax diff --git a/src/kernel/task/syscall.c b/src/kernel/task/syscall.c index dd909e0..9a1ce81 100644 --- a/src/kernel/task/syscall.c +++ b/src/kernel/task/syscall.c @@ -31,6 +31,7 @@ CALL3V(request_answer, request_answer_sc); CALL3(request_mapShm, request_mapShm_sc); CALL2(request, request_sc); 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); @@ -56,4 +57,5 @@ int_callback syscalls[] = { request_mapShm_sc, request_sc, send_msg_sc, + proc_setheap_sc, 0 }; diff --git a/src/kernel/task/task.c b/src/kernel/task/task.c index dec7565..9221813 100644 --- a/src/kernel/task/task.c +++ b/src/kernel/task/task.c @@ -77,6 +77,7 @@ void tasking_switch() { } current_thread = thread_next(); + pagedir_switch(current_thread->process->pagedir); gdt_setKernelStack(((uint32_t)current_thread->kernelStack_addr) + current_thread->kernelStack_size); @@ -278,6 +279,7 @@ struct process *process_new(struct process* parent, uint32_t uid, uint32_t privi p->pagedir = pagedir_new(); p->next = processes; p->stacksBottom = 0xDF000000; + p->heapseg = 0; p->next_objdesc = 0; p->objects = 0; @@ -289,6 +291,7 @@ 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; @@ -319,3 +322,24 @@ static void process_delete(struct process *pr) { } kfree(pr); } + +int process_setheapseg(size_t start, size_t end) { //syscall + struct process *p = current_thread->process; + if (start >= 0xE0000000 || end >= 0xE0000000) return -1; + if (p->heapseg == 0) { + struct segment *s = simpleseg_make(start, end - start, 1); + if (s == 0) return -5; + p->heapseg = seg_map(s, p->pagedir, 0); + if (p->heapseg == 0) return -1; + return 0; + } else if (p->heapseg->start != start) { + seg_unmap(p->heapseg); + struct segment *s = simpleseg_make(start, end - start, 1); + if (s == 0) return -5; + p->heapseg = seg_map(s, p->pagedir, 0); + if (p->heapseg == 0) return -1; + return 0; + } else { + return simpleseg_resize(p->heapseg, end - start); + } +} diff --git a/src/kernel/task/task.h b/src/kernel/task/task.h index 1c22785..3dad63d 100644 --- a/src/kernel/task/task.h +++ b/src/kernel/task/task.h @@ -32,6 +32,8 @@ struct process { struct obj_descriptor *objects; uint32_t next_objdesc; + struct segment_map *heapseg; + struct process *next; //Forms a linked list }; @@ -62,5 +64,6 @@ void thread_exit(); void process_exit(uint32_t retval); struct thread * thread_new(struct process *proc, thread_entry entry_point, void *data); struct process* process_new(struct process *parent, uint32_t uid, uint32_t privilege); +int process_setheapseg(size_t start, size_t end); //syscall #endif |