summaryrefslogtreecommitdiff
path: root/stage3
diff options
context:
space:
mode:
Diffstat (limited to 'stage3')
-rw-r--r--stage3/debug.c97
-rw-r--r--stage3/init.c3
-rw-r--r--stage3/isr.lua13
-rw-r--r--stage3/main.c6
-rw-r--r--stage3/paging.asm15
-rw-r--r--stage3/watchdog.lua4
6 files changed, 87 insertions, 51 deletions
diff --git a/stage3/debug.c b/stage3/debug.c
index 0621dbd..ed28fee 100644
--- a/stage3/debug.c
+++ b/stage3/debug.c
@@ -4,7 +4,6 @@
#include "halt.h"
#include "debug.h"
-static str dbg_map = NILS;
static str dbg_disas = NILS;
static str exception[32] = {
@@ -37,56 +36,70 @@ static str exception[32] = {
NILS,
};
-static void dump_frame(interrupt_frame *frame)
+static bool get_source(u64 code, str *func, str *linep)
{
- print(S("rip = "));
- print_hex(frame->rip);
-
- if (dbg_map.data != nil) {
- str entry = NILS;
- str iter = dbg_map;
- while (iter.len > 0) {
- str line = str_walk(&iter, S("\n"));
- line = str_eat(line, S(" "));
- if (!str_start(line, S("0x")))
+ if (dbg_disas.data == nil)
+ return false;
+
+ *func = (str) NILS;
+ *linep = (str) NILS;
+
+ str iter = dbg_disas;
+ while (iter.len > 0) {
+ str line = str_walk(&iter, S("\n"));
+ u64 func_addr;
+ usize adv;
+ if ((adv = str_parse_num(line, 16, &func_addr))) {
+ line = str_advance(line, adv);
+ if (line.len < 2 || line.data[0] != ' ' || line.data[1] != '<')
continue;
line = str_advance(line, 2);
-
+ usize close = str_find(line, S(">"));
+ *func = (str) { .len = close, .data = line.data };
+ } else {
u64 addr;
- usize adv = str_parse_num(line, 16, &addr);
- if (adv == 0)
+ if (!str_parse_num(str_eat(line, S(" ")), 16, &addr))
continue;
- line = str_advance(line, adv);
-
- if (addr > frame->rip)
- break;
-
- line = str_eat(line, S(" "));
- if (line.len > 0)
- entry = line;
+ *linep = line;
+ if (addr == code)
+ return true;
}
+ }
- if (entry.len > 0) {
- print(S(" in "));
- print(entry);
- }
+ return false;
+}
+
+static void trace(u64 code, u64 base)
+{
+ if (base == 0)
+ return;
+
+ str func, line;
+ if (get_source(code, &func, &line)) {
+ print(S("\t"));
+ print_hex(code);
+ print(S(" in "));
+ print(func);
+ print(S("\n"));
}
- if (dbg_disas.data != nil) {
- str iter = dbg_disas;
- while (iter.len > 0) {
- str line = str_walk(&iter, S("\n"));
- u64 addr;
- if (!str_parse_num(str_eat(line, S(" ")), 16, &addr))
- continue;
- if (addr == frame->rip) {
- print(S("\n"));
- print(line);
- break;
- }
- }
+ u64 *stack = (u64 *) base;
+ trace(stack[1], stack[0]);
+}
+
+static void dump_frame(interrupt_frame *frame)
+{
+ str func, line;
+ if (get_source(frame->rip, &func, &line)) {
+ print(line);
+ print(S("\n"));
}
+ print(S("backtrace:\n"));
+ trace(frame->rip, frame->rbp);
+
+ print(S("rip = "));
+ print_hex(frame->rip);
print(S("\n"));
struct {
@@ -187,7 +200,7 @@ void debug_exception(interrupt_frame *frame)
void debug_init()
{
- print(S("loading kernel debug info...\n"));
- dbg_map = fs_read(S("dbg/kernel.map"));
+ print(S("loading kernel debug info... "));
dbg_disas = fs_read(S("dbg/kernel.dis.asm"));
+ print(S("done\n"));
}
diff --git a/stage3/init.c b/stage3/init.c
index 2e26e19..c65f08b 100644
--- a/stage3/init.c
+++ b/stage3/init.c
@@ -1,7 +1,7 @@
#include "def.h"
void kmain();
-void init()
+void _start()
{
// enable SSE. long mode demands it is present
u64 cr0;
@@ -14,5 +14,6 @@ void init()
u16 fpu_cw = 0x37a;
asm volatile("fldcw %0"::"m"(fpu_cw));
+
kmain();
}
diff --git a/stage3/isr.lua b/stage3/isr.lua
index 3c88c5e..4810f01 100644
--- a/stage3/isr.lua
+++ b/stage3/isr.lua
@@ -6,6 +6,13 @@ for _, x in pairs({8, 10, 11, 12, 13, 14, 17, 21, 29, 30}) do
has_error_code[x] = true
end
+print("section .data")
+print("idt_entries:")
+for i = 0, 255 do
+ print("dq isr_"..i)
+end
+
+print("section .text")
for i = 0, 255 do
print("isr_" .. i .. ":")
print("cli")
@@ -18,11 +25,6 @@ for i = 0, 255 do
print("jmp isr_common")
end
-print("idt_entries:")
-for i = 0, 255 do
- print("dq isr_"..i)
-end
-
print([[
isr_common:
push r15
@@ -42,6 +44,7 @@ isr_common:
push rax
cld
+ xor rbp, rbp
mov rdi, rsp
call interrupt_handler
diff --git a/stage3/main.c b/stage3/main.c
index ae94abf..b796fd1 100644
--- a/stage3/main.c
+++ b/stage3/main.c
@@ -63,6 +63,12 @@ void kmain()
heap_init();
#define MMAP for (MemRegion *mreg = (void *) 0x500; mreg->start != nil; mreg++)
+ MMAP {
+ if (mreg->start == (void *) 0x100000) {
+ mreg->start = (void *) 0x200000;
+ mreg->size -= 0x100000;
+ }
+ }
// backup memory map
usize n_mreg = 0;
diff --git a/stage3/paging.asm b/stage3/paging.asm
index 783649e..f58bb98 100644
--- a/stage3/paging.asm
+++ b/stage3/paging.asm
@@ -1,15 +1,24 @@
global page_region
-section .text
+%define PAGEBUFSIZE 0x10 * 0x1000
+
+section .bss
+
+ALIGN(4096)
+pagebuf_data: resb PAGEBUFSIZE
+
+section .data
pagebuf_init:
- .start: dq 0x5000
- .size: dq 0x2000
+ .start: dq pagebuf_data
+ .size: dq PAGEBUFSIZE
.used: dq 0
pagebuf: dq pagebuf_init
next_page: dq 0
+section .text
+
; allocate new page table buffer
alloc:
; rsi = buffer (result)
diff --git a/stage3/watchdog.lua b/stage3/watchdog.lua
index dac4d57..8d3a206 100644
--- a/stage3/watchdog.lua
+++ b/stage3/watchdog.lua
@@ -12,9 +12,13 @@ local regs = {
print("global watchdog")
print("extern rand, watchdog_err")
+print("section .bss")
+
print("regs_backup: resq 16")
print("regs_rand: resq 16")
+print("section .text")
+
print("watchdog:")
local function iter_regs(f)