Skip to content

Commit

Permalink
handling double faults in a seperate stack segment
Browse files Browse the repository at this point in the history
  • Loading branch information
Blindspot22 committed May 18, 2024
1 parent 7c57ee0 commit 3318cd9
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 2 deletions.
46 changes: 46 additions & 0 deletions src/gdt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use x86_64::VirtAddr;
use x86_64::structures::tss::TaskStateSegment;
use lazy_static::lazy_static;
use x86_64::structures::gdt::{GlobalDescriptorTable, Descriptor, SegmentSelector};

pub const DOUBLE_FAULT_IST_INDEX: u16 = 0;

pub fn init() {
use x86_64::instructions::tables::load_tss;
use x86_64::instructions::segmentation::{CS, Segment};

GDT.0.load();
unsafe {
CS::set_reg(GDT.1.code_selector);
load_tss(GDT.1.tss_selector);
}
}

struct Selectors {
code_selector: SegmentSelector,
tss_selector: SegmentSelector,
}

lazy_static! {
static ref GDT: (GlobalDescriptorTable, Selectors) = {
let mut gdt = GlobalDescriptorTable::new();
let code_selector = gdt.add_entry(Descriptor::kernel_code_segment());
let tss_selector = gdt.add_entry(Descriptor::tss_segment(&TSS));
(gdt, Selectors { code_selector, tss_selector })
};
}

lazy_static! {
static ref TSS: TaskStateSegment = {
let mut tss = TaskStateSegment::new();
tss.interrupt_stack_table[DOUBLE_FAULT_IST_INDEX as usize] = {
const STACK_SIZE: usize = 4096 * 5;
static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE];

let stack_start = VirtAddr::from_ptr(unsafe { &STACK });
let stack_end = stack_start + STACK_SIZE;
stack_end
};
tss
};
}
11 changes: 11 additions & 0 deletions src/interrupts.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::println;
use crate::gdt;

use lazy_static::lazy_static;
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
Expand All @@ -7,10 +8,16 @@ lazy_static! {
static ref IDT: InterruptDescriptorTable = {
let mut idt = InterruptDescriptorTable::new();
idt.breakpoint.set_handler_fn(breakpoint_handler);
unsafe {
idt.double_fault.set_handler_fn(double_fault_handler)
.set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX); // new
}

idt
};
}


pub fn init_idt() {
IDT.load();
}
Expand All @@ -19,6 +26,10 @@ extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame){
println!("EXCEPTION: BREAKPOINT\n{stack_frame:#?}");
}

extern "x86-interrupt" fn double_fault_handler(stack_frame: InterruptStackFrame, _error_code: u64) -> ! {
panic!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame);
}

#[test_case]
fn test_breakpoint_exception() {
x86_64::instructions::interrupts::int3();
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
pub mod serial;
pub mod vga_buffer;
pub mod interrupts;
pub mod gdt;

use core::panic::PanicInfo;

Expand Down Expand Up @@ -50,6 +51,7 @@ pub extern "C" fn _start() -> ! {
}

pub fn init() {
gdt::init();
interrupts::init_idt();
}

Expand Down
2 changes: 0 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ pub extern "C" fn _start() -> ! {

orust_os::init();

x86_64::instructions::interrupts::int3();

#[cfg(test)]
test_main();

Expand Down

0 comments on commit 3318cd9

Please sign in to comment.