From 9ad0eafcf7e2f3e0532666c5353b0f5294401b06 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Tue, 20 Jul 2021 21:38:09 +0200 Subject: per-process virtual memory VGA is only mapped into the virtual memory because there are no other ways of interacting with the OS. --- src/init/main.c | 5 ++++- src/kernel/main.c | 33 +++++++++++++++------------------ src/kernel/proc.c | 21 ++++++++++++++++----- src/kernel/proc.h | 6 ++++-- 4 files changed, 39 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/init/main.c b/src/init/main.c index e6188ac..ce1600c 100644 --- a/src/init/main.c +++ b/src/init/main.c @@ -6,5 +6,8 @@ int main() { uint8_t *vga = (void*) 0xB8000; for (int i = 0; i < 80 * 25; i++) vga[(i << 1) + 1] = 0x4e; - for (;;); + + // try to mess with kernel memory + uint8_t *kernel = (void*) 0x100000; + *kernel = 0; // should segfault } diff --git a/src/kernel/main.c b/src/kernel/main.c index a59c014..729e39d 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -6,32 +6,29 @@ #include #include -static void setup_paging() { - struct pagedir *dir = pagedir_new(); +static void run_init(struct kmain_info *info) { + struct process *proc = process_new(); + void *init_base = (void*) 0x200000; - // map VGA - pagedir_map(dir, 0xB8000, 0xB8000, true, true); + // map VGA for testing + pagedir_map(proc->pages, 0xB8000, 0xB8000, true, true); - // map the kernel - for (size_t p = 0x100000; p < &_bss_end; p += PAGE_SIZE) - pagedir_map(dir, p, p, false, true); // yes, .text is writeable too + // map the module as rw + for (uintptr_t off = 0; off < info->init.size; off += PAGE_SIZE) + pagedir_map(proc->pages, init_base + off, info->init.at + off, + true, true); + proc->eip = init_base; - pagedir_switch(dir); + log_const("switching..."); + process_switch(proc); } void kmain(struct kmain_info info) { log_const("mem..."); mem_init(&info); - log_const("paging..."); - setup_paging(); - - log_const("creating process..."); + log_const("loading init..."); + run_init(&info); - void *init_addr = (void*)0x200000; - memcpy(init_addr, info.init.at, info.init.size); - - struct process *proc = process_new(init_addr); - log_const("switching..."); - process_switch(proc); + panic(); } diff --git a/src/kernel/proc.c b/src/kernel/proc.c index 4a931a5..6b80254 100644 --- a/src/kernel/proc.c +++ b/src/kernel/proc.c @@ -1,19 +1,30 @@ #include #include #include +#include struct process *process_current; -struct process *process_new(void *eip) { - struct process *proc; - proc = page_alloc(1); // TODO kmalloc - proc->stack_top = proc->esp = page_alloc(1) + 1 * PAGE_SIZE; - proc->eip = eip; +struct process *process_new() { + struct process *proc = page_alloc(1); // TODO kmalloc + proc->pages = pagedir_new(); + // map the stack to the last page in memory + pagedir_map(proc->pages, (void*)~PAGE_MASK, page_alloc(1), true, true); + proc->stack_top = proc->esp = (void*) ~0; + + // map the kernel + // yup, .text is writeable too. the plan is to not map the kernel + // into user memory at all, but i'll implement that later. TODO + for (size_t p = 0x100000; p < &_bss_end; p += PAGE_SIZE) + pagedir_map(proc->pages, (void*)p, (void*)p, false, true); + + // the kernel still has to load the executable code and set EIP return proc; } void process_switch(struct process *proc) { process_current = proc; + pagedir_switch(proc->pages); sysexit(proc->eip, proc->esp); } diff --git a/src/kernel/proc.h b/src/kernel/proc.h index 976b275..745db8d 100644 --- a/src/kernel/proc.h +++ b/src/kernel/proc.h @@ -1,13 +1,15 @@ #pragma once +#include struct process { void *stack_top; void *esp; - void *eip; + + struct pagedir *pages; }; extern struct process *process_current; -struct process *process_new(void *eip); +struct process *process_new(); void process_switch(struct process *proc); -- cgit v1.2.3