summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMarvin Borner2021-07-07 19:13:11 +0200
committerMarvin Borner2021-07-07 19:13:11 +0200
commit9a2d5cbdc7972d1d5bfb1ea93f82f66d113faa17 (patch)
tree08ceb8427b64a08c89a5526dfbf8b66c78f9d12c
parent6355c3e08c9f4d3db122252abce5837c364d5b81 (diff)
Strange implementations
-rw-r--r--example/mb1/main.c15
-rw-r--r--example/mb2/entry.asm51
-rw-r--r--example/mb2/link.ld33
-rw-r--r--example/mb2/main.c31
-rw-r--r--example/mb2/makefile16
-rw-r--r--example/segelboot.cfg2
-rw-r--r--makefile5
-rw-r--r--src/loader/cfg.c16
-rw-r--r--src/loader/impl/all.c18
-rw-r--r--src/loader/impl/mb1.c58
-rw-r--r--src/loader/impl/mb2.c100
-rw-r--r--src/loader/inc/acpi.h2
-rw-r--r--src/loader/inc/cfg.h5
-rw-r--r--src/loader/inc/def.h3
-rw-r--r--src/loader/inc/dev.h2
-rw-r--r--src/loader/inc/impl.h20
-rw-r--r--src/loader/inc/impl/all.h20
-rw-r--r--src/loader/inc/impl/mb1.h126
-rw-r--r--src/loader/inc/impl/mb2.h61
-rw-r--r--src/loader/inc/pnc.h3
-rw-r--r--src/loader/jmp.asm28
-rw-r--r--src/loader/log.c2
22 files changed, 568 insertions, 49 deletions
diff --git a/example/mb1/main.c b/example/mb1/main.c
index 0174803..d572977 100644
--- a/example/mb1/main.c
+++ b/example/mb1/main.c
@@ -1,6 +1,16 @@
// MIT License, Copyright (c) 2021 Marvin Borner
typedef unsigned int u32;
+typedef unsigned short u16;
+typedef unsigned char u8;
+
+static void draw(u8 color, u8 data)
+{
+ u16 *out = (u16 *)0xb8000;
+ for (u16 i = 0; i < 80 * 25; i++) {
+ out[i] = data | (color << 8);
+ }
+}
int kernel_main(u32 magic, u32 addr, u32 esp); // Decl
int kernel_main(u32 magic, u32 addr, u32 esp)
@@ -9,6 +19,11 @@ int kernel_main(u32 magic, u32 addr, u32 esp)
(void)addr;
(void)esp;
+ if (magic == 0x2badb002)
+ draw(0x02, 'y');
+ else
+ draw(0x04, 'n');
+
while (1)
;
diff --git a/example/mb2/entry.asm b/example/mb2/entry.asm
new file mode 100644
index 0000000..063ac74
--- /dev/null
+++ b/example/mb2/entry.asm
@@ -0,0 +1,51 @@
+; MIT License, Copyright (c) 2021 Marvin Borner
+
+bits 32
+
+MAGIC equ 0xe85250d6
+ARCHITECHTURE equ 0
+HEADER_LENGTH equ multiboot_header_end - multiboot_header_start
+CHECKSUM equ 0x100000000 - (MAGIC + ARCHITECHTURE + HEADER_LENGTH)
+
+multiboot_header_start:
+ dd MAGIC
+ dd ARCHITECHTURE
+ dd HEADER_LENGTH
+ dd CHECKSUM
+entry_address_tag_start:
+ dw 3
+ dw 0
+ dd entry_address_tag_end - entry_address_tag_start
+ dd 0 ; low
+ dd boot_entry ; high
+entry_address_tag_end:
+framebuffer_tag_start:
+ dw 5
+ dw 0
+ dd framebuffer_tag_end - framebuffer_tag_start
+ dd 1920
+ dd 1200
+ dd 32
+framebuffer_tag_end:
+ dw 0
+ dw 0
+ dd 8
+multiboot_header_end:
+
+global boot_entry
+extern kernel_main
+boot_entry:
+ mov esp, stack_top
+ push esp
+ push ebx
+ push eax
+ cli
+ call kernel_main
+ hlt
+ jmp $
+
+section .bss
+align 32
+stack_bottom:
+ resb 0x4000
+stack_top:
diff --git a/example/mb2/link.ld b/example/mb2/link.ld
new file mode 100644
index 0000000..0d79ef4
--- /dev/null
+++ b/example/mb2/link.ld
@@ -0,0 +1,33 @@
+/* MIT License, Copyright (c) 2021 Marvin Borner */
+
+OUTPUT_ARCH(i386)
+ENTRY(boot_entry)
+phys = 0x00100000;
+
+SECTIONS
+{
+ . = phys;
+
+ .text BLOCK(4K) : ALIGN(4K)
+ {
+ *(.text*)
+ }
+
+ .rodata BLOCK(4K) : ALIGN(4K)
+ {
+ *(.rodata*)
+ }
+
+ .data BLOCK(4K) : ALIGN(4K)
+ {
+ *(.data*)
+ }
+
+ .bss BLOCK(4K) : ALIGN(4K)
+ {
+ *(COMMON)
+ *(.bss)
+ }
+
+ end = .;
+}
diff --git a/example/mb2/main.c b/example/mb2/main.c
new file mode 100644
index 0000000..3c7b064
--- /dev/null
+++ b/example/mb2/main.c
@@ -0,0 +1,31 @@
+// MIT License, Copyright (c) 2021 Marvin Borner
+
+typedef unsigned int u32;
+typedef unsigned short u16;
+typedef unsigned char u8;
+
+static void draw(u8 color, u8 data)
+{
+ u16 *out = (u16 *)0xb8000;
+ for (u16 i = 0; i < 80 * 25; i++) {
+ out[i] = data | (color << 8);
+ }
+}
+
+int kernel_main(u32 magic, u32 addr, u32 esp); // Decl
+int kernel_main(u32 magic, u32 addr, u32 esp)
+{
+ (void)magic;
+ (void)addr;
+ (void)esp;
+
+ if (magic == 0x36d76289)
+ draw(0x02, 'y');
+ else
+ draw(0x04, 'n');
+
+ while (1)
+ ;
+
+ return 1;
+}
diff --git a/example/mb2/makefile b/example/mb2/makefile
new file mode 100644
index 0000000..0976447
--- /dev/null
+++ b/example/mb2/makefile
@@ -0,0 +1,16 @@
+# MIT License, Copyright (c) 2021 Marvin Borner
+# Gets called by main makefile (their variables are exported)
+
+OBJS = entry_asm.o main.o
+
+all: compile
+
+%.o: %.c
+ @$(CC) -c $(CFLAGS) $< -o $@
+
+%_asm.o: %.asm
+ @$(AS) $(ASFLAGS) $< -o $@
+
+compile: $(OBJS)
+ @mkdir -p $(BLD)/examples/
+ @$(LD) -N -z max-page-size=0x1000 -eboot_entry -Tlink.ld -o $(BLD)/examples/mb2.elf $+
diff --git a/example/segelboot.cfg b/example/segelboot.cfg
index 65938eb..d30fc0d 100644
--- a/example/segelboot.cfg
+++ b/example/segelboot.cfg
@@ -4,4 +4,4 @@ TIMEOUT=10
PATH=hda0:/boot/mb1.elf
# Multiboot 2 (TODO)
-PATH=hda0:/boot/mb1.elf
+PATH=hda0:/boot/mb2.elf
diff --git a/makefile b/makefile
index 3d310d0..1622d7b 100644
--- a/makefile
+++ b/makefile
@@ -29,7 +29,7 @@ ASFLAGS = -f elf32
export
-all: dir $(BLD)/boot.bin mb1
+all: dir $(BLD)/boot.bin mb1 mb2
dir:
@mkdir -p $(BLD)/entry/
@@ -39,6 +39,9 @@ dir:
mb1:
@$(MAKE) --no-print-directory -C example/$@
+mb2:
+ @$(MAKE) --no-print-directory -C example/$@
+
$(BLD)/boot.bin: $(BLD)/loader.bin
@$(AS) $(ASFLAGS) -f bin $(SRC)/entry/bootsector.asm -o $@
diff --git a/src/loader/cfg.c b/src/loader/cfg.c
index 2c6cce3..bbe215a 100644
--- a/src/loader/cfg.c
+++ b/src/loader/cfg.c
@@ -2,6 +2,7 @@
#include <cfg.h>
#include <dev.h>
+#include <impl/all.h>
#include <lib.h>
#include <log.h>
#include <pnc.h>
@@ -53,7 +54,7 @@ static void cfg_add(u8 index, enum cfg_key key, const char *value)
break;
case CFG_PATH:
cfg_in_entry(index);
- strlcpy(entry->path, value, sizeof(entry->path));
+ strlcpy(entry->full_path, value, sizeof(entry->full_path));
break;
case CFG_NONE:
default:
@@ -151,8 +152,8 @@ static void cfg_verify(void)
for (u8 i = 0; i < COUNT(cfg.entry) && cfg.entry[i].exists; i++) {
struct cfg_entry *entry = &cfg.entry[i];
- u8 len = cfg_path_disk(entry->path);
- struct dev *dev = dev_get_by_name(entry->path, len);
+ u8 len = cfg_path_disk(entry->full_path);
+ struct dev *dev = dev_get_by_name(entry->full_path, len);
if (!dev || dev->type != DEV_DISK)
panic("Invalid device in config\n");
entry->dev = dev;
@@ -161,14 +162,15 @@ static void cfg_verify(void)
panic("Device fs not readable\n");
// This is now the correct path (due to "disk:PATH")
- const char *path = &entry->path[len + 1];
+ const char *path = &entry->full_path[len + 1];
+ entry->path = path;
u8 buf[1] = { 0 }; // Just for existence-check
s32 ret = dev->p.disk.fs.read(path, buf, 0, sizeof(buf), dev);
if (ret != 1 || !buf[0])
panic("Path is invalid\n");
- if (!impl_detect(dev, path))
+ if (!impl_detect(entry))
panic("No boot implementation found\n");
}
}
@@ -188,13 +190,13 @@ static void cfg_print(void)
log("[CFG] Global: %d\n", cfg.timeout);
for (u8 i = 0; i < COUNT(cfg.entry) && cfg.entry[i].exists; i++)
- log("[CFG] Entry: %s at %s\n", cfg.entry[i].name, cfg.entry[i].path);
+ log("[CFG] Entry: %s at %s\n", cfg.entry[i].name, cfg.entry[i].full_path);
}
// Execute entry implementation
void cfg_exec(struct cfg_entry *entry)
{
- impl_exec(entry->dev, &entry->path[cfg_path_disk(entry->path) + 1]);
+ impl_exec(entry);
}
void cfg_read(void)
diff --git a/src/loader/impl/all.c b/src/loader/impl/all.c
index a5c93b1..941986d 100644
--- a/src/loader/impl/all.c
+++ b/src/loader/impl/all.c
@@ -2,25 +2,31 @@
#include <impl/all.h>
#include <impl/mb1.h>
+#include <impl/mb2.h>
#include <pnc.h>
-u8 impl_detect(struct dev *dev, const char *path)
+u8 impl_detect(struct cfg_entry *cfg)
{
- if (mb1_detect(dev, path))
+ if (mb1_detect(cfg))
+ return 1;
+
+ if (mb2_detect(cfg))
return 1;
return 0;
}
-void impl_exec(struct dev *dev, const char *path)
+void impl_exec(struct cfg_entry *cfg)
{
- assert(dev->type == DEV_DISK);
+ assert(cfg->dev->type == DEV_DISK);
- switch (dev->p.disk.impl.type) {
+ switch (cfg->impl.type) {
case IMPL_MB1:
- mb1_exec(dev, path);
+ mb1_exec(cfg);
break;
case IMPL_MB2:
+ mb2_exec(cfg);
+ break;
case IMPL_NONE:
default:
panic("Invalid implementation\n");
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
}
diff --git a/src/loader/impl/mb2.c b/src/loader/impl/mb2.c
new file mode 100644
index 0000000..f46310b
--- /dev/null
+++ b/src/loader/impl/mb2.c
@@ -0,0 +1,100 @@
+// MIT License, Copyright (c) 2021 Marvin Borner
+// Everything according to spec
+
+#include <elf.h>
+#include <impl/mb2.h>
+#include <lib.h>
+#include <pnc.h>
+
+// The address where data gets stored
+#define MB2_LOAD_ADDRESS 0x10000
+
+struct multiboot_entry {
+ u32 magic;
+ u32 flags;
+ u32 header_length;
+ u32 checksum; // Everything after that is optional
+ u8 *tags;
+};
+
+// The (really simple) multiboot checksum algorithm
+/* static u32 mb2_checksum(struct multiboot_entry *entry) */
+/* { */
+/* return -(entry->magic + entry->flags); */
+/* } */
+
+// Load data into memory and return address (not overlapping
+static u32 mb2_store(void *data, u32 size)
+{
+ static u32 offset = 0;
+ memcpy((void *)MB2_LOAD_ADDRESS, data, size);
+ offset += size;
+ return MB2_LOAD_ADDRESS + (size - offset);
+}
+
+// Load the mb2 structs into memory
+static void mb2_load(struct multiboot_entry *entry)
+{
+ (void)mb2_store;
+ (void)entry;
+}
+
+// Jump to kernel with correct info pointer in eax
+static void mb2_jump(u32 entry, u32 info)
+{
+ log("Jumping. So long and thanks for all the fish!\n");
+
+ // Move and jump!
+ __asm__ volatile("movl $" STRINGIFY(MB2_LOAD_MAGIC) ", %%eax\n\t"
+ "jmpl *%%edi\n\t"
+ :
+ : "D"(entry), "b"(info)
+ : "memory");
+
+ panic("Jumper returned\n");
+}
+
+// Detect and verify mb2
+u8 mb2_detect(struct cfg_entry *cfg)
+{
+ u8 header[8192] = { 0 };
+
+ s32 ret = cfg->dev->p.disk.fs.read(cfg->path, header, 0, sizeof(header), cfg->dev);
+ if (ret < 12)
+ return 0;
+
+ // Find start of multiboot entry by searching for magic
+ struct multiboot_entry *entry = 0;
+ for (u32 i = 0; i < sizeof(header); i++) {
+ u32 *p = (u32 *)&header[i];
+ if (*p == MB2_MAGIC) {
+ entry = (void *)p;
+ break;
+ }
+ }
+
+ if (!entry)
+ return 0;
+
+ // TODO: mb2 checksum
+ /* u32 checksum = mb2_checksum(entry); */
+ /* if (checksum != entry->checksum) */
+ /* return 0; */
+
+ cfg->impl.type = IMPL_MB2;
+ cfg->impl.start = entry;
+
+ return 1;
+}
+
+// Execute mb2 type kernel
+void mb2_exec(struct cfg_entry *cfg)
+{
+ u32 entry = elf_load(cfg->dev, cfg->path);
+ mb2_load(cfg->impl.start);
+
+ // This is a kind of hacky parameter stack pushing thing, just disable warning :)
+#pragma GCC diagnostic ignored "-Wpedantic"
+ jmp_kernel((void *)mb2_jump, 2, entry, MB2_LOAD_ADDRESS);
+#pragma GCC diagnostic pop
+}
diff --git a/src/loader/inc/acpi.h b/src/loader/inc/acpi.h
index f7626e9..f1794b9 100644
--- a/src/loader/inc/acpi.h
+++ b/src/loader/inc/acpi.h
@@ -40,8 +40,8 @@ struct generic_address {
u8 bit_width;
u8 bit_offset;
u8 access_size;
- u32 phys_high;
u32 phys_low;
+ u32 phys_high;
};
/**
diff --git a/src/loader/inc/cfg.h b/src/loader/inc/cfg.h
index 156d561..f3a15ab 100644
--- a/src/loader/inc/cfg.h
+++ b/src/loader/inc/cfg.h
@@ -4,6 +4,7 @@
#define CFG_H
#include <def.h>
+#include <impl.h>
// Global config element index (can actually be anything but wth)
#define CFG_GLOBAL 0
@@ -18,8 +19,10 @@ enum cfg_key {
struct cfg_entry {
u8 exists : 1;
char name[64];
- char path[64];
+ char full_path[64]; // With disk name
+ const char *path; // Without disk name
struct dev *dev;
+ struct impl impl;
};
struct cfg {
diff --git a/src/loader/inc/def.h b/src/loader/inc/def.h
index 3532bc1..a8ee30b 100644
--- a/src/loader/inc/def.h
+++ b/src/loader/inc/def.h
@@ -25,6 +25,9 @@ typedef __builtin_va_list va_list;
#define COUNT(a) (sizeof(a) / sizeof 0 [a])
#define UNUSED(a) ((void)a);
+#define STRINGIFY_PARAM(a) #a
+#define STRINGIFY(a) STRINGIFY_PARAM(a)
+
#define PACKED __attribute__((packed))
#endif
diff --git a/src/loader/inc/dev.h b/src/loader/inc/dev.h
index 9e64bdb..7120a83 100644
--- a/src/loader/inc/dev.h
+++ b/src/loader/inc/dev.h
@@ -5,7 +5,6 @@
#include <def.h>
#include <dsk.h>
-#include <impl/all.h>
enum dev_type {
DEV_DISK,
@@ -23,7 +22,6 @@ struct dev {
union {
struct {
struct fs fs;
- struct impl impl;
} disk;
// TODO: Other (framebuffer?)
} p; // Prototype union
diff --git a/src/loader/inc/impl.h b/src/loader/inc/impl.h
new file mode 100644
index 0000000..c7b1261
--- /dev/null
+++ b/src/loader/inc/impl.h
@@ -0,0 +1,20 @@
+// MIT License, Copyright (c) 2021 Marvin Borner
+
+#ifndef IMPL_H
+#define IMPL_H
+
+#include <dev.h>
+
+enum impl_type {
+ IMPL_NONE,
+ IMPL_MB1,
+ IMPL_MB2,
+};
+
+struct impl {
+ enum impl_type type;
+ void *start; // Of header/entry
+ void (*load)(struct dev *, const char *);
+};
+
+#endif
diff --git a/src/loader/inc/impl/all.h b/src/loader/inc/impl/all.h
index f38fe42..01565a6 100644
--- a/src/loader/inc/impl/all.h
+++ b/src/loader/inc/impl/all.h
@@ -3,24 +3,10 @@
#ifndef IMPL_ALL_H
#define IMPL_ALL_H
+#include <cfg.h>
#include <def.h>
-enum impl_type {
- IMPL_NONE,
- IMPL_MB1,
- IMPL_MB2,
-};
-
-struct dev;
-struct impl {
- enum impl_type type;
- void *start; // Of header/entry
- void (*load)(struct dev *, const char *);
-};
-
-#include <dev.h>
-
-u8 impl_detect(struct dev *dev, const char *path);
-void impl_exec(struct dev *dev, const char *path);
+u8 impl_detect(struct cfg_entry *cfg);
+void impl_exec(struct cfg_entry *cfg);
#endif
diff --git a/src/loader/inc/impl/mb1.h b/src/loader/inc/impl/mb1.h
index d737cb2..5e68ece 100644
--- a/src/loader/inc/impl/mb1.h
+++ b/src/loader/inc/impl/mb1.h
@@ -3,10 +3,132 @@
#ifndef IMPL_MB1_H
#define IMPL_MB1_H
+#include <cfg.h>
#include <def.h>
#include <dev.h>
-u8 mb1_detect(struct dev *dev, const char *path);
-void mb1_exec(struct dev *dev, const char *path);
+#define MB1_MAGIC 0x1badb002 // Identifies kernel
+#define MB1_LOAD_MAGIC 0x2badb002 // Passed to kernel
+
+#define MB1_INFO_MEMORY 0x00000001
+#define MB1_INFO_BOOTDEV 0x00000002
+#define MB1_INFO_CMDLINE 0x00000004
+#define MB1_INFO_MODS 0x00000008
+#define MB1_INFO_AOUT_SYMS 0x00000010
+#define MB1_INFO_ELF_SHDR 0x00000020
+#define MB1_INFO_MEM_MAP 0x00000040
+#define MB1_INFO_DRIVE_INFO 0x00000080
+#define MB1_INFO_CONFIG_TABLE 0x00000100
+#define MB1_INFO_BOOT_LOADER_NAME 0x00000200
+#define MB1_INFO_APM_TABLE 0x00000400
+#define MB1_INFO_VBE_INFO 0x00000800
+#define MB1_INFO_FRAMEBUFFER_INFO 0x00001000
+
+#define MB1_FRAMEBUFFER_TYPE_INDEXED 0
+#define MB1_FRAMEBUFFER_TYPE_RGB 1
+#define MB1_FRAMEBUFFER_TYPE_EGA_TEXT 2
+
+#define MB1_MEMORY_AVAILABLE 1
+#define MB1_MEMORY_RESERVED 2
+#define MB1_MEMORY_ACPI_RECLAIMABLE 3
+#define MB1_MEMORY_NVS 4
+#define MB1_MEMORY_BADRAM 5
+
+#include <def.h>
+
+struct mb1_aout_symbol_table {
+ u32 tabsize;
+ u32 strsize;
+ u32 addr;
+ u32 reserved;
+};
+
+struct mb1_elf_section_header_table {
+ u32 num;
+ u32 size;
+ u32 addr;
+ u32 shndx;
+};
+
+struct mb1_info {
+ u32 flags;
+
+ u32 mem_lower;
+ u32 mem_upper;
+
+ u32 boot_device;
+
+ u32 cmdline;
+
+ u32 mods_count;
+ u32 mods_addr;
+
+ union {
+ struct mb1_aout_symbol_table aout_sym;
+ struct mb1_elf_section_header_table elf_sec;
+ } u;
+
+ u32 mmap_length;
+ u32 mmap_addr;
+
+ u32 drives_length;
+ u32 drives_addr;
+
+ u32 config_table;
+
+ u32 boot_loader_name;
+
+ u32 apm_table;
+
+ u32 vbe_control_info;
+ u32 vbe_mode_info;
+ u16 vbe_mode;
+ u16 vbe_interface_seg;
+ u16 vbe_interface_off;
+ u16 vbe_interface_len;
+
+ u32 framebuffer_addr_high;
+ u32 framebuffer_addr_low;
+ u32 framebuffer_pitch;
+ u32 framebuffer_width;
+ u32 framebuffer_height;
+ u8 framebuffer_bpp;
+ u8 framebuffer_type;
+ union {
+ struct {
+ u32 framebuffer_palette_addr;
+ u16 framebuffer_palette_num_colors;
+ } palette;
+ struct {
+ u8 framebuffer_red_field_position;
+ u8 framebuffer_red_mask_size;
+ u8 framebuffer_green_field_position;
+ u8 framebuffer_green_mask_size;
+ u8 framebuffer_blue_field_position;
+ u8 framebuffer_blue_mask_size;
+ } colors;
+ } framebuffer_colors;
+} PACKED;
+
+struct mb1_mmap_entry {
+ u32 struct_size;
+ u32 addr_low;
+ u32 addr_high;
+ u32 len_low;
+ u32 len_high;
+ u32 type;
+} PACKED;
+
+struct mb1_mod_list {
+ u32 mod_start;
+ u32 mod_end;
+
+ u32 cmdline;
+
+ u32 pad;
+};
+
+u8 mb1_detect(struct cfg_entry *cfg);
+void mb1_exec(struct cfg_entry *cfg);
#endif
diff --git a/src/loader/inc/impl/mb2.h b/src/loader/inc/impl/mb2.h
new file mode 100644
index 0000000..3f64dbd
--- /dev/null
+++ b/src/loader/inc/impl/mb2.h
@@ -0,0 +1,61 @@
+// MIT License, Copyright (c) 2021 Marvin Borner
+
+#ifndef IMPL_MB2_H
+#define IMPL_MB2_H
+
+#include <cfg.h>
+#include <def.h>
+#include <dev.h>
+
+#define MB2_MAGIC 0xe85250d6 // Identifies kernel
+#define MB2_LOAD_MAGIC 0x36d76289 // Passed to kernel
+
+struct mb2_header {
+ u32 total_size;
+ u32 unknown;
+} PACKED;
+
+struct mb2_tag {
+ u32 type;
+ u32 size;
+} PACKED;
+
+struct mb2_memory {
+ u32 addr_low;
+ u32 addr_high;
+ u32 size_low;
+ u32 size_high;
+ u32 type;
+ u32 reserved;
+} PACKED;
+
+struct mb2_module {
+ u32 start;
+ u32 end;
+ char string[1];
+} PACKED;
+
+struct mb2_fb {
+ u32 addr_low;
+ u32 addr_high;
+ u32 pitch;
+ u32 width;
+ u32 height;
+ u8 bpp;
+ u8 type;
+} PACKED;
+
+enum mb2_tags {
+ MB2_TAG_END = 0,
+ MB2_TAG_CMDLINE = 1,
+ MB2_TAG_MODULE = 3,
+ MB2_TAG_MEMORY = 6,
+ MB2_TAG_FB = 8,
+ MB2_TAG_ACPI_1 = 14,
+ MB2_TAG_ACPI_2 = 15,
+};
+
+u8 mb2_detect(struct cfg_entry *cfg);
+void mb2_exec(struct cfg_entry *cfg);
+
+#endif
diff --git a/src/loader/inc/pnc.h b/src/loader/inc/pnc.h
index 1630bd9..73819c9 100644
--- a/src/loader/inc/pnc.h
+++ b/src/loader/inc/pnc.h
@@ -18,4 +18,7 @@
panic("Assertion '" #exp "' failed\n"); \
}
+// This shouldn't return, therefore this declaration belongs here (kinda)
+void jmp_kernel(void *kernel, int args, ...);
+
#endif
diff --git a/src/loader/jmp.asm b/src/loader/jmp.asm
new file mode 100644
index 0000000..f591dda
--- /dev/null
+++ b/src/loader/jmp.asm
@@ -0,0 +1,28 @@
+; MIT License, Copyright (c) 2021 Marvin Borner
+; Exit the bootloader and clear registers
+
+bits 32
+
+; Empty (invalid) idt
+idt:
+ dd 0, 0
+
+global jmp_kernel
+jmp_kernel:
+ cli ; Disable interrupts because of invalid idt
+ lidt [idt] ; Load empty (invalid) idt
+
+ xor eax, eax
+ lldt ax ; Clear LDT by pointing to nothing
+
+ add esp, 4
+ pop edi
+ add esp, 4
+
+ mov eax, 0x00000001
+ mov cr0, eax ; Clear cr0 except protected mode
+
+ xor eax, eax
+ mov cr4, eax ; Clear cr4 completely
+
+ call edi ; Call custom (specified) jumper
diff --git a/src/loader/log.c b/src/loader/log.c
index a22f5d2..ff4feff 100644
--- a/src/loader/log.c
+++ b/src/loader/log.c
@@ -1,3 +1,5 @@
+// MIT License, Copyright (c) 2021 Marvin Borner
+
#include <cpu.h>
#include <lib.h>
#include <log.h>