:: commit 22ac79080e17e2d399fcffe01398de2b8c58aba0

mintsuki <mintsuki@protonmail.com> — 2020-06-10 17:49

parents: 925631ccaf

Add support for TempleOS boot protocol

diff --git a/qloader2.bin b/qloader2.bin
index 956a3b77..9bd7310e 100644
Binary files a/qloader2.bin and b/qloader2.bin differ
diff --git a/src/main.c b/src/main.c
index 7ffb81f8..1f0a78ab 100644
--- a/src/main.c
+++ b/src/main.c
@@ -27,6 +27,7 @@ asm (
 #include <lib/elf.h>
 #include <protos/stivale.h>
 #include <protos/linux.h>
+#include <protos/templeos.h>
 #include <protos/chainload.h>
 #include <menu.h>
 
@@ -74,6 +75,8 @@ void main(int boot_drive) {
         stivale_load(cmdline, boot_drive);
     } else if (!strcmp(proto, "linux")) {
         linux_load(cmdline, boot_drive);
+    } else if (!strcmp(proto, "templeos")) {
+        templeos_load(boot_drive);
     } else if (!strcmp(proto, "chainload")) {
         chainload();
     } else {
diff --git a/src/protos/templeos.c b/src/protos/templeos.c
new file mode 100644
index 00000000..d75060d5
--- /dev/null
+++ b/src/protos/templeos.c
@@ -0,0 +1,118 @@
+#include <stddef.h>
+#include <stdint.h>
+#include <lib/config.h>
+#include <lib/blib.h>
+#include <lib/libc.h>
+#include <lib/print.h>
+#include <fs/file.h>
+
+__attribute__((used))
+__attribute__((naked)) static void trampoline(void *p, size_t sz, int boot_drive) {
+    asm (
+        "tos_trampoline_begin:\n\t"
+
+        "mov edx, dword ptr ss:[esp+12]\n\t"
+
+        "mov ecx, dword ptr ss:[esp+8]\n\t"
+        "mov esi, dword ptr ss:[esp+4]\n\t"
+        "mov edi, 0x7c00\n\t"
+        "cld\n\t"
+        "rep movsb\n\t"
+
+        "lgdt [4f - tos_trampoline_begin + 0x500]\n\t"
+
+        "jmp 0x08:1f - tos_trampoline_begin + 0x500\n\t"
+        "1: .code16\n\t"
+        "mov ax, 0x10\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"
+        "mov eax, cr0\n\t"
+        "and al, 0xfe\n\t"
+        "mov cr0, eax\n\t"
+        "jmp 0:2f - tos_trampoline_begin + 0x500\n\t"
+        "2:\n\t"
+        "xor ax, ax\n\t"
+        "mov fs, ax\n\t"
+        "mov gs, ax\n\t"
+
+        "mov ax, 0x96c0\n\t"
+        "mov ds, ax\n\t"
+        "mov ss, ax\n\t"
+
+        "mov ax, 0x35e0\n\t"
+        "mov es, ax\n\t"
+
+        "mov eax, 3\n\t"
+
+        "xor ebx, ebx\n\t"
+        "xor ecx, ecx\n\t"
+        "mov esi, 0x92\n\t"
+        "mov edi, 0x200\n\t"
+        "xor ebp, ebp\n\t"
+
+        "mov esp, 0x400\n\t"
+
+        "push 0x246\n\t"
+        "push 0x07c0\n\t"
+        "push 0x0\n\t"
+        "iret\n\t"
+
+        ".code32\n\t"
+
+        "3:\n\t"
+        ".quad 0\n\t"
+        ".quad 0x00009A000000FFFF\n\t"
+        ".quad 0x000092000000FFFF\n\t"
+        "4:\n\t"
+        ".short 4b - 3b - 1\n\t"
+        ".long 3b - tos_trampoline_begin + 0x500\n\t"
+
+        "tos_trampoline_end:\n\t"
+    );
+    (void)p; (void)sz; (void)boot_drive;
+}
+
+extern symbol tos_trampoline_begin;
+extern symbol tos_trampoline_end;
+
+void templeos_load(int boot_drive) {
+    int kernel_drive; {
+        char buf[32];
+        if (!config_get_value(buf, 0, 32, "DRIVE")) {
+            kernel_drive = boot_drive;
+        } else {
+            kernel_drive = (int)strtoui(buf);
+        }
+    }
+
+    int kernel_part; {
+        char buf[32];
+        if (!config_get_value(buf, 0, 32, "PARTITION")) {
+            panic("PARTITION not specified");
+        } else {
+            kernel_part = (int)strtoui(buf);
+        }
+    }
+
+    struct file_handle f;
+    if (fopen(&f, kernel_drive, kernel_part, "/Kernel.BIN.C")) {
+        panic("TempleOS kernel not found.");
+    }
+
+    print("TempleOS kernel size: %U bytes\n", f.size);
+
+    void *kernel = balloc(f.size);
+    fread(&f, kernel, 0, f.size);
+
+    void (*t)(void *p, size_t sz, int boot_drive);
+    t = (void *)0x500;
+
+    memcpy(t, tos_trampoline_begin, (size_t)tos_trampoline_end - (size_t)tos_trampoline_begin);
+
+    t(kernel, f.size, kernel_drive);
+
+    for (;;);
+}
diff --git a/src/protos/templeos.h b/src/protos/templeos.h
new file mode 100644
index 00000000..97610863
--- /dev/null
+++ b/src/protos/templeos.h
@@ -0,0 +1,6 @@
+#ifndef __PROTOS__TEMPLEOS_H__
+#define __PROTOS__TEMPLEOS_H__
+
+void templeos_load(int boot_drive);
+
+#endif
tab: 248 wrap: offon