diff --git a/src/interrupts.rs b/src/interrupts.rs new file mode 100644 index 0000000..dbeae7d --- /dev/null +++ b/src/interrupts.rs @@ -0,0 +1,24 @@ +use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame}; +use crate::println; +use lazy_static::lazy_static; + +lazy_static! { + static ref IDT: InterruptDescriptorTable = { + let mut idt = InterruptDescriptorTable::new(); + idt.breakpoint.set_handler_fn(breakpoint_handler); + idt + }; +} + +pub fn init_idt() { + IDT.load(); +} + +extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame) { + println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame); +} + +#[test_case] +fn test_breakpoint_exceptions() { + x86_64::instructions::interrupts::int3(); +} diff --git a/src/lib.rs b/src/lib.rs index 052452f..4b3b12a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,11 +3,17 @@ #![feature(custom_test_frameworks)] #![test_runner(crate::test_runner)] #![reexport_test_harness_main = "test_main"] +#![feature(abi_x86_interrupt)] use core::panic::PanicInfo; pub mod serial; pub mod vga_buffer; +pub mod interrupts; + +pub fn init() { + interrupts::init_idt(); +} pub trait Testable { fn run(&self) -> (); @@ -59,6 +65,7 @@ pub fn exit_qemu(exit_code: QemuExitCode) { #[cfg(test)] #[no_mangle] pub extern "C" fn _start() -> ! { + init(); test_main(); loop {} } diff --git a/src/main.rs b/src/main.rs index f7996e4..9ddd14b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,6 +19,9 @@ pub extern "C" fn _start() -> ! { println!("System booted successfully"); + os::init(); + + x86_64::instructions::interrupts::int3(); #[cfg(test)] test_main();