-
-
Save Lucky4Luuk/d04957d8470030d015a2aedd2c487af2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use x86_64::VirtAddr; | |
use x86_64::structures::tss::TaskStateSegment; | |
use x86_64::structures::gdt::{GlobalDescriptorTable, Descriptor, SegmentSelector}; | |
use lazy_static::lazy_static; | |
pub const DOUBLE_FAULT_IST_INDEX: u16 = 0; | |
pub const KERNEL_STACK_START: u64 = 0xFFFFFF8000000000; | |
pub const KERNEL_STACK_SIZE: u64 = 512; | |
lazy_static! { | |
static ref TSS: TaskStateSegment = { | |
let mut tss = TaskStateSegment::new(); | |
tss.privilege_stack_table[0] = VirtAddr::new(KERNEL_STACK_START + KERNEL_STACK_SIZE * 4096); | |
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 | |
}; | |
} | |
lazy_static! { | |
static ref GDT: (GlobalDescriptorTable, Selectors) = { | |
let mut gdt = GlobalDescriptorTable::new(); | |
let kernel_code_selector = gdt.add_entry(Descriptor::kernel_code_segment()); | |
let kernel_data_selector = gdt.add_entry(Descriptor::kernel_data_segment()); | |
let user_code_selector = gdt.add_entry(Descriptor::user_code_segment()); | |
let user_data_selector = gdt.add_entry(Descriptor::user_data_segment()); | |
let tss_selector = gdt.add_entry(Descriptor::tss_segment(&TSS)); | |
(gdt, Selectors { | |
kernel_code_selector: kernel_code_selector, | |
kernel_data_selector: kernel_data_selector, | |
tss_selector: tss_selector, | |
user_code_selector: user_code_selector, | |
user_data_selector: user_data_selector, | |
}) | |
}; | |
} | |
struct Selectors { | |
kernel_code_selector: SegmentSelector, | |
kernel_data_selector: SegmentSelector, | |
tss_selector: SegmentSelector, | |
user_code_selector: SegmentSelector, | |
user_data_selector: SegmentSelector, | |
} | |
pub fn init() { | |
use x86_64::instructions::segmentation::{set_cs, load_ss}; | |
use x86_64::instructions::tables::load_tss; | |
// trace!("RPL: {:?}", GDT.1.user_code_selector.rpl()); //Prints "3", which is correct | |
GDT.0.load(); | |
unsafe { | |
set_cs(GDT.1.kernel_code_selector); | |
load_ss(GDT.1.kernel_data_selector); | |
//These 2 lines are needed for ring 3 to work, but currently put the kernel in a bootloop | |
// set_cs(GDT.1.user_code_selector); | |
// load_ss(GDT.1.user_data_selector); | |
load_tss(GDT.1.tss_selector); | |
} | |
//It doesn't even get to this point if the `set_cs(user_code_sel)` line is uncommented | |
// panic!("Test"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment