diff options
Diffstat (limited to 'src/loader/impl/mb1.c')
-rw-r--r-- | src/loader/impl/mb1.c | 58 |
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 } |