Skip to content

Commit b287d3f

Browse files
IDT
1 parent 1e839c9 commit b287d3f

File tree

7 files changed

+72
-9
lines changed

7 files changed

+72
-9
lines changed

linker.ld

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ SECTIONS {
4747

4848
/DISCARD/ :
4949
{
50+
/*
51+
Weird section that always puts itself at the start and causes the binary to be non-bootable
52+
Only seems to appear on some platforms, and we can find no use of it in our circumstances
53+
*/
5054
*(.eh_frame)
5155
}
5256
}

src/protected/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/protected/stage_3/Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,8 @@ name = "stage_3"
1111
crate-type = ["staticlib"]
1212

1313
[dependencies]
14-
shared = { path = "../../shared" }
14+
shared = { path = "../../shared" }
15+
16+
[dependencies.lazy_static]
17+
version = "1.0"
18+
features = ["spin_no_std"]
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use shared::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
2+
use crate::println;
3+
use lazy_static::lazy_static;
4+
5+
lazy_static! {
6+
static ref IDT: InterruptDescriptorTable = {
7+
let mut idt = InterruptDescriptorTable::new();
8+
9+
idt.divide_error.set_handler_fn(divide_handler);
10+
idt.breakpoint.set_handler_fn(breakpoint_handler);
11+
//idt.double_fault.set_handler_fn(double_fault_handler);
12+
13+
idt
14+
};
15+
}
16+
17+
18+
pub fn init_idt() {
19+
// Seems like we have to manually initialize it first for some reason, otherwise it crashes
20+
::lazy_static::initialize(&IDT);
21+
IDT.load();
22+
}
23+
24+
extern "x86-interrupt" fn divide_handler(
25+
stack_frame: &mut InterruptStackFrame)
26+
{
27+
println!("[Bootloader] [IDT] Divide Exception");
28+
}
29+
30+
extern "x86-interrupt" fn breakpoint_handler(
31+
stack_frame: &mut InterruptStackFrame)
32+
{
33+
println!("[Bootloader] [IDT] Breakpoint Hit");
34+
}
35+
36+
/*extern "x86-interrupt" fn double_fault_handler(
37+
stack_frame: &mut InterruptStackFrame, _error_code: u64) -> !
38+
{
39+
panic!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame);
40+
loop {};
41+
}*/

src/protected/stage_3/src/lib.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
#![no_std]
2+
#![feature(abi_x86_interrupt, asm)]
23

34
use shared::println;
45
use shared::instructions;
56

7+
mod interrupts;
68
mod panic;
79

810
#[no_mangle]
@@ -23,5 +25,13 @@ pub extern "C" fn third_stage() -> ! {
2325

2426
println!("[Bootloader] [32] Loaded TSS");
2527

26-
loop {}
28+
interrupts::init_idt();
29+
30+
println!("[Bootloader] [32] Loaded IDT");
31+
32+
unsafe { asm!("int 3") };
33+
34+
println!("[Bootloader] [32] It didn't crash!");
35+
36+
loop {};
2737
}

src/real/stage_2/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ lazy_static! {
1717
let mut tss = TaskStateSegment::new();
1818

1919
tss.privilege_stack_table[0].esp = linker_symbol!(_protected_mode_stack_end);
20+
tss.privilege_stack_table[0].ss = 2 * 8; // Kernel data segment is 2nd segment (null, code, data)
2021

2122
tss
2223
};

src/shared/src/structures/idt.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ pub struct InterruptDescriptorTable {
3434
impl InterruptDescriptorTable {
3535
/// Creates a new IDT filled with non-present entries.
3636
#[inline]
37-
pub const fn new() -> InterruptDescriptorTable {
38-
InterruptDescriptorTable {
37+
pub fn new() -> InterruptDescriptorTable {
38+
let idt = InterruptDescriptorTable {
3939
divide_error: Entry::missing(),
4040
debug: Entry::missing(),
4141
non_maskable_interrupt: Entry::missing(),
@@ -60,7 +60,9 @@ impl InterruptDescriptorTable {
6060
reserved_2: [Entry::missing(); 9],
6161
security_exception: Entry::missing(),
6262
reserved_3: Entry::missing(),
63-
}
63+
};
64+
65+
idt
6466
}
6567

6668
/// Loads the IDT in the CPU using the `lidt` command.
@@ -122,7 +124,7 @@ pub struct Entry<F> {
122124
impl<F> Entry<F> {
123125
/// Creates a non-present IDT entry (but sets the must-be-one bits).
124126
#[inline]
125-
pub const fn missing() -> Self {
127+
pub fn missing() -> Self {
126128
Entry {
127129
gdt_selector: 0,
128130
offset_low: 0,
@@ -140,7 +142,7 @@ impl<F> Entry<F> {
140142
/// The function returns a mutable reference to the entry's options that allows
141143
/// further customization.
142144
#[inline]
143-
fn set_handler_addr(&mut self, addr: u32) -> &mut EntryOptions {
145+
pub fn set_handler_addr(&mut self, addr: u32) -> &mut EntryOptions {
144146
self.offset_low = addr as u16;
145147
self.offset_high = (addr >> 16) as u16;
146148

@@ -196,7 +198,7 @@ impl EntryOptions {
196198
/// Set or reset the preset bit.
197199
#[inline]
198200
pub fn set_present(&mut self, present: bool) -> &mut Self {
199-
self.0.set_bit(15, present);
201+
self.0.set_bit(7, present);
200202
self
201203
}
202204
}
@@ -213,7 +215,7 @@ pub type DivergingHandlerFuncWithErrCode =
213215
extern "x86-interrupt" fn(&mut InterruptStackFrame, error_code: u64) -> !;
214216

215217
/// Represents the interrupt stack frame pushed by the CPU on interrupt or exception entry.
216-
#[derive(Clone)]
218+
#[derive(Clone, Debug)]
217219
#[repr(C)]
218220
pub struct InterruptStackFrame {
219221
pub eip: u32,

0 commit comments

Comments
 (0)