add limine.conf (oops) and make exceptions more helpful

This commit is contained in:
Zoe
2024-08-13 13:13:14 -05:00
parent 119e27129c
commit c373d23ee0
5 changed files with 191 additions and 33 deletions

10
limine.conf Normal file
View File

@@ -0,0 +1,10 @@
# Timeout in seconds that Limine will use before automatically booting.
timeout: 3
/CappuccinOS
protocol: limine
kernel_path: boot():/boot/CappuccinOS.elf
cmdline: fat_in_mem=false big_fat_phony
module_path: boot():/boot/initramfs.img

View File

@@ -1,3 +1,5 @@
use core::sync::atomic::{AtomicU8, Ordering};
use super::idt_set_gate;
use crate::hcf;
use crate::{log_error, log_info};
@@ -33,46 +35,97 @@ struct Registers {
ss: usize,
}
static FAULTED: AtomicU8 = AtomicU8::new(0);
extern "C" fn exception_handler(registers: u64) {
let registers = unsafe { *(registers as *const Registers) };
// crate::println!("{:X?}", registers);
match FAULTED.fetch_add(1, Ordering::SeqCst) {
0 => {}
1 => {
log_error!("Exception Loop detected, stopping here");
print_registers(&registers);
hcf();
}
// We have faulted multiple times, this could indicate an issue with the allocator, stop everything without further logging since it will likely cause more issues
_ => hcf(),
}
let int = registers.int;
match int {
0x00 => {
crate::drivers::serial::write_string("DIVISION ERROR!");
log_error!("DIVISION ERROR!");
}
0x06 => {
crate::drivers::serial::write_string("INVALID OPCODE!");
log_error!("INVALID OPCODE!");
}
0x08 => {
crate::drivers::serial::write_string("DOUBLE FAULT!");
log_error!("DOUBLE FAULT!");
}
0x0D => {
crate::drivers::serial::write_string("GENERAL PROTECTION FAULT!");
log_error!("GENERAL PROTECTION FAULT!");
}
0x0E => {
crate::drivers::serial::write_string("PAGE FAULT!");
log_error!("PAGE FAULT!");
}
0xFF => {
crate::drivers::serial::write_string("EXCEPTION!");
log_error!("EXCEPTION!");
}
_ => {
crate::drivers::serial::write_string("EXCEPTION!");
log_error!("EXCEPTION!");
}
}
// log_info!(
// "INT: {:x} RIP: {:X}, CS: {:X}, EFLAGS: {:b}",
// int,
// registers.rip,
// registers.cs,
// registers.rflags
// );
print_registers(&registers);
// crate::arch::stack_trace::print_stack_trace(6, registers.rbp as u64);
crate::arch::stack_trace::print_stack_trace(6, registers.rbp as u64);
}
fn print_registers(registers: &Registers) {
log_info!("{:-^width$}", " REGISTERS ", width = 98);
log_info!(
"INT: {:#018X}, RIP: {:#018X}, CS: {:#018X}, FLG: {:#018X}",
registers.int,
registers.rip,
registers.cs,
registers.rflags
);
log_info!(
"RSP: {:#018X}, SS: {:#018X}, RAX: {:#018X}, RBX: {:#018X}",
registers.rsp,
registers.ss,
registers.rax,
registers.rbx
);
log_info!(
"RCX: {:#018X}, RDX: {:#018X}, RSI: {:#018X}, RDI: {:#018X}",
registers.rcx,
registers.rdx,
registers.rsi,
registers.rdi
);
log_info!(
"RBP: {:#018X}, R8: {:#018X}, R9: {:#018X}, R10: {:#018X}",
registers.rbp,
registers.r8,
registers.r9,
registers.r10
);
log_info!(
"R11: {:#018X}, R12: {:#018X}, R13: {:#018X}, R14: {:#018X}",
registers.r11,
registers.r12,
registers.r13,
registers.r14
);
log_info!("R15: {:#018X}", registers.r15);
}
// *macro intensifies*
@@ -80,20 +133,25 @@ macro_rules! exception_function {
($code:expr, $handler:ident) => {
#[inline(always)]
extern "C" fn $handler() {
crate::arch::push_gprs();
unsafe {
core::arch::asm!(
"pushfq",
"push {0:r}",
"mov rdi, rsp",
"call {1}",
"pop {0:r}",
"mov rsp, rdi",
"popfq",
in(reg) $code,
sym exception_handler,
options(nostack)
);
};
crate::arch::pop_gprs();
super::signal_end_of_interrupt();
hcf();
}
};

View File

@@ -34,3 +34,78 @@ pub unsafe fn cpu_set_msr(msr: u32, lo: &u32, hi: &u32) {
in("edx") *hi,
);
}
// struct Registers {
// // Pushed by wrapper
// int: usize,
// // Pushed by push_gprs in crate::arch::x86_64
// r15: usize,
// r14: usize,
// r13: usize,
// r12: usize,
// r11: usize,
// r10: usize,
// r9: usize,
// r8: usize,
// rbp: usize,
// rdi: usize,
// rsi: usize,
// rdx: usize,
// rcx: usize,
// rbx: usize,
// rax: usize,
// // Pushed by interrupt
// rip: usize,
// cs: usize,
// rflags: usize,
// rsp: usize,
// ss: usize,
// }
pub fn push_gprs() {
unsafe {
core::arch::asm!(
"push rax",
"push rbx",
"push rcx",
"push rdx",
"push rsi",
"push rdi",
"push rbp",
"push r8",
"push r9",
"push r10",
"push r11",
"push r12",
"push r13",
"push r14",
"push r15",
options(nostack)
)
}
}
pub fn pop_gprs() {
unsafe {
core::arch::asm!(
"pop r15",
"pop r14",
"pop r13",
"pop r12",
"pop r11",
"pop r10",
"pop r9",
"pop r8",
"pop rbp",
"pop rdi",
"pop rsi",
"pop rdx",
"pop rcx",
"pop rbx",
"pop rax",
options(nostack)
)
}
}

View File

@@ -1,6 +1,10 @@
use alloc::{borrow::ToOwned, string::String, vec::Vec};
use crate::drivers::fs::vfs::{vfs_open, UserCred};
use crate::{
drivers::fs::vfs::{vfs_open, UserCred},
log_info,
mem::HHDM_OFFSET,
};
// use crate::drivers::fs::vfs::VfsFileSystem;
@@ -8,41 +12,48 @@ use crate::drivers::fs::vfs::{vfs_open, UserCred};
#[derive(Clone, Copy, Debug)]
struct StackFrame {
back: *const StackFrame,
rip: u64,
rip: usize,
}
pub fn print_stack_trace(max_frames: usize, rbp: u64) {
let mut stackframe = rbp as *const StackFrame;
let mut frames_processed = 0;
crate::println!("Stack Trace:");
for _frame in 0..max_frames {
if stackframe.is_null() || unsafe { core::ptr::read_unaligned(stackframe).back.is_null() } {
log_info!("{:-^width$}", " Stack Trace ", width = 98);
for _ in 0..max_frames {
frames_processed += 1;
if stackframe.is_null() {
break;
}
let instruction_pointer = unsafe { (*stackframe).rip };
let instruction_ptr = unsafe { (*stackframe).rip };
if instruction_pointer == 0x0 {
if instruction_ptr < *HHDM_OFFSET {
unsafe {
stackframe = (*stackframe).back;
};
continue;
}
crate::print!(" {:#X} ", instruction_pointer);
let instruction_info = get_function_name(instruction_ptr as u64);
let instrcution_info = get_function_name(instruction_pointer);
if let Ok((function_name, function_offset)) = instrcution_info {
crate::println!("<{}+{:#X}>", function_name, function_offset);
let address_info = if let Ok((function_name, function_offset)) = instruction_info {
&alloc::format!("<{}+{:#X}>", function_name, function_offset)
} else {
crate::println!();
}
""
};
log_info!("{:#X} {address_info}", instruction_ptr);
unsafe {
stackframe = (*stackframe).back;
};
}
if frames_processed == max_frames && !stackframe.is_null() {
log_info!("... <frames omitted>");
}
}
fn get_function_name(function_address: u64) -> Result<(String, u64), ()> {
@@ -97,5 +108,5 @@ fn get_function_name(function_address: u64) -> Result<(String, u64), ()> {
previous_symbol = Some((function_name, address));
}
unreachable!();
return Err(());
}

View File

@@ -102,6 +102,10 @@ pub fn kmain() -> ! {
.read(0, 0, 0)
);
unsafe {
*(0xDEADBEEF as *mut u32) = 0xBAADF00D;
};
// let file = vfs_open("/example.txt").unwrap();
// as a sign that we didnt panic