summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-05-06 12:34:48 -0400
committerFreya Murphy <freya@freyacat.org>2025-05-06 12:35:41 -0400
commit40bfcbb2cf8a39e58ec19b21956caaf4685c9b8b (patch)
tree3e2b5aa933b9f06ad1ed7aca2f63b0d79d36fa02
parentremove sym lookup (diff)
downloadcomus-40bfcbb2cf8a39e58ec19b21956caaf4685c9b8b.tar.gz
comus-40bfcbb2cf8a39e58ec19b21956caaf4685c9b8b.tar.bz2
comus-40bfcbb2cf8a39e58ec19b21956caaf4685c9b8b.zip
terrible hack to not overwrite mboot data
-rw-r--r--kernel/include/comus/mboot.h10
-rw-r--r--kernel/mboot/mboot.c19
-rw-r--r--kernel/mboot/module.c16
-rw-r--r--kernel/memory/physalloc.c24
4 files changed, 58 insertions, 11 deletions
diff --git a/kernel/include/comus/mboot.h b/kernel/include/comus/mboot.h
index aba3e4e..bed29f1 100644
--- a/kernel/include/comus/mboot.h
+++ b/kernel/include/comus/mboot.h
@@ -47,4 +47,14 @@ EFI_HANDLE mboot_get_efi_hdl(void);
*/
void *mboot_get_initrd(size_t *len);
+/**
+ * Returns the physical pointer to the loaded init ram disk with size given by len
+ */
+void *mboot_get_initrd_phys(size_t *len);
+
+/**
+ * Gets the end of the mboot pointer
+ */
+void *mboot_end(void);
+
#endif /* mboot.h */
diff --git a/kernel/mboot/mboot.c b/kernel/mboot/mboot.c
index e4547e7..8163f04 100644
--- a/kernel/mboot/mboot.c
+++ b/kernel/mboot/mboot.c
@@ -5,6 +5,8 @@
static volatile void *mboot = NULL;
+extern char kernel_end[];
+
void mboot_init(long magic, volatile void *ptr)
{
if (magic != MULTIBOOT2_BOOTLOADER_MAGIC)
@@ -12,6 +14,23 @@ void mboot_init(long magic, volatile void *ptr)
mboot = ptr;
}
+void *mboot_end(void)
+{
+ if (mboot == NULL)
+ return NULL;
+
+ struct multiboot *info = (struct multiboot *)mboot;
+ uintptr_t mboot_end, initrd_end;
+ size_t initrd_len;
+
+ mboot_end = (uintptr_t)info + info->total_size;
+ initrd_end = (uintptr_t)mboot_get_initrd_phys(&initrd_len);
+ if (initrd_end)
+ initrd_end += initrd_len;
+
+ return (void *)MAX(mboot_end, initrd_end);
+}
+
void *locate_mboot_table(uint32_t type)
{
if (mboot == NULL)
diff --git a/kernel/mboot/module.c b/kernel/mboot/module.c
index bf15eca..03c5147 100644
--- a/kernel/mboot/module.c
+++ b/kernel/mboot/module.c
@@ -1,4 +1,4 @@
-#include "comus/memory.h"
+#include <comus/memory.h>
#include <comus/mboot.h>
#include "mboot.h"
@@ -16,7 +16,7 @@ struct multiboot_tag_module {
static void *mapped_addr = NULL;
size_t initrd_len;
-void *mboot_get_initrd(size_t *len)
+void *mboot_get_initrd_phys(size_t *len)
{
struct multiboot_tag_module *mod;
void *tag, *phys;
@@ -36,11 +36,21 @@ void *mboot_get_initrd(size_t *len)
phys = (void *)(uintptr_t)mod->mod_start;
initrd_len = mod->mod_end - mod->mod_start;
+ *len = initrd_len;
+ return phys;
+}
+
+void *mboot_get_initrd(size_t *len)
+{
+ // get phys
+ void *phys = mboot_get_initrd_phys(len);
+ if (phys == NULL)
+ return NULL;
+
// map addr
mapped_addr = kmapaddr(phys, NULL, initrd_len, F_PRESENT | F_WRITEABLE);
if (mapped_addr == NULL)
return NULL;
- *len = initrd_len;
return mapped_addr;
}
diff --git a/kernel/memory/physalloc.c b/kernel/memory/physalloc.c
index 47522b8..7551c75 100644
--- a/kernel/memory/physalloc.c
+++ b/kernel/memory/physalloc.c
@@ -1,12 +1,14 @@
-#include "lib/kio.h"
#include <lib.h>
#include <comus/memory.h>
#include <comus/asm.h>
+#include <comus/mboot.h>
+#include <stdint.h>
#include "physalloc.h"
extern char kernel_start[];
extern char kernel_end[];
+static void *kernel_real_end = NULL;
// between memory_start and kernel_start will be the bitmap
static uintptr_t memory_start = 0;
@@ -30,16 +32,17 @@ static int n_pages(const struct memory_segment *m)
return (m->len + PAGE_SIZE - 1) / PAGE_SIZE;
}
-static void *page_at(int i)
+static void *page_at(size_t i)
{
- int cur_page = 0;
+ size_t cur_page = 0;
+ const struct memory_segment *m = page_start;
for (uint64_t idx = 0; idx < segment_count; idx++) {
- const struct memory_segment *m = page_start;
- int pages = n_pages(m);
+ size_t pages = n_pages(m);
if (i - cur_page < pages) {
return (void *)(m->addr + (PAGE_SIZE * (i - cur_page)));
}
cur_page += pages;
+ m++;
}
return NULL;
}
@@ -48,8 +51,8 @@ static long page_idx(void *page)
{
uintptr_t addr = (uintptr_t)page;
int cur_page = 0;
+ const struct memory_segment *m = page_start;
for (uint64_t idx = 0; idx < segment_count; idx++) {
- const struct memory_segment *m = page_start;
if (addr < m->addr) {
return -1;
}
@@ -57,6 +60,7 @@ static long page_idx(void *page)
return cur_page + ((addr - m->addr) / PAGE_SIZE);
}
cur_page += n_pages(m);
+ m++;
}
return -1;
}
@@ -211,7 +215,7 @@ static struct memory_segment clamp_segment(const struct memory_segment *segment)
if (memory_start)
start = memory_start;
else
- start = (uintptr_t)kernel_end;
+ start = (uintptr_t)kernel_real_end;
if (segment->addr < start) {
addr = start;
@@ -243,6 +247,10 @@ void physalloc_init(struct memory_map *map)
segment_count = 0;
+ kernel_real_end = mboot_end();
+ if ((char *)kernel_real_end < kernel_end)
+ kernel_real_end = kernel_end;
+
for (uint32_t i = 0; i < map->entry_count; i++) {
struct memory_segment *segment = &map->entries[i];
@@ -256,7 +264,7 @@ void physalloc_init(struct memory_map *map)
long bitmap_pages = (page_count / 64 / PAGE_SIZE) + 1;
long bitmap_size = bitmap_pages * PAGE_SIZE;
- bitmap = (uint64_t *)page_align((uintptr_t)kernel_end);
+ bitmap = (uint64_t *)page_align((uintptr_t)kernel_real_end);
long page_area_size = segment_count * sizeof(struct memory_segment);
char *page_area_addr = (char *)bitmap + bitmap_size;