aboutsummaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
authorAlex Auvolat <alex.auvolat@ens.fr>2015-02-19 17:03:55 +0100
committerAlex Auvolat <alex.auvolat@ens.fr>2015-02-19 17:03:55 +0100
commit408faed4df730384538aaa0e338ae8ea7abe400d (patch)
treed391e7b94bab9de64ded62faf06d32f8a8340d3d /src/kernel
parent396a630f55aae0105ce56d302afaa937632d15ed (diff)
downloadkogata-408faed4df730384538aaa0e338ae8ea7abe400d.tar.gz
kogata-408faed4df730384538aaa0e338ae8ea7abe400d.zip
Implement userspace malloc
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/include/process.h5
-rw-r--r--src/kernel/user/process.c9
-rw-r--r--src/kernel/user/syscall.c41
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;
}