add serial logging for exceptions, fix virtualbox issue

This commit is contained in:
Benji Dial 2024-05-19 13:27:11 -04:00
parent f8ff95f192
commit 649ff9636f
6 changed files with 169 additions and 38 deletions

View file

@ -0,0 +1,27 @@
#pragma once
#include <stdint.h>
namespace hilbert::kernel {
extern "C" void serial_init();
extern "C" void serial_putchar(char ch);
static inline void serial_putstr(const char *str) {
while (*str) {
serial_putchar(*str);
++str;
}
}
template <int digits, int dot_every = 4>
static inline void serial_puthex(uint64_t n) {
for (int d = digits - 1; d >= 0; --d) {
serial_putchar("0123456789abcdef"[(n >> (d * 4)) & 0xf]);
if (d % dot_every == 0 && d != 0)
serial_putchar('.');
}
}
}

View file

@ -2,7 +2,7 @@ SOURCES = \
storage/bd/memory.cpp storage/fs/tarfs.cpp application.asm application.cpp \ storage/bd/memory.cpp storage/fs/tarfs.cpp application.asm application.cpp \
framebuffer.cpp interrupts.asm interrupts.cpp allocator.cpp storage.cpp \ framebuffer.cpp interrupts.asm interrupts.cpp allocator.cpp storage.cpp \
syscall.cpp utility.cpp paging.asm paging.cpp entry.cpp input.cpp panic.cpp \ syscall.cpp utility.cpp paging.asm paging.cpp entry.cpp input.cpp panic.cpp \
vfile.cpp vfile.cpp serial.asm
build/%.asm.o: source/%.asm build/%.asm.o: source/%.asm
@mkdir -p $(@D) @mkdir -p $(@D)

View file

@ -3,6 +3,7 @@
#include <hilbert/kernel/application.hpp> #include <hilbert/kernel/application.hpp>
#include <hilbert/kernel/framebuffer.hpp> #include <hilbert/kernel/framebuffer.hpp>
#include <hilbert/kernel/paging.hpp> #include <hilbert/kernel/paging.hpp>
#include <hilbert/kernel/serial.hpp>
#include <hilbert/kernel/input.hpp> #include <hilbert/kernel/input.hpp>
#include <hilbert/kernel/panic.hpp> #include <hilbert/kernel/panic.hpp>
#include <hilbert/kernel/vfile.hpp> #include <hilbert/kernel/vfile.hpp>
@ -97,6 +98,8 @@ static bool have_initfs;
extern "C" [[noreturn]] void entry() { extern "C" [[noreturn]] void entry() {
serial_init();
//TODO?: maybe we should check if the limine requests were //TODO?: maybe we should check if the limine requests were
// fulfilled and display some error message if not // fulfilled and display some error message if not

View file

@ -227,19 +227,51 @@ section .bss
section .text section .text
isr_start:
push rcx
mov rcx, qword [rsp + 8]
mov qword [rsp + 8], rax
push rdx
push rdi
push rsi
push r8
push r9
push r10
push r11
push rcx
;this is a complete hack but it works
mov rdi, qword [rsp + 10 * 8 + 4 * 8]
cmp rdi, 0x38
je .fix_ss
ret
.fix_ss:
mov qword [rsp + 10 * 8 + 4 * 8], 0x3b
ret
isr_end:
pop rcx
pop r11
pop r10
pop r9
pop r8
pop rsi
pop rdi
pop rdx
mov rax, qword [rsp + 8]
mov qword [rsp + 8], rcx
pop rcx
ret
extern on_keyboard_interrupt extern on_keyboard_interrupt
keyboard_isr: keyboard_isr:
push r11 call isr_start
push r10
push r9
push r8
push rsi
push rdi
push rdx
push rcx
push rax
call wait_read_ps2 call wait_read_ps2
in al, 0x60 in al, 0x60
@ -250,15 +282,7 @@ keyboard_isr:
mov al, 0x20 mov al, 0x20
out 0x20, al out 0x20, al
pop rax call isr_end
pop rcx
pop rdx
pop rdi
pop rsi
pop r8
pop r9
pop r10
pop r11
iretq iretq
@ -266,15 +290,7 @@ extern on_mouse_interrupt
mouse_isr: mouse_isr:
push r11 call isr_start
push r10
push r9
push r8
push rsi
push rdi
push rdx
push rcx
push rax
call wait_read_ps2 call wait_read_ps2
in al, 0x60 in al, 0x60
@ -286,15 +302,7 @@ mouse_isr:
out 0x20, al out 0x20, al
out 0xa0, al out 0xa0, al
pop rax call isr_end
pop rcx
pop rdx
pop rdi
pop rsi
pop r8
pop r9
pop r10
pop r11
iretq iretq

View file

@ -1,4 +1,5 @@
#include <hilbert/kernel/framebuffer.hpp> #include <hilbert/kernel/framebuffer.hpp>
#include <hilbert/kernel/serial.hpp>
#include <hilbert/kernel/input.hpp> #include <hilbert/kernel/input.hpp>
#include <hilbert/kernel/panic.hpp> #include <hilbert/kernel/panic.hpp>
@ -36,13 +37,47 @@ struct [[gnu::packed]] exception_info_t {
extern exception_info_t exception_info; extern exception_info_t exception_info;
static inline void print_reg(const char *regname, uint64_t value) {
serial_putstr(" ");
serial_putstr(regname);
serial_putstr(" = 0x");
serial_puthex<16>(value);
serial_putchar('\n');
}
extern "C" [[noreturn]] void print_exception() { extern "C" [[noreturn]] void print_exception() {
//so exception_info's type is known by gdb //so exception_info's type is known by gdb
exception_info_t the_exception_info = exception_info; exception_info_t the_exception_info = exception_info;
(void)the_exception_info; (void)the_exception_info;
//TODO: log exception, and recover if possible. serial_putstr("exception 0x");
serial_puthex<2>(exception_info.exception_number);
serial_putchar('\n');
if (exception_info.has_error)
print_reg("error code", exception_info.error);
print_reg("rflags", exception_info.rflags);
print_reg("rip", exception_info.rip);
print_reg("cr2", exception_info.cr2);
print_reg("cr3", exception_info.cr3);
print_reg("rax", exception_info.rax);
print_reg("rbx", exception_info.rbx);
print_reg("rcx", exception_info.rcx);
print_reg("rdx", exception_info.rdx);
print_reg("rdi", exception_info.rdi);
print_reg("rsi", exception_info.rsi);
print_reg("rbp", exception_info.rbp);
print_reg("rsp", exception_info.rsp);
print_reg("r8 ", exception_info.r8 );
print_reg("r9 ", exception_info.r9 );
print_reg("r10", exception_info.r10);
print_reg("r11", exception_info.r11);
print_reg("r12", exception_info.r12);
print_reg("r13", exception_info.r13);
print_reg("r14", exception_info.r14);
print_reg("r15", exception_info.r15);
panic(0xba40bb); panic(0xba40bb);

58
kernel/source/serial.asm Normal file
View file

@ -0,0 +1,58 @@
bits 64
global serial_init
global serial_putchar
section .text
serial_init:
xor al, al
mov dx, 0x03f9
out dx, al
mov al, 0x80
mov dx, 0x03fb
out dx, al
mov al, 0x03
mov dx, 0x03f8
out dx, al
xor al, al
mov dx, 0x03f9
out dx, al
mov al, 0x03
mov dx, 0x03fb
out dx, al
mov al, 0xc7
mov dx, 0x03fa
out dx, al
ret
serial_putchar:
cmp dil, 0x0a
je .do_cr
.cr_ret:
mov dx, 0x03fd
.loop:
in al, dx
test al, 0x20
jz .loop
mov al, dil
mov dx, 0x03f8
out dx, al
ret
.do_cr:
mov dil, 0x0d
call serial_putchar
mov dil, 0x0a
jmp .cr_ret