diff --git a/Cargo.lock b/Cargo.lock index 20cb404..f64ef5f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9,9 +9,22 @@ dependencies = [ "bootloader", "lazy_static", "spin", - "volatile", + "volatile 0.2.7", + "x86_64", ] +[[package]] +name = "bit_field" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bootloader" version = "0.9.19" @@ -38,3 +51,20 @@ name = "volatile" version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6b06ad3ed06fef1713569d547cdbdb439eafed76341820fb0e0344f29a41945" + +[[package]] +name = "volatile" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4c2dbd44eb8b53973357e6e207e370f0c1059990df850aca1eca8947cf464f0" + +[[package]] +name = "x86_64" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4522ae25e1e0dbf4302ffde77e55c43afe3d7523cba662943b5de8ff04871f6c" +dependencies = [ + "bit_field", + "bitflags", + "volatile 0.4.4", +] diff --git a/Cargo.toml b/Cargo.toml index 436089f..04fb44b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ edition = "2018" bootloader = "0.9.8" volatile = "0.2.6" spin = "0.5.2" +x86_64 = "0.14.2" [dependencies.lazy_static] version = "1.0" diff --git a/src/interrupts.rs b/src/interrupts.rs new file mode 100644 index 0000000..6b94536 --- /dev/null +++ b/src/interrupts.rs @@ -0,0 +1,19 @@ +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); +} diff --git a/src/main.rs b/src/main.rs index acbe823..8eebc36 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,14 @@ #![no_std] #![no_main] +#![feature(custom_test_frameworks)] +#![test_runner(crate::test_runner)] +#![reexport_test_harness_main = "test_main"] + +#![feature(abi_x86_interrupt)] + mod vga_buffer; +mod interrupts; use core::panic::PanicInfo; @@ -11,12 +18,29 @@ fn panic(info: &PanicInfo) -> ! { loop {} } +fn init() { + interrupts::init_idt(); +} + #[no_mangle] pub extern "C" fn _start() { - println!("The senate will decide your fate"); - println!(); - panic!("I am the senate"); + println!("Hello, world"); + init(); + x86_64::instructions::interrupts::int3(); + + #[cfg(test)] + test_main(); + + println!("It did not crash!"); loop {} } + +#[cfg(test)] +fn test_runner(tests: &[&dyn Fn()]) { + println!("Running {} tests", tests.len()); + for test in tests { + test(); + } +}