diff options
author | Alex Auvolat <alex.auvolat@ens.fr> | 2015-02-19 17:03:55 +0100 |
---|---|---|
committer | Alex Auvolat <alex.auvolat@ens.fr> | 2015-02-19 17:03:55 +0100 |
commit | 408faed4df730384538aaa0e338ae8ea7abe400d (patch) | |
tree | d391e7b94bab9de64ded62faf06d32f8a8340d3d /src/kernel | |
parent | 396a630f55aae0105ce56d302afaa937632d15ed (diff) | |
download | kogata-408faed4df730384538aaa0e338ae8ea7abe400d.tar.gz kogata-408faed4df730384538aaa0e338ae8ea7abe400d.zip |
Implement userspace malloc
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/include/process.h | 5 | ||||
-rw-r--r-- | src/kernel/user/process.c | 9 | ||||
-rw-r--r-- | src/kernel/user/syscall.c | 41 |
3 files changed, 41 insertions, 14 deletions
diff --git a/src/kernel/include/process.h b/src/kernel/include/process.h index edb25c3..5d9c3bf 100644 --- a/src/kernel/include/process.h +++ b/src/kernel/include/process.h @@ -16,11 +16,8 @@ #include <thread.h> #include <vfs.h> +#include <mmap.h> -// Modes for mmaping regions -#define MM_READ (0x01) -#define MM_WRITE (0x02) -#define MM_EXEC (0x04) #define USERSTACK_ADDR 0xB8000000 #define USERSTACK_SIZE 0x00020000 // 32 KB diff --git a/src/kernel/user/process.c b/src/kernel/user/process.c index fc608a7..6cba0f7 100644 --- a/src/kernel/user/process.c +++ b/src/kernel/user/process.c @@ -151,7 +151,8 @@ bool mmap(process_t *proc, void* addr, size_t size, int mode) { r->addr = addr; r->size = PAGE_ALIGN_UP(size); - if (r->addr >= (void*)K_HIGHHALF_ADDR || r->addr + r->size > (void*)K_HIGHHALF_ADDR || r->size == 0) { + if (r->addr >= (void*)K_HIGHHALF_ADDR || r->addr + r->size > (void*)K_HIGHHALF_ADDR + || r->addr + r->size <= r->addr || r->size == 0) { free(r); return false; } @@ -187,7 +188,8 @@ bool mmap_file(process_t *proc, fs_handle_t *h, size_t offset, void* addr, size_ r->addr = addr; r->size = PAGE_ALIGN_UP(size); - if (r->addr >= (void*)K_HIGHHALF_ADDR || r->addr + r->size > (void*)K_HIGHHALF_ADDR || r->size == 0) { + if (r->addr >= (void*)K_HIGHHALF_ADDR || r->addr + r->size > (void*)K_HIGHHALF_ADDR + || r->addr + r->size <= r->addr || r->size == 0) { free(r); return false; } @@ -257,7 +259,7 @@ bool munmap(process_t *proc, void* addr) { // Unmap that stuff pagedir_t *save_pd = get_current_pagedir(); switch_pagedir(proc->pd); - for (void* it = r->addr; it < r->addr + r->size; r += PAGE_SIZE) { + for (void* it = r->addr; it < r->addr + r->size; it += PAGE_SIZE) { uint32_t ent = pd_get_entry(it); uint32_t frame = pd_get_frame(it); @@ -293,6 +295,7 @@ static void proc_usermem_pf(void* p, registers_t *regs, void* addr) { user_region_t *r = find_user_region(proc, addr); if (r == 0) { dbg_printf("Segmentation fault in process %d (0x%p : not mapped) : exiting.\n", proc->pid, addr); + dbg_dump_registers(regs); exit(); } diff --git a/src/kernel/user/syscall.c b/src/kernel/user/syscall.c index 26032ad..ca5a65c 100644 --- a/src/kernel/user/syscall.c +++ b/src/kernel/user/syscall.c @@ -4,7 +4,11 @@ #include <syscall.h> -typedef uint32_t (*syscall_handler_t)(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); +typedef struct { + uint32_t sc_id, a, b, c, d, e; // a: ebx, b: ecx, c: edx, d: esi, e: edi +} sc_args_t; + +typedef uint32_t (*syscall_handler_t)(sc_args_t); static syscall_handler_t sc_handlers[SC_MAX] = { 0 }; @@ -25,21 +29,22 @@ static char* sc_copy_string(uint32_t s, uint32_t slen) { // THE SYSCALLS CODE !! // // ==================== // -static uint32_t exit_sc(uint32_t code, uint32_t uu1, uint32_t uu2, uint32_t uu3, uint32_t uu4) { - dbg_printf("Proc %d exit with code %d\n", current_process()->pid, code); + +static uint32_t exit_sc(sc_args_t args) { + dbg_printf("Proc %d exit with code %d\n", current_process()->pid, args.a); // TODO : use code... and process exiting is not supposed to be done this way exit(); return 0; } -static uint32_t yield_sc() { +static uint32_t yield_sc(sc_args_t args) { yield(); return 0; } -static uint32_t dbg_print_sc(uint32_t s, uint32_t slen, uint32_t uu2, uint32_t uu3, uint32_t uu4) { - char* msg = sc_copy_string(s, slen); +static uint32_t dbg_print_sc(sc_args_t args) { + char* msg = sc_copy_string(args.a, args.b); if (msg == 0) return -1; dbg_print(msg); @@ -48,6 +53,18 @@ static uint32_t dbg_print_sc(uint32_t s, uint32_t slen, uint32_t uu2, uint32_t u return 0; } +static uint32_t mmap_sc(sc_args_t args) { + return mmap(current_process(), (void*)args.a, args.b, args.c); +} + +static uint32_t mchmap_sc(sc_args_t args) { + return mchmap(current_process(), (void*)args.a, args.b); +} + +static uint32_t munmap_sc(sc_args_t args) { + return munmap(current_process(), (void*)args.a); +} + // ====================== // // SYSCALLS SETUP ROUTINE // // ====================== // @@ -56,6 +73,10 @@ void setup_syscalls() { sc_handlers[SC_EXIT] = exit_sc; sc_handlers[SC_YIELD] = yield_sc; sc_handlers[SC_DBG_PRINT] = dbg_print_sc; + + sc_handlers[SC_MMAP] = mmap_sc; + sc_handlers[SC_MCHMAP] = mchmap_sc; + sc_handlers[SC_MUNMAP] = munmap_sc; } void syscall_handler(registers_t *regs) { @@ -64,7 +85,13 @@ void syscall_handler(registers_t *regs) { if (regs->eax < SC_MAX) { syscall_handler_t h = sc_handlers[regs->eax]; if (h != 0) { - regs->eax = h(regs->ebx, regs->ecx, regs->edx, regs->esi, regs->edi); + sc_args_t args = { + .a = regs->ebx, + .b = regs->ecx, + .c = regs->edx, + .d = regs->esi, + .e = regs->edi}; + regs->eax = h(args); } else { regs->eax = -1; } |