From 4ecec1eec682a9b39eba26bdd1c35b3f9542bd8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Thu, 1 Mar 2018 15:12:35 +0100 Subject: [PATCH] Stupidly simple process memory manager with brk() --- src/kernel/boot/kmain.c | 4 ++-- src/kernel/include/memory.h | 4 ++-- src/kernel/include/process.h | 7 ++++++- src/kernel/memory/vmm.c | 4 ++-- src/kernel/proc/process.c | 8 +++++--- src/kernel/proc/procmm.c | 24 ++++++++++++++++++++++++ 6 files changed, 41 insertions(+), 10 deletions(-) create mode 100644 src/kernel/proc/procmm.c diff --git a/src/kernel/boot/kmain.c b/src/kernel/boot/kmain.c index 0b7f20e..4fdbc94 100644 --- a/src/kernel/boot/kmain.c +++ b/src/kernel/boot/kmain.c @@ -29,8 +29,8 @@ void kmain(uint64_t multiboot_magic, void *multiboot_data) cpu_init(); struct process *p1 = new_process((void (*)(void))0x10000); - vmm_set_page(p1->P4, 0x10000, pmm_calloc(), PAGE_WRITE | PAGE_PRESENT | PAGE_USER); - memcpy_k2u(p1->P4, (void *)0x10000, (void *)(uintptr_t)thread_function, 100); + procmm_brk(p1, (void *)0x10010); + memcpy_to_p4(p1->P4, (void *)0x10000, (void *)(uintptr_t)thread_function, 100); ready(p1); diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 849cd9f..671f3f8 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -45,8 +45,8 @@ uint64_t vmm_get_page(uint64_t P4, uint64_t addr); #define PAGE_EXIST(p) ((p) != (uint64_t)-1) int vmm_set_page(uint64_t P4, uint64_t addr, uint64_t page, uint16_t flags); void vmm_clear_page(uint64_t P4, uint64_t addr, int free); -size_t memcpy_k2u(uint64_t P4, void *dst, void *src, size_t n); -size_t memcpy_u2k(void *dst, uint64_t P4, void *src, size_t n); +size_t memcpy_to_p4(uint64_t P4, void *dst, void *src, size_t n); +size_t memcpy_from_p4(void *dst, uint64_t P4, void *src, size_t n); extern union PTE BootP4; extern int kernel_start, kernel_end; diff --git a/src/kernel/include/process.h b/src/kernel/include/process.h index 5473bb6..3b63546 100644 --- a/src/kernel/include/process.h +++ b/src/kernel/include/process.h @@ -3,15 +3,18 @@ #include #include #include +#include struct process { uint64_t pid; void *stack_ptr; uint64_t state; + uint64_t P4; + uint64_t brk; + uint64_t stack; QUEUE_SPOT(runQ); - uint8_t stack[]; }; struct process *process(); @@ -21,3 +24,5 @@ void yield(); void start_scheduler(); void switch_stack(void *old_ptr, void *new_ptr); + +uint64_t procmm_brk(struct process *p, void *addr); diff --git a/src/kernel/memory/vmm.c b/src/kernel/memory/vmm.c index b13abd1..96099a9 100644 --- a/src/kernel/memory/vmm.c +++ b/src/kernel/memory/vmm.c @@ -106,7 +106,7 @@ void vmm_clear_page(uint64_t P4, uint64_t addr, int free) #define min(a,b) (((a) < (b))?(a):(b)) #define offset(p) ((uintptr_t)(p) % PAGE_SIZE) #define remaining(p) (PAGE_SIZE - offset(p)) -size_t memcpy_k2u(uint64_t P4, void *dst, void *src, size_t n) +size_t memcpy_to_p4(uint64_t P4, void *dst, void *src, size_t n) { size_t copied = 0; while(n) @@ -127,7 +127,7 @@ size_t memcpy_k2u(uint64_t P4, void *dst, void *src, size_t n) return copied; } -size_t memcpy_u2k(void *dst, uint64_t P4, void *src, size_t n) +size_t memcpy_from_p4(void *dst, uint64_t P4, void *src, size_t n) { size_t copied = 0; while(n) diff --git a/src/kernel/proc/process.c b/src/kernel/proc/process.c index 9dee224..9e6b4ca 100644 --- a/src/kernel/proc/process.c +++ b/src/kernel/proc/process.c @@ -20,13 +20,15 @@ struct swtch_stack struct process *sched_proc = 0; struct process *_proc = 0; +void procmm_init(struct process *p); + uint64_t next_pid = 1; struct process *new_process(void (*function)(void)) { struct process *proc = P2V(pmm_calloc()); proc->pid = next_pid++; proc->stack_ptr = incptr(proc, PAGE_SIZE - sizeof(struct swtch_stack)); - proc->P4 = new_P4(); + procmm_init(proc); struct swtch_stack *stk = proc->stack_ptr; stk->RBP = (uint64_t)&stk->RBP2; @@ -38,7 +40,7 @@ struct process *new_process(void (*function)(void)) stk->r.cs = 0x10 | 3; stk->r.ss = 0x18 | 3; stk->r.rflags = 3<<12; - stk->r.rsp = 0x10FFF; + stk->r.rsp = KERNEL_OFFSET; return proc; } @@ -62,7 +64,7 @@ void scheduler() _proc = new; write_cr3(new->P4); - interrupt_stack(new + PAGE_SIZE); + interrupt_stack(incptr(new, PAGE_SIZE)); switch_stack(&sched_proc->stack_ptr, &new->stack_ptr); ready(_proc); diff --git a/src/kernel/proc/procmm.c b/src/kernel/proc/procmm.c new file mode 100644 index 0000000..0c8c9f3 --- /dev/null +++ b/src/kernel/proc/procmm.c @@ -0,0 +1,24 @@ +#include +#include +#include +#include +#include +#include + +void procmm_init(struct process *p) +{ + p->P4 = new_P4(); + p->brk = 0; + p->stack = KERNEL_OFFSET; + +} + +uint64_t procmm_brk(struct process *p, void *addr) +{ + while((uint64_t)addr > p->brk) + { + vmm_set_page(p->P4, p->brk, pmm_alloc(), PAGE_USER | PAGE_WRITE | PAGE_PRESENT); + p->brk += PAGE_SIZE; + } + return p->brk; +}