From 8494b1d880226e66c8567604f0e33e210d40d805 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Wed, 25 Mar 2020 21:05:14 +0100 Subject: [PATCH] Add protos abstraction and stivale and qword protocols --- src/lib/elf.c | 57 ++--------------------------------- src/lib/elf.h | 3 +- src/main.c | 32 +++++++++++++------- src/protos/stivale.c | 71 ++++++++++++++++++++++++++++++++++++++++++++ src/protos/stivale.h | 8 +++++ test/qloader2.cfg | 1 + 6 files changed, 105 insertions(+), 67 deletions(-) create mode 100644 src/protos/stivale.c create mode 100644 src/protos/stivale.h diff --git a/src/lib/elf.c b/src/lib/elf.c index 656bcd3d..cb81914a 100644 --- a/src/lib/elf.c +++ b/src/lib/elf.c @@ -48,7 +48,7 @@ struct elf_phdr { #define FIXED_HIGHER_HALF_OFFSET ((uint64_t)0xffffffff80000000) -int elf_load(struct echfs_file_handle *fd) { +int elf_load(struct echfs_file_handle *fd, uint64_t *entry_point) { struct elf_hdr hdr; echfs_read(fd, &hdr, 0, sizeof(struct elf_hdr)); @@ -89,60 +89,7 @@ int elf_load(struct echfs_file_handle *fd) { } } - volatile struct { - uint64_t pml4[512]; - uint64_t pml3_lo[512]; - uint64_t pml3_hi[512]; - uint64_t pml2_0gb[512]; - uint64_t pml2_1gb[512]; - uint64_t pml2_2gb[512]; - uint64_t pml2_3gb[512]; - } *pagemap = (void *)0x10000; - - // first, zero out the pagemap - for (uint64_t *p = (uint64_t *)pagemap; p < &pagemap->pml3_hi[512]; p++) - *p = 0; - - pagemap->pml4[511] = (uint64_t)(size_t)pagemap->pml3_hi | 0x03; - pagemap->pml4[256] = (uint64_t)(size_t)pagemap->pml3_lo | 0x03; - pagemap->pml4[0] = (uint64_t)(size_t)pagemap->pml3_lo | 0x03; - pagemap->pml3_hi[510] = (uint64_t)(size_t)pagemap->pml2_0gb | 0x03; - pagemap->pml3_hi[511] = (uint64_t)(size_t)pagemap->pml2_1gb | 0x03; - pagemap->pml3_lo[0] = (uint64_t)(size_t)pagemap->pml2_0gb | 0x03; - pagemap->pml3_lo[1] = (uint64_t)(size_t)pagemap->pml2_1gb | 0x03; - pagemap->pml3_lo[2] = (uint64_t)(size_t)pagemap->pml2_2gb | 0x03; - pagemap->pml3_lo[3] = (uint64_t)(size_t)pagemap->pml2_3gb | 0x03; - - // populate the page directories - for (size_t i = 0; i < 512 * 4; i++) - (&pagemap->pml2_0gb[0])[i] = (i * 0x1000) | 0x03 | (1 << 7); - - asm volatile ( - "cli\n\t" - "mov cr3, eax\n\t" - "mov eax, cr4\n\t" - "or eax, 1 << 5 | 1 << 7\n\t" - "mov cr4, eax\n\t" - "mov ecx, 0xc0000080\n\t" - "rdmsr\n\t" - "or eax, 1 << 8\n\t" - "wrmsr\n\t" - "mov eax, cr0\n\t" - "or eax, 1 << 31\n\t" - "mov cr0, eax\n\t" - "jmp 0x28:1f\n\t" - "1: .code64\n\t" - "mov ax, 0x30\n\t" - "mov ds, ax\n\t" - "mov es, ax\n\t" - "mov fs, ax\n\t" - "mov gs, ax\n\t" - "mov ss, ax\n\t" - "jmp [rbx]\n\t" - ".code32\n\t" - : - : "a" (pagemap), "b" (&hdr.entry) - ); + *entry_point = hdr.entry; return 0; } diff --git a/src/lib/elf.h b/src/lib/elf.h index d3234d83..01e33edd 100644 --- a/src/lib/elf.h +++ b/src/lib/elf.h @@ -1,8 +1,9 @@ #ifndef __LIB__ELF_H__ #define __LIB__ELF_H__ +#include #include -int elf_load(struct echfs_file_handle *fd); +int elf_load(struct echfs_file_handle *fd, uint64_t *entry_point); #endif diff --git a/src/main.c b/src/main.c index 95ff8f3b..de75c338 100644 --- a/src/main.c +++ b/src/main.c @@ -8,11 +8,13 @@ asm ( #include #include #include +#include #include #include #include #include #include +#include #define CONFIG_NAME "qloader2.cfg" @@ -56,7 +58,7 @@ void main(int boot_drive) { } int drive, part; - char path[128], cmdline[128]; + char path[128], cmdline[128], proto[64]; if (config_loaded) { char buf[32]; @@ -66,6 +68,7 @@ void main(int boot_drive) { part = (int)strtoui(buf); config_get_value(path, 128, (void*)0x100000, "KERNEL_PATH"); config_get_value(cmdline, 128, (void*)0x100000, "KERNEL_CMDLINE"); + config_get_value(proto, 64, (void*)0x100000, "KERNEL_PROTO"); } else { print(" !! NO CONFIG FILE FOUND ON BOOT DRIVE !!"); for (;;); @@ -80,17 +83,24 @@ void main(int boot_drive) { break; } } + print("\n"); echfs_open(&f, drive, part, path); - echfs_read(&f, (void *)0x100000, 0, f.dir_entry.size); - //elf_load(&f); - // Boot the kernel. - asm volatile ( - "cli\n\t" - "jmp 0x100000\n\t" - : - : "b" (cmdline) - : "memory" - ); + if (!strcmp(proto, "stivale")) { + stivale_load(&f); + } else if (!strcmp(proto, "qword")) { + echfs_read(&f, (void *)0x100000, 0, f.dir_entry.size); + // Boot the kernel. + asm volatile ( + "cli\n\t" + "jmp 0x100000\n\t" + : + : "b" (cmdline) + : "memory" + ); + } else { + print("Invalid protocol specified: `%s`.\n", proto); + for (;;); + } } diff --git a/src/protos/stivale.c b/src/protos/stivale.c new file mode 100644 index 00000000..c9bda16f --- /dev/null +++ b/src/protos/stivale.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include + +struct stivale_header { + uint64_t magic; + uint64_t stack; + uint8_t video_mode; // 0 = default at boot (CGA text mode). 1 = graphical VESA +}; + +void stivale_load(struct echfs_file_handle *fd) { + uint64_t entry_point; + + elf_load(fd, &entry_point); + + volatile struct { + uint64_t pml4[512]; + uint64_t pml3_lo[512]; + uint64_t pml3_hi[512]; + uint64_t pml2_0gb[512]; + uint64_t pml2_1gb[512]; + uint64_t pml2_2gb[512]; + uint64_t pml2_3gb[512]; + } *pagemap = (void *)0x10000; + + // first, zero out the pagemap + for (uint64_t *p = (uint64_t *)pagemap; p < &pagemap->pml3_hi[512]; p++) + *p = 0; + + pagemap->pml4[511] = (uint64_t)(size_t)pagemap->pml3_hi | 0x03; + pagemap->pml4[256] = (uint64_t)(size_t)pagemap->pml3_lo | 0x03; + pagemap->pml4[0] = (uint64_t)(size_t)pagemap->pml3_lo | 0x03; + pagemap->pml3_hi[510] = (uint64_t)(size_t)pagemap->pml2_0gb | 0x03; + pagemap->pml3_hi[511] = (uint64_t)(size_t)pagemap->pml2_1gb | 0x03; + pagemap->pml3_lo[0] = (uint64_t)(size_t)pagemap->pml2_0gb | 0x03; + pagemap->pml3_lo[1] = (uint64_t)(size_t)pagemap->pml2_1gb | 0x03; + pagemap->pml3_lo[2] = (uint64_t)(size_t)pagemap->pml2_2gb | 0x03; + pagemap->pml3_lo[3] = (uint64_t)(size_t)pagemap->pml2_3gb | 0x03; + + // populate the page directories + for (size_t i = 0; i < 512 * 4; i++) + (&pagemap->pml2_0gb[0])[i] = (i * 0x1000) | 0x03 | (1 << 7); + + asm volatile ( + "cli\n\t" + "mov cr3, eax\n\t" + "mov eax, cr4\n\t" + "or eax, 1 << 5 | 1 << 7\n\t" + "mov cr4, eax\n\t" + "mov ecx, 0xc0000080\n\t" + "rdmsr\n\t" + "or eax, 1 << 8\n\t" + "wrmsr\n\t" + "mov eax, cr0\n\t" + "or eax, 1 << 31\n\t" + "mov cr0, eax\n\t" + "jmp 0x28:1f\n\t" + "1: .code64\n\t" + "mov ax, 0x30\n\t" + "mov ds, ax\n\t" + "mov es, ax\n\t" + "mov fs, ax\n\t" + "mov gs, ax\n\t" + "mov ss, ax\n\t" + "jmp [rbx]\n\t" + ".code32\n\t" + : + : "a" (pagemap), "b" (&entry_point) + ); +} diff --git a/src/protos/stivale.h b/src/protos/stivale.h new file mode 100644 index 00000000..5587a98e --- /dev/null +++ b/src/protos/stivale.h @@ -0,0 +1,8 @@ +#ifndef __PROTOS__STIVALE_H__ +#define __PROTOS__STIVALE_H__ + +#include + +void stivale_load(struct echfs_file_handle *fd); + +#endif diff --git a/test/qloader2.cfg b/test/qloader2.cfg index 5d729370..2544fc20 100644 --- a/test/qloader2.cfg +++ b/test/qloader2.cfg @@ -1,4 +1,5 @@ KERNEL_DRIVE=128 KERNEL_PARTITION=0 KERNEL_PATH=test.elf +KERNEL_PROTO=stivale KERNEL_CMDLINE=none