add limine.conf (oops) and make exceptions more helpful
This commit is contained in:
10
limine.conf
Normal file
10
limine.conf
Normal 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
|
||||
@@ -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(®isters);
|
||||
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(®isters);
|
||||
|
||||
// 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();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(());
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user