hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
Diffstat (limited to 'boot')
-rw-r--r--boot/boot.zig22
-rw-r--r--boot/limine.conf5
-rw-r--r--boot/limine.zig27
-rw-r--r--boot/linker.ld52
4 files changed, 106 insertions, 0 deletions
diff --git a/boot/boot.zig b/boot/boot.zig
new file mode 100644
index 0000000..0f6c92c
--- /dev/null
+++ b/boot/boot.zig
@@ -0,0 +1,22 @@
+const std = @import("std");
+const limine = @import("limine.zig");
+
+// We need a panic handler otherwise zig won't be happy,
+// std usually formats a message through std.Io.Writer which
+// emits SSE instructions which I haven't enabled. For now
+// we just halt.
+pub const panic = std.debug.FullPanic(struct {
+ fn halt(_: []const u8, _: ?usize) noreturn {
+ while (true) asm volatile ("hlt");
+ }
+}.halt);
+
+// Check `linker.ld`
+export var base_revision: limine.BaseRevision linksection(".limine_requests") = limine.BaseRevision.init(3);
+export var requests_start: limine.RequestsStartMarker linksection(".limine_requests_start") = .{};
+export var requests_end: limine.RequestsEndMarker linksection(".limine_requests_end") = .{};
+
+// ENTRY(_start)
+export fn _start() callconv(.c) noreturn {
+ while (true) asm volatile ("hlt");
+}
diff --git a/boot/limine.conf b/boot/limine.conf
new file mode 100644
index 0000000..7398dca
--- /dev/null
+++ b/boot/limine.conf
@@ -0,0 +1,5 @@
+timeout: 0
+
+/Revel
+ protocol: limine
+ path: boot():/boot/revel
diff --git a/boot/limine.zig b/boot/limine.zig
new file mode 100644
index 0000000..e9aac9c
--- /dev/null
+++ b/boot/limine.zig
@@ -0,0 +1,27 @@
+// Limine scans the loaded image for these magic numbers,
+// BaseRevision is a handshake, essentially we ask limine
+// for rev 3, and if it supports it, limine zeros it out
+pub const BaseRevision = extern struct {
+ magic0: u64 = 0xf9562b2d5c95a6c8,
+ magic1: u64 = 0x6a7b384944536bdc,
+ revision: u64,
+
+ pub fn init(revision: u64) BaseRevision {
+ return .{ .revision = revision };
+ }
+};
+
+// Bracketing markers, they are pretty optional but when
+// we add proper limine requests, having these here comes
+// handy
+pub const RequestsStartMarker = extern struct {
+ m0: u64 = 0xf6b8f4b39de7d1ae,
+ m1: u64 = 0xfab91a6940fcb9cf,
+ m2: u64 = 0x785c6ed015d3e316,
+ m3: u64 = 0x181e920a7852b9d9,
+};
+
+pub const RequestsEndMarker = extern struct {
+ m0: u64 = 0xadc0e0531bb10d03,
+ m1: u64 = 0x9572709f31764c62,
+};
diff --git a/boot/linker.ld b/boot/linker.ld
new file mode 100644
index 0000000..e15ed10
--- /dev/null
+++ b/boot/linker.ld
@@ -0,0 +1,52 @@
+/* the higher half of the kernel link maps
+ * at the top 2 GiB is where Limine maps us. */
+
+OUTPUT_FORMAT(elf64-x86-64)
+ENTRY(_start)
+
+PHDRS
+{
+ limine_requests PT_LOAD;
+ text PT_LOAD;
+ rodata PT_LOAD;
+ data PT_LOAD;
+}
+
+SECTIONS
+{
+ . = 0xffffffff80000000;
+
+ /* The loader hunts for the magic numbers here
+ * these are referenced in `boot/` */
+ .limine_requests : {
+ KEEP(*(.limine_requests_start))
+ KEEP(*(.limine_requests))
+ KEEP(*(.limine_requests_end))
+ } :limine_requests
+
+ . = ALIGN(CONSTANT(MAXPAGESIZE));
+ .text : {
+ *(.text .text.*)
+ } :text
+
+ . = ALIGN(CONSTANT(MAXPAGESIZE));
+ .rodata : {
+ *(.rodata .rodata.*)
+ } :rodata
+
+ . = ALIGN(CONSTANT(MAXPAGESIZE));
+ .data : {
+ *(.data .data.*)
+ } :data
+
+ .bss : {
+ *(.bss .bss.*)
+ *(COMMON)
+ } :data
+
+ /* no unwind tables or note sections. */
+ /DISCARD/ : {
+ *(.eh_frame*)
+ *(.note .note.*)
+ }
+}