summaryrefslogtreecommitdiff
path: root/kernel/mboot
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/mboot')
-rw-r--r--kernel/mboot/mboot.c19
-rw-r--r--kernel/mboot/module.c42
2 files changed, 56 insertions, 5 deletions
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 79d092e..03c5147 100644
--- a/kernel/mboot/module.c
+++ b/kernel/mboot/module.c
@@ -1,3 +1,4 @@
+#include <comus/memory.h>
#include <comus/mboot.h>
#include "mboot.h"
@@ -12,13 +13,44 @@ struct multiboot_tag_module {
char cmdline[];
};
-void *mboot_get_initrd(size_t *len)
+static void *mapped_addr = NULL;
+size_t initrd_len;
+
+void *mboot_get_initrd_phys(size_t *len)
{
- void *tag = locate_mboot_table(MULTIBOOT_TAG_TYPE_MODULE);
+ struct multiboot_tag_module *mod;
+ void *tag, *phys;
+
+ // if already loaded, return
+ if (mapped_addr) {
+ *len = initrd_len;
+ return mapped_addr;
+ }
+
+ // locate
+ tag = locate_mboot_table(MULTIBOOT_TAG_TYPE_MODULE);
if (tag == NULL)
return NULL;
- struct multiboot_tag_module *mod = (struct multiboot_tag_module *)tag;
- *len = mod->mod_end - mod->mod_start;
- return (void *)(uintptr_t)mod->mod_start;
+ mod = (struct multiboot_tag_module *)tag;
+ 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;
+
+ return mapped_addr;
}