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 super::idt_set_gate;
|
||||||
use crate::hcf;
|
use crate::hcf;
|
||||||
use crate::{log_error, log_info};
|
use crate::{log_error, log_info};
|
||||||
@@ -33,46 +35,97 @@ struct Registers {
|
|||||||
ss: usize,
|
ss: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FAULTED: AtomicU8 = AtomicU8::new(0);
|
||||||
|
|
||||||
extern "C" fn exception_handler(registers: u64) {
|
extern "C" fn exception_handler(registers: u64) {
|
||||||
let registers = unsafe { *(registers as *const Registers) };
|
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;
|
let int = registers.int;
|
||||||
|
|
||||||
match int {
|
match int {
|
||||||
0x00 => {
|
0x00 => {
|
||||||
crate::drivers::serial::write_string("DIVISION ERROR!");
|
log_error!("DIVISION ERROR!");
|
||||||
}
|
}
|
||||||
0x06 => {
|
0x06 => {
|
||||||
crate::drivers::serial::write_string("INVALID OPCODE!");
|
log_error!("INVALID OPCODE!");
|
||||||
}
|
}
|
||||||
0x08 => {
|
0x08 => {
|
||||||
crate::drivers::serial::write_string("DOUBLE FAULT!");
|
log_error!("DOUBLE FAULT!");
|
||||||
}
|
}
|
||||||
0x0D => {
|
0x0D => {
|
||||||
crate::drivers::serial::write_string("GENERAL PROTECTION FAULT!");
|
log_error!("GENERAL PROTECTION FAULT!");
|
||||||
}
|
}
|
||||||
0x0E => {
|
0x0E => {
|
||||||
crate::drivers::serial::write_string("PAGE FAULT!");
|
log_error!("PAGE FAULT!");
|
||||||
}
|
}
|
||||||
0xFF => {
|
0xFF => {
|
||||||
crate::drivers::serial::write_string("EXCEPTION!");
|
log_error!("EXCEPTION!");
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
crate::drivers::serial::write_string("EXCEPTION!");
|
log_error!("EXCEPTION!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// log_info!(
|
print_registers(®isters);
|
||||||
// "INT: {:x} RIP: {:X}, CS: {:X}, EFLAGS: {:b}",
|
|
||||||
// int,
|
|
||||||
// registers.rip,
|
|
||||||
// registers.cs,
|
|
||||||
// registers.rflags
|
|
||||||
// );
|
|
||||||
|
|
||||||
// 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*
|
// *macro intensifies*
|
||||||
@@ -80,20 +133,25 @@ macro_rules! exception_function {
|
|||||||
($code:expr, $handler:ident) => {
|
($code:expr, $handler:ident) => {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
extern "C" fn $handler() {
|
extern "C" fn $handler() {
|
||||||
|
crate::arch::push_gprs();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
core::arch::asm!(
|
core::arch::asm!(
|
||||||
"pushfq",
|
|
||||||
"push {0:r}",
|
"push {0:r}",
|
||||||
"mov rdi, rsp",
|
"mov rdi, rsp",
|
||||||
"call {1}",
|
"call {1}",
|
||||||
"pop {0:r}",
|
"pop {0:r}",
|
||||||
"mov rsp, rdi",
|
"mov rsp, rdi",
|
||||||
"popfq",
|
|
||||||
in(reg) $code,
|
in(reg) $code,
|
||||||
sym exception_handler,
|
sym exception_handler,
|
||||||
|
options(nostack)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
crate::arch::pop_gprs();
|
||||||
|
|
||||||
|
super::signal_end_of_interrupt();
|
||||||
|
|
||||||
hcf();
|
hcf();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -34,3 +34,78 @@ pub unsafe fn cpu_set_msr(msr: u32, lo: &u32, hi: &u32) {
|
|||||||
in("edx") *hi,
|
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 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;
|
// use crate::drivers::fs::vfs::VfsFileSystem;
|
||||||
|
|
||||||
@@ -8,41 +12,48 @@ use crate::drivers::fs::vfs::{vfs_open, UserCred};
|
|||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
struct StackFrame {
|
struct StackFrame {
|
||||||
back: *const StackFrame,
|
back: *const StackFrame,
|
||||||
rip: u64,
|
rip: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_stack_trace(max_frames: usize, rbp: u64) {
|
pub fn print_stack_trace(max_frames: usize, rbp: u64) {
|
||||||
let mut stackframe = rbp as *const StackFrame;
|
let mut stackframe = rbp as *const StackFrame;
|
||||||
|
let mut frames_processed = 0;
|
||||||
|
|
||||||
crate::println!("Stack Trace:");
|
log_info!("{:-^width$}", " Stack Trace ", width = 98);
|
||||||
for _frame in 0..max_frames {
|
for _ in 0..max_frames {
|
||||||
if stackframe.is_null() || unsafe { core::ptr::read_unaligned(stackframe).back.is_null() } {
|
frames_processed += 1;
|
||||||
|
|
||||||
|
if stackframe.is_null() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let instruction_pointer = unsafe { (*stackframe).rip };
|
let instruction_ptr = unsafe { (*stackframe).rip };
|
||||||
|
|
||||||
if instruction_pointer == 0x0 {
|
if instruction_ptr < *HHDM_OFFSET {
|
||||||
unsafe {
|
unsafe {
|
||||||
stackframe = (*stackframe).back;
|
stackframe = (*stackframe).back;
|
||||||
};
|
};
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::print!(" {:#X} ", instruction_pointer);
|
let instruction_info = get_function_name(instruction_ptr as u64);
|
||||||
|
|
||||||
let instrcution_info = get_function_name(instruction_pointer);
|
let address_info = if let Ok((function_name, function_offset)) = instruction_info {
|
||||||
|
&alloc::format!("<{}+{:#X}>", function_name, function_offset)
|
||||||
if let Ok((function_name, function_offset)) = instrcution_info {
|
|
||||||
crate::println!("<{}+{:#X}>", function_name, function_offset);
|
|
||||||
} else {
|
} else {
|
||||||
crate::println!();
|
""
|
||||||
}
|
};
|
||||||
|
|
||||||
|
log_info!("{:#X} {address_info}", instruction_ptr);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
stackframe = (*stackframe).back;
|
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), ()> {
|
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));
|
previous_symbol = Some((function_name, address));
|
||||||
}
|
}
|
||||||
|
|
||||||
unreachable!();
|
return Err(());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,6 +102,10 @@ pub fn kmain() -> ! {
|
|||||||
.read(0, 0, 0)
|
.read(0, 0, 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
*(0xDEADBEEF as *mut u32) = 0xBAADF00D;
|
||||||
|
};
|
||||||
|
|
||||||
// let file = vfs_open("/example.txt").unwrap();
|
// let file = vfs_open("/example.txt").unwrap();
|
||||||
|
|
||||||
// as a sign that we didnt panic
|
// as a sign that we didnt panic
|
||||||
|
|||||||
Reference in New Issue
Block a user