summaryrefslogtreecommitdiffhomepage
path: root/src/loader/impl/mb1.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/loader/impl/mb1.c')
-rw-r--r--src/loader/impl/mb1.c58
1 files changed, 47 insertions, 11 deletions
diff --git a/src/loader/impl/mb1.c b/src/loader/impl/mb1.c
index 765433e..5541c6e 100644
--- a/src/loader/impl/mb1.c
+++ b/src/loader/impl/mb1.c
@@ -3,9 +3,11 @@
#include <elf.h>
#include <impl/mb1.h>
+#include <lib.h>
#include <pnc.h>
-#define MB1_MAGIC 0x1badb002
+// The address where data gets stored
+#define MB1_LOAD_ADDRESS 0x10000
struct multiboot_entry {
u32 magic;
@@ -28,12 +30,43 @@ static u32 mb1_checksum(struct multiboot_entry *entry)
return -(entry->magic + entry->flags);
}
+// Load data into memory and return address (not overlapping
+static u32 mb1_store(void *data, u32 size)
+{
+ static u32 offset = 0;
+ memcpy((void *)MB1_LOAD_ADDRESS, data, size);
+ offset += size;
+ return MB1_LOAD_ADDRESS + (size - offset);
+}
+
+// Load the mb1 structs into memory
+static void mb1_load(struct multiboot_entry *entry)
+{
+ (void)mb1_store;
+ (void)entry;
+}
+
+// Jump to kernel with correct info pointer in eax
+static void mb1_jump(u32 entry, u32 info)
+{
+ log("Jumping. So long and thanks for all the fish!\n");
+
+ // Move and jump!
+ __asm__ volatile("movl $" STRINGIFY(MB1_LOAD_MAGIC) ", %%eax\n\t"
+ "jmpl *%%edi\n\t"
+ :
+ : "D"(entry), "b"(info)
+ : "memory");
+
+ panic("Jumper returned\n");
+}
+
// Detect and verify mb1
-u8 mb1_detect(struct dev *dev, const char *path)
+u8 mb1_detect(struct cfg_entry *cfg)
{
u8 header[8192] = { 0 };
- s32 ret = dev->p.disk.fs.read(path, header, 0, sizeof(header), dev);
+ s32 ret = cfg->dev->p.disk.fs.read(cfg->path, header, 0, sizeof(header), cfg->dev);
if (ret < 12)
return 0;
@@ -54,19 +87,22 @@ u8 mb1_detect(struct dev *dev, const char *path)
if (checksum != entry->checksum)
return 0;
- dev->p.disk.impl.type = IMPL_MB1;
- dev->p.disk.impl.start = entry;
+ cfg->impl.type = IMPL_MB1;
+ cfg->impl.start = entry;
return 1;
}
+#include <pic.h>
+
// Execute mb1 type kernel
-void mb1_exec(struct dev *dev, const char *path)
+void mb1_exec(struct cfg_entry *cfg)
{
- u32 entry = elf_load(dev, path);
- void (*kernel)(void *);
- *(void **)(&kernel) = (void *)entry;
+ u32 entry = elf_load(cfg->dev, cfg->path);
+ mb1_load(cfg->impl.start);
- // TODO: Push mb1 stuff
- kernel(dev);
+ // This is a kind of hacky parameter stack pushing thing, just disable warning :)
+#pragma GCC diagnostic ignored "-Wpedantic"
+ jmp_kernel((void *)mb1_jump, 2, entry, MB1_LOAD_ADDRESS);
+#pragma GCC diagnostic pop
}