diff options
author | Lizzy Fleckenstein <lizzy@vlhl.dev> | 2023-12-19 09:19:43 +0100 |
---|---|---|
committer | Lizzy Fleckenstein <lizzy@vlhl.dev> | 2023-12-19 09:24:31 +0100 |
commit | 3102878c86c810c0bf877d72aceefeb28a44271d (patch) | |
tree | b6232392ff6dc2903567a79828b4a713ababc76f | |
parent | a6b460d3b1b0909e0c7b388f1a55365bf24c6b7b (diff) | |
download | cuddles-3102878c86c810c0bf877d72aceefeb28a44271d.tar.xz |
improve debugging
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 21 | ||||
-rw-r--r-- | stage3/font.c | 4 | ||||
-rw-r--r-- | stage3/interrupts.c | 117 | ||||
-rw-r--r-- | stage3/isr.lua | 48 | ||||
-rw-r--r-- | stage3/main.c | 14 | ||||
-rw-r--r-- | stage3/shell.c | 4 | ||||
-rw-r--r-- | stage3/string.c | 37 | ||||
-rw-r--r-- | stage3/string.h | 5 |
9 files changed, 204 insertions, 47 deletions
@@ -2,6 +2,7 @@ *.o *.img *.map +*.dis.asm bx_enh_dbg.ini stage3/isr.asm fs.tar @@ -37,6 +37,7 @@ STAGE3 = \ stage3/version.o PAD_BOUNDARY = pad() { truncate -s $$(echo "($$(du -b $$1 | cut -f1)+$$2-1)/$$2*$$2" | bc) $$1; }; pad +DISAS = objdump -b binary -D -M intel -m i386:x86-64 stage3.bin --adjust-vma 0x9000 cuddles.img: stage1.bin stage2.bin stage3.bin fs.tar cat stage{1,2,3}.bin fs.tar > cuddles.img @@ -50,10 +51,15 @@ stage2.bin: stage2/main.asm stage2/mmap.asm stage2/paging.asm stage2/vesa.asm st nasm -f bin stage2/main.asm -o stage2.bin truncate -s 4608 stage2.bin -stage3.bin: $(STAGE3) stage3.ld - ld $(STAGE3) -T stage3.ld -Map=stage3.map +stage3.bin fs/dbg/kernel.map: $(STAGE3) stage3.ld + mkdir -p fs/dbg/ + ld $(STAGE3) -T stage3.ld -Map=fs/dbg/kernel.map $(PAD_BOUNDARY) stage3.bin 512 +fs/dbg/kernel.dis.asm: stage3.bin + mkdir -p fs/dbg/ + $(DISAS) > fs/dbg/kernel.dis.asm + stage3/%.o: stage3/%.asm nasm -f elf64 $< -o $@ @@ -72,10 +78,10 @@ stage3/version.$(GIT_VERSION).c: stage3/isr.asm: stage3/isr.lua lua stage3/isr.lua > stage3/isr.asm -fs.tar: $(shell find fs | sed 's/ /\\ /g') +fs.tar: $(shell find fs | sed 's/ /\\ /g') fs/dbg/kernel.map fs/dbg/kernel.dis.asm cd fs && tar --format=ustar -cf ../fs.tar * -.PHONY: run clean flash disas map qemu bochs +.PHONY: run clean flash disas qemu bochs bochs: cuddles.img rm -f cuddles.img.lock @@ -90,13 +96,10 @@ qemu_slow: cuddles.img run: qemu clean: - rm -rf stage3/*.o *.bin *.img *.map stage3/{isr.asm,version.c,version.*.c} fs.tar + rm -rf stage3/*.o *.bin *.img stage3/{isr.asm,version.c,version.*.c} fs.tar fs/dbg flash: cuddles.img dd if=cuddles.img of=$(DEV) disas: stage3.bin - objdump -b binary -D -M intel -m i386:x86-64 stage3.bin --adjust-vma 0x9000 --disassembler-color=on - -map: stage3.bin - cat stage3.map + $(DISAS) --disassembler-color=on diff --git a/stage3/font.c b/stage3/font.c index ca3a420..31b771e 100644 --- a/stage3/font.c +++ b/stage3/font.c @@ -116,10 +116,10 @@ void print_char(char c) cursor_x = 0; break; - /*case '\t': + case '\t': render_char(' '); cursor_x = (cursor_x + TAB_SIZE) & ~(TAB_SIZE - 1); - break;*/ + break; case '\b': if (cursor_x > 0) { diff --git a/stage3/interrupts.c b/stage3/interrupts.c index 2713cfa..edfe431 100644 --- a/stage3/interrupts.c +++ b/stage3/interrupts.c @@ -5,11 +5,13 @@ #include "pic.h" #include "thread.h" #include "io.h" +#include "string.h" +extern str dbg_map, dbg_disas; extern u64 idt_entries[256]; // isr.asm typedef struct __attribute__((packed)) { - u64 rax, rdx, rcx, rsi, rdi, r8, r9, r10, r11; + u64 rax, rbx, rcx, rdx, rbp, rdi, rsi, r8, r9, r10, r11, r12, r13, r14, r15; u64 which, error_code; u64 rip, cs, rflags, rsp, ss; } interrupt_frame; @@ -46,11 +48,112 @@ static str exception[32] = { static void dump_frame(interrupt_frame *frame) { - print(S("rip = ")); print_hex(frame->rip); print_char('\n'); - print(S("cs = ")); print_hex(frame->cs); print_char('\n'); - print(S("rflags = ")); print_hex(frame->rflags); print_char('\n'); - print(S("rsp = ")); print_hex(frame->rsp); print_char('\n'); - print(S("ss = ")); print_hex(frame->ss); print_char('\n'); + 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"))) + continue; + line = str_advance(line, 2); + + u64 addr; + usize adv = str_parse_num(line, 16, &addr); + if (adv == 0) + continue; + line = str_advance(line, adv); + + if (addr > frame->rip) + break; + + line = str_eat(line, S(" ")); + if (line.len > 0) + entry = line; + } + + if (entry.len > 0) { + print(S(" in ")); + print(entry); + } + } + + 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; + } + } + } + + print(S("\n")); + + struct { + u8 bit; + str name; + } flags[] = { + { 0, S("CF") }, + { 2, S("PF") }, + { 4, S("AF") }, + { 6, S("ZF") }, + { 7, S("SF") }, + { 8, S("TF") }, + { 9, S("IF") }, + { 10, S("DF") }, + { 11, S("OF") }, + { 16, S("RF") }, + { 17, S("VM") }, + { 18, S("AC") }, + { 19, S("VIF") }, + { 20, S("ID") }, + }; + + print(S("rflags = ")); + + usize f = 0; + for (usize i = 0; i < 63; i++) { + bool has_name = f < sizeof flags / sizeof *flags && flags[f].bit == i; + + if (frame->rflags & ((u64) 1 << i)) { + if (has_name) + print(flags[f].name); + else + print_dec(i); + print(S(" ")); + } + + if (has_name) + f++; + } + + print(S("\n")); + +#define REG(X) print(S(#X)); if (S(#X).len == 2) print(S(" ")); print(S(" = ")); print_num_pad(frame->X, 16, 16, ' '); +#define REGS(A, B) REG(A) print(S(" ")); REG(B) print(S("\n")); + + REGS(rax, rbx) + REGS(rcx, rdx) + REGS(rsp, rbp) + REGS(rdi, rsi) + REGS(r8, r9) + REGS(r10, r11) + REGS(r12, r13) + REGS(r14, r15) + REGS(r14, r15) + REGS(ss, cs) + +#undef REG +#undef REGS } void interrupt_handler(interrupt_frame *frame) @@ -67,7 +170,7 @@ void interrupt_handler(interrupt_frame *frame) } print_char('\n'); - if (frame->which == 13) { + if (frame->which == 14) { str bits[8] = { S("present"), S("write"), diff --git a/stage3/isr.lua b/stage3/isr.lua index 83515a5..3c88c5e 100644 --- a/stage3/isr.lua +++ b/stage3/isr.lua @@ -25,29 +25,41 @@ end print([[ isr_common: - push r11 - push r10 - push r9 - push r8 - push rdi - push rsi - push rcx - push rdx - push rax + push r15 + push r14 + push r13 + push r12 + push r11 + push r10 + push r9 + push r8 + push rsi + push rdi + push rbp + push rdx + push rcx + push rbx + push rax cld mov rdi, rsp call interrupt_handler - pop rax - pop rdx - pop rcx - pop rsi - pop rdi - pop r8 - pop r9 - pop r10 - pop r11 + pop rax + pop rbx + pop rcx + pop rdx + pop rbp + pop rdi + pop rsi + pop r8 + pop r9 + pop r10 + pop r11 + pop r12 + pop r13 + pop r14 + pop r15 add rsp, 16 diff --git a/stage3/main.c b/stage3/main.c index 10fde84..c2ae4c8 100644 --- a/stage3/main.c +++ b/stage3/main.c @@ -12,6 +12,8 @@ #include "ps2.h" #include "thread.h" #include "shell.h" +#include "fs.h" +#include "gfx.h" char keymap[256] = { '\0' }; @@ -53,6 +55,9 @@ void keyboard_handler() } } +str dbg_map = NILS; +str dbg_disas = NILS; + void kmain() { heap_init(); @@ -97,6 +102,12 @@ void kmain() print(S("\n")); } + print(S("gfx framebuffer at ")); + print_hex(gfx_info->framebuffer); + print(S("-")); + print_hex((u64) gfx_info->framebuffer + gfx_info->pitch * gfx_info->height); + print(S("\n")); + interrupts_init(); pic_init(); thread_init(); @@ -104,6 +115,9 @@ void kmain() ata_init(); ps2_init(); + dbg_map = fs_read(S("dbg/kernel.map")); + dbg_disas = fs_read(S("dbg/kernel.dis.asm")); + shell_run_cmd(S("run init")); thread *keyboard_thread = thread_create(S("keyboard"), &keyboard_handler); diff --git a/stage3/shell.c b/stage3/shell.c index b0e1fce..dfcea43 100644 --- a/stage3/shell.c +++ b/stage3/shell.c @@ -101,7 +101,7 @@ static void cmd_run(str arg) } else { str iter = f; for (;;) { - str cmd = str_split_walk(&iter, S("\n")); + str cmd = str_walk(&iter, S("\n")); if (cmd.data == nil) break; shell_run_cmd(cmd); @@ -189,7 +189,7 @@ static command registry[] = { void shell_run_cmd(str cmd) { - str prog = str_split_walk(&cmd, S(" \t")); + str prog = str_walk(&cmd, S(" \t")); if (prog.len == 0) return; diff --git a/stage3/string.c b/stage3/string.c index 2f95b99..836f6a3 100644 --- a/stage3/string.c +++ b/stage3/string.c @@ -39,22 +39,22 @@ usize str_parse_num(str s, u8 base, u64 *x) if (c >= '0' && c <= '9') d = c - '0'; else if (c >= 'a' && c <= 'z') - d = c - 'a'; - else if (c >= 'A' && c <= 'z') - d = c - 'A'; + d = c - 'a' + 10; + else if (c >= 'A' && c <= 'Z') + d = c - 'A' + 10; else return i; if (d >= base) return i; - *x = *x * base + d; + *x = (*x) * base + d; } return s.len; } -str str_split_walk(str *s, str sep) +str str_walk(str *s, str sep) { if (s->len == 0) return NILS; @@ -62,11 +62,32 @@ str str_split_walk(str *s, str sep) usize x = str_find(*s, sep); usize o = x + (x < s->len); - s->len -= o; - s->data += o; + *s = str_advance(*s, o); if (x == 0) - return str_split_walk(s, sep); + return str_walk(s, sep); else return (str) { x, s->data - o }; } + +str str_eat(str s, str tokens) +{ + while (s.len > 0 && match_char(s.data[0], tokens)) + s = str_advance(s, 1); + return s; +} + +str str_advance(str s, usize x) +{ + s.len -= x; + s.data += x; + return s; +} + +bool str_start(str s, str start) +{ + if (s.len < start.len) + return false; + s.len = start.len; + return str_cmp(s, start) == 0; +} diff --git a/stage3/string.h b/stage3/string.h index 8375136..fc91522 100644 --- a/stage3/string.h +++ b/stage3/string.h @@ -6,6 +6,9 @@ isize str_cmp(str s1, str s2); usize str_find(str s, str tokens); usize str_parse_num(str s, u8 base, u64 *x); -str str_split_walk(str *s, str sep); +str str_walk(str *s, str sep); +str str_eat(str s, str tokens); +str str_advance(str s, usize x); +bool str_start(str s, str start); #endif |