summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile21
-rw-r--r--stage3/font.c4
-rw-r--r--stage3/interrupts.c117
-rw-r--r--stage3/isr.lua48
-rw-r--r--stage3/main.c14
-rw-r--r--stage3/shell.c4
-rw-r--r--stage3/string.c37
-rw-r--r--stage3/string.h5
9 files changed, 204 insertions, 47 deletions
diff --git a/.gitignore b/.gitignore
index 6f17dd4..6132154 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
*.o
*.img
*.map
+*.dis.asm
bx_enh_dbg.ini
stage3/isr.asm
fs.tar
diff --git a/Makefile b/Makefile
index 0cb067c..ee856d0 100644
--- a/Makefile
+++ b/Makefile
@@ -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