CPU Exception

This commit is contained in:
Sainnhe Park 2022-01-09 17:13:30 +08:00
parent c15df2a6a9
commit 70099da497
3 changed files with 37 additions and 0 deletions

19
src/interrupts.rs Normal file
View File

@ -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);
}

View File

@ -3,10 +3,12 @@
#![feature(custom_test_frameworks)] #![feature(custom_test_frameworks)]
#![test_runner(crate::test_runner)] #![test_runner(crate::test_runner)]
#![reexport_test_harness_main = "test_main"] #![reexport_test_harness_main = "test_main"]
#![feature(abi_x86_interrupt)]
use core::panic::PanicInfo; use core::panic::PanicInfo;
pub mod serial; pub mod serial;
pub mod vga_buffer; pub mod vga_buffer;
pub mod interrupts;
pub trait Testable { pub trait Testable {
fn run(&self) -> (); fn run(&self) -> ();
@ -41,6 +43,7 @@ pub fn test_panic_handler(info: &PanicInfo) -> ! {
#[cfg(test)] #[cfg(test)]
#[no_mangle] #[no_mangle]
pub extern "C" fn _start() -> ! { pub extern "C" fn _start() -> ! {
init();
test_main(); test_main();
loop {} loop {}
} }
@ -51,6 +54,14 @@ fn panic(info: &PanicInfo) -> ! {
test_panic_handler(info) test_panic_handler(info)
} }
#[test_case]
fn test_breakpoint_exception() {
x86_64::instructions::interrupts::int3();
// 如果程序继续运行则说明测试成功
// 用 cargo test 运行全部测试
// 或 cargo test --lib 仅运行库测试
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)] #[repr(u32)]
pub enum QemuExitCode { pub enum QemuExitCode {
@ -67,3 +78,6 @@ pub fn exit_qemu(exit_code: QemuExitCode) {
} }
} }
pub fn init() {
interrupts::init_idt();
}

View File

@ -14,6 +14,10 @@ use anos::println;
pub extern "C" fn _start() -> ! { pub extern "C" fn _start() -> ! {
println!("Hello World{}", "!"); println!("Hello World{}", "!");
anos::init();
x86_64::instructions::interrupts::int3();
println!("It didn't crash!");
#[cfg(test)] #[cfg(test)]
test_main(); test_main();