diff --git a/src/arch/x86_64/idt.rs b/src/arch/x86_64/idt.rs index 41943cdd04d24923cce15be803d9029cfd44e819..ba81aa95b931b8251e6afc9abb083849722bb458 100644 --- a/src/arch/x86_64/idt.rs +++ b/src/arch/x86_64/idt.rs @@ -1,6 +1,9 @@ -use crate::{debug, info}; +use crate::{debug, error, info}; use spin::Lazy; -use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame}; +use x86_64::{ + registers::control::Cr2, + structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode}, +}; // @@ -67,16 +70,28 @@ extern "x86-interrupt" fn double_fault(stack: InterruptStackFrame, ec: u64) -> ! panic!(); } +extern "x86-interrupt" fn page_fault(stack: InterruptStackFrame, ec: PageFaultErrorCode) { + let addr = Cr2::read(); + + error!("INT: Page fault\nAddress: {addr:?}\nErrorCode: {ec:?}\n{stack:#?}"); + + panic!(); +} + // static IDT: Lazy<InterruptDescriptorTable> = Lazy::new(|| { let mut idt = InterruptDescriptorTable::new(); + idt.breakpoint.set_handler_fn(breakpoint); + + let opt = idt.double_fault.set_handler_fn(double_fault); unsafe { - idt.double_fault - .set_handler_fn(double_fault) - .set_stack_index(DOUBLE_FAULT_IST); + opt.set_stack_index(DOUBLE_FAULT_IST); } + + idt.page_fault.set_handler_fn(page_fault); + idt }); diff --git a/src/boot/limine/addr.rs b/src/boot/limine/addr.rs new file mode 100644 index 0000000000000000000000000000000000000000..bae296dff6e328bf63e4ca4a52888a542258cad3 --- /dev/null +++ b/src/boot/limine/addr.rs @@ -0,0 +1,20 @@ +use limine::{LimineKernelAddressRequest, LimineKernelAddressResponse}; +use spin::Lazy; +use x86_64::{PhysAddr, VirtAddr}; + +// + +pub fn phys_addr() -> PhysAddr { + PhysAddr::new(KERNEL_ADDR.physical_base) +} + +pub fn virt_addr() -> VirtAddr { + VirtAddr::new(KERNEL_ADDR.virtual_base) +} + +// + +static KERNEL_ADDR: Lazy<&'static LimineKernelAddressResponse> = Lazy::new(|| { + static REQ: LimineKernelAddressRequest = LimineKernelAddressRequest::new(0); + REQ.get_response().get().unwrap() +}); diff --git a/src/boot/limine/mem.rs b/src/boot/limine/mem.rs index 40c8350ccbab9c4be03aa8ddb1fda44232ea5d69..ab4b1fe5841c820f129c4e8b1f717f2bb70f7f8f 100644 --- a/src/boot/limine/mem.rs +++ b/src/boot/limine/mem.rs @@ -1,4 +1,4 @@ -use crate::{debug, mem::map::Memmap}; +use crate::mem::map::Memmap; use limine::{LimineMemmapEntry, LimineMemmapRequest, LimineMemoryMapEntryType, NonNullPtr}; use spin::Lazy; diff --git a/src/boot/limine/mod.rs b/src/boot/limine/mod.rs index c5657a8152cfb109d939b861c21e5013131ff518..a0288990b00450db288f597a52ad7fe8968c814e 100644 --- a/src/boot/limine/mod.rs +++ b/src/boot/limine/mod.rs @@ -3,12 +3,15 @@ use crate::{arch, kernel_main}; // +pub use addr::phys_addr; +pub use addr::virt_addr; pub use mem::memmap; pub use mem::memtotal; pub use term::_print; // +mod addr; mod cmdline; mod framebuffer; mod mem; diff --git a/src/main.rs b/src/main.rs index 640553e533f2a9c91a3c07645806dd34ee243380..7deb83197b1d4f8fd9a350ffe3f4a667afc502da 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,12 @@ // +use x86_64::{ + registers::control::Cr3, + structures::paging::{PageTable, PhysFrame}, + VirtAddr, +}; + extern crate alloc; // @@ -50,8 +56,46 @@ fn kernel_main() -> ! { debug!("Entering kernel_main"); debug!("Cmdline: {:?}", env::Arguments::get()); + debug!( + "Kernel addr: {:?} {:?}", + boot::virt_addr(), + boot::phys_addr() + ); + mem::init(); + /* let (l4, _) = Cr3::read(); + + let read_pt = |frame: PhysFrame| -> &mut PageTable { + let addr = VirtAddr::new(frame.start_address().as_u64()); + let table: *mut PageTable = addr.as_mut_ptr(); + unsafe { &mut *table } + }; + + for (i, e) in read_pt(l4).iter().enumerate() { + if !e.is_unused() { + println!("L4 entry {i}: {e:?}"); + + for (i, e) in read_pt(e.frame().unwrap()).iter().enumerate() { + if !e.is_unused() { + println!(" L3 entry {i}: {e:?}"); + + for (i, e) in read_pt(e.frame().unwrap()).iter().enumerate() { + if !e.is_unused() { + println!(" L2 entry {i}: {e:?}"); + + for (i, e) in read_pt(e.frame().unwrap()).iter().enumerate() { + if !e.is_unused() { + println!(" L1 entry {i}: {e:?}"); + } + } + } + } + } + } + } + } */ + // ofc. every kernel has to have this cringy ascii name splash info!("\n{}\n", include_str!("./splash")); diff --git a/src/mem/pfa.rs b/src/mem/pfa.rs index 442644a761ea76904fcaa492c5ba047058e51f7f..b9241c9bdc6585b35a3ca18e553fbad2ace69976 100755 --- a/src/mem/pfa.rs +++ b/src/mem/pfa.rs @@ -1,7 +1,6 @@ use super::map::Memmap; use crate::{ boot, debug, - log::{test_log_level, LogLevel}, mem::bump, util::{bitmap::Bitmap, fmt::NumberPostfix}, }; @@ -79,7 +78,7 @@ pub fn init() { #[cfg(debug_assertions)] bitmap.set(page as _, false).unwrap(); #[cfg(not(debug_assertions))] - let _ = bitmap.set(page as _, false); + let res = bitmap.set(page as _, false); } } @@ -109,5 +108,5 @@ pub struct PageFrameAllocator { // impl PageFrameAllocator { - pub fn free_page(&mut self, addr: u64) {} + pub fn free_page(&mut self, _addr: u64) {} } diff --git a/src/panic.rs b/src/panic.rs index d69b7998e0c087a58737629edd7786ab0bfd8165..1b474357bde0d187e07ad693140b06e9f5d3076d 100644 --- a/src/panic.rs +++ b/src/panic.rs @@ -6,7 +6,7 @@ use core::panic::PanicInfo; #[cfg(not(feature = "tests"))] #[panic_handler] fn panic_handler(info: &PanicInfo) -> ! { - crate::println!("{info}"); + crate::println!("Kernel {info}"); done(); } diff --git a/src/testfw.rs b/src/testfw.rs index 5c28a89089161e8f5ba8bb60f5375bef30f2e745..a3179284f819ef5ec900a2875441e1fa3525411e 100644 --- a/src/testfw.rs +++ b/src/testfw.rs @@ -63,6 +63,8 @@ pub fn test_panic_handler(info: &PanicInfo) { #[cfg(test)] mod tests { + /* use crate::{debug, println}; */ + #[allow(clippy::eq_op)] #[test_case] fn trivial() { @@ -73,10 +75,19 @@ mod tests { #[test_case] fn random_tests() { // error handling test - // stack_overflow(79999999); - // unsafe { - // *(0xFFFFFFFFDEADC0DE as *mut u8) = 42; - // } + + /* stack_overflow(79999999); */ + + /* unsafe { + *(0xFFFFFFFFDEADC0DE as *mut u8) = 42; + } */ + + /* unsafe { + let x = *(0xffffffffc18a8137 as *mut u8); + println!("Read worked: {x}"); + *(0xffffffffc18a8137 as *mut u8) = 42; + println!("Write worked"); + } */ #[allow(unused)] fn stack_overflow(n: usize) {