summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/generic.h1
-rw-r--r--src/kernel/main.c2
-rw-r--r--src/kernel/mem.c15
-rw-r--r--src/kernel/mem.h3
4 files changed, 16 insertions, 5 deletions
diff --git a/src/arch/generic.h b/src/arch/generic.h
index f9617ab..4bed2fe 100644
--- a/src/arch/generic.h
+++ b/src/arch/generic.h
@@ -3,6 +3,7 @@
#include <arch/log.h>
// i have no idea where else to put it
+// some code assumes that it's a power of 2
#define PAGE_SIZE 4096
// src/arch/i386/boot.s
diff --git a/src/kernel/main.c b/src/kernel/main.c
index d2f2e7f..761e499 100644
--- a/src/kernel/main.c
+++ b/src/kernel/main.c
@@ -9,7 +9,7 @@ void r3_test();
void kmain(struct kmain_info info) {
log_write(info.init.at, info.init.size);
log_const("mem...");
- mem_init();
+ mem_init(&info);
log_const("creating process...");
struct process *proc = process_new(r3_test);
diff --git a/src/kernel/mem.c b/src/kernel/mem.c
index d002050..b455b25 100644
--- a/src/kernel/mem.c
+++ b/src/kernel/mem.c
@@ -1,11 +1,20 @@
#include <arch/generic.h>
#include <kernel/mem.h>
+#include <stdint.h>
-extern void *_bss_end;
static void *highest_page;
-void mem_init() {
- highest_page = &_bss_end;
+void mem_init(struct kmain_info *info) {
+ // finds the highest used page, and starts allocating pages above it
+ extern char _bss_end;
+ void *highest = &_bss_end;
+ size_t page_mask = PAGE_SIZE - 1;
+
+ if (highest < info->init.at + info->init.size)
+ highest = info->init.at + info->init.size;
+
+ // align up to PAGE_SIZE
+ highest_page = (void*)(((uintptr_t)highest + page_mask) & ~page_mask);
}
void *page_alloc(size_t pages) {
diff --git a/src/kernel/mem.h b/src/kernel/mem.h
index efa65d6..f608bb8 100644
--- a/src/kernel/mem.h
+++ b/src/kernel/mem.h
@@ -1,7 +1,8 @@
#pragma once
+#include <kernel/main.h>
#include <stddef.h>
-void mem_init();
+void mem_init(struct kmain_info *);
// allocates `pages` consecutive pages
void *page_alloc(size_t pages);