Implement double-fault handling

finchie
Dec 26, 2023, 12:51 PM
QJPM62J2AY4RISVQIIKS33OK6QUBUHYILETWZ42CSDA77PN2VU4AC

Dependencies

  • [2] K5LGXRU2 Create simple kernel toolchain

Change contents

  • edit in kernel/src/main.rs at line 3
    [2.1961]
    [2.1961]
    #![feature(abi_x86_interrupt)]
    mod gdt;
    mod interrupts;
  • edit in kernel/src/main.rs at line 16
    [2.2125]
    [2.2125]
    init();
  • edit in kernel/src/main.rs at line 21
    [2.2140]
    [2.2140]
    fn init() {
    gdt::init();
    interrupts::init();
    }
  • replacement in kernel/src/main.rs at line 27
    [2.2157][2.2157:2192]()
    fn panic(_info: &PanicInfo) -> ! {
    [2.2157]
    [2.2192]
    fn panic(info: &PanicInfo) -> ! {
  • file addition: interrupts.rs (----------)
    [2.1903]
    use lazy_static::lazy_static;
    use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
    lazy_static! {
    static ref IDT: InterruptDescriptorTable = {
    let mut idt = InterruptDescriptorTable::new();
    unsafe {
    idt.double_fault
    .set_handler_fn(double_fault_handler)
    .set_stack_index(crate::gdt::DOUBLE_FAULT_INST_INDEX);
    }
    idt
    };
    }
    pub fn init() {
    IDT.load();
    }
    extern "x86-interrupt" fn double_fault_handler(
    stack_frame: InterruptStackFrame,
    _error_code: u64,
    ) -> ! {
    panic!("Double fault: {:#?}", stack_frame);
    }
  • file addition: gdt.rs (----------)
    [2.1903]
    use lazy_static::lazy_static;
    use x86_64::structures::gdt::{Descriptor, GlobalDescriptorTable, SegmentSelector};
    use x86_64::structures::tss::TaskStateSegment;
    use x86_64::VirtAddr;
    pub const DOUBLE_FAULT_INST_INDEX: u16 = 0;
    const STACK_SIZE: usize = 4096 * 5;
    lazy_static! {
    static ref TSS: TaskStateSegment = {
    let mut tss = TaskStateSegment::new();
    tss.interrupt_stack_table[DOUBLE_FAULT_INST_INDEX as usize] = {
    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
    };
    static ref GDT_SEGMENTS: SegmentedTable = {
    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));
    SegmentedTable {
    table: gdt,
    code_selector,
    tss_selector,
    }
    };
    }
    struct SegmentedTable {
    table: GlobalDescriptorTable,
    code_selector: SegmentSelector,
    tss_selector: SegmentSelector,
    }
    pub fn init() {
    use x86_64::instructions::segmentation::{Segment, CS};
    use x86_64::instructions::tables::load_tss;
    GDT_SEGMENTS.table.load();
    unsafe {
    CS::set_reg(GDT_SEGMENTS.code_selector);
    load_tss(GDT_SEGMENTS.tss_selector);
    }
    }
  • edit in kernel/Cargo.toml at line 8
    [2.2350]
    lazy_static = { version = "1.4.0", features = ["spin_no_std"] }
    x86_64 = "0.14.11"
  • edit in Cargo.lock at line 144
    [2.6063]
    [2.6063]
    [[package]]
    name = "bit_field"
    version = "0.10.2"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
  • edit in Cargo.lock at line 511
    [2.15133]
    [2.15133]
    "lazy_static",
    "x86_64",
  • edit in Cargo.lock at line 549
    [2.15927]
    [2.15927]
    [[package]]
    name = "lazy_static"
    version = "1.4.0"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
    dependencies = [
    "spin",
    ]
  • edit in Cargo.lock at line 752
    [2.21049]
    [2.21049]
    [[package]]
    name = "rustversion"
    version = "1.0.14"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
  • edit in Cargo.lock at line 840
    [2.23073]
    [2.23073]
    name = "spin"
    version = "0.5.2"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
    [[package]]
  • edit in Cargo.lock at line 925
    [2.25148]
    [2.25148]
    [[package]]
    name = "volatile"
    version = "0.4.6"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "442887c63f2c839b346c192d047a7c87e73d0689c9157b00b53dcc27dd5ea793"
  • edit in Cargo.lock at line 1106
    [2.30681]
    [[package]]
    name = "x86_64"
    version = "0.14.11"
    source = "registry+https://github.com/rust-lang/crates.io-index"
    checksum = "3b835097a84e4457323331ec5d6eb23d096066cbfb215d54096dcb4b2e85f500"
    dependencies = [
    "bit_field",
    "bitflags 2.4.1",
    "rustversion",
    "volatile",
    ]