:: commit 8494b1d880226e66c8567604f0e33e210d40d805

mintsuki <mintsuki@protonmail.com> — 2020-03-25 20:05

parents: c66d052afc

Add protos abstraction and stivale and qword protocols

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 <stdint.h>
 #include <fs/echfs.h>
 
-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 <drivers/vga_textmode.h>
 #include <lib/real.h>
 #include <lib/blib.h>
+#include <lib/libc.h>
 #include <lib/mbr.h>
 #include <lib/config.h>
 #include <fs/echfs.h>
 #include <sys/interrupt.h>
 #include <lib/elf.h>
+#include <protos/stivale.h>
 
 #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 <stdint.h>
+#include <stddef.h>
+#include <protos/stivale.h>
+#include <lib/elf.h>
+
+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 <fs/echfs.h>
+
+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
tab: 248 wrap: offon