diff options
author | Marvin Borner | 2021-07-07 19:13:11 +0200 |
---|---|---|
committer | Marvin Borner | 2021-07-07 19:13:11 +0200 |
commit | 9a2d5cbdc7972d1d5bfb1ea93f82f66d113faa17 (patch) | |
tree | 08ceb8427b64a08c89a5526dfbf8b66c78f9d12c | |
parent | 6355c3e08c9f4d3db122252abce5837c364d5b81 (diff) |
Strange implementations
-rw-r--r-- | example/mb1/main.c | 15 | ||||
-rw-r--r-- | example/mb2/entry.asm | 51 | ||||
-rw-r--r-- | example/mb2/link.ld | 33 | ||||
-rw-r--r-- | example/mb2/main.c | 31 | ||||
-rw-r--r-- | example/mb2/makefile | 16 | ||||
-rw-r--r-- | example/segelboot.cfg | 2 | ||||
-rw-r--r-- | makefile | 5 | ||||
-rw-r--r-- | src/loader/cfg.c | 16 | ||||
-rw-r--r-- | src/loader/impl/all.c | 18 | ||||
-rw-r--r-- | src/loader/impl/mb1.c | 58 | ||||
-rw-r--r-- | src/loader/impl/mb2.c | 100 | ||||
-rw-r--r-- | src/loader/inc/acpi.h | 2 | ||||
-rw-r--r-- | src/loader/inc/cfg.h | 5 | ||||
-rw-r--r-- | src/loader/inc/def.h | 3 | ||||
-rw-r--r-- | src/loader/inc/dev.h | 2 | ||||
-rw-r--r-- | src/loader/inc/impl.h | 20 | ||||
-rw-r--r-- | src/loader/inc/impl/all.h | 20 | ||||
-rw-r--r-- | src/loader/inc/impl/mb1.h | 126 | ||||
-rw-r--r-- | src/loader/inc/impl/mb2.h | 61 | ||||
-rw-r--r-- | src/loader/inc/pnc.h | 3 | ||||
-rw-r--r-- | src/loader/jmp.asm | 28 | ||||
-rw-r--r-- | src/loader/log.c | 2 |
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 @@ -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> |