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
