1
0
Fork 0
forked from AbleOS/ableos
ableos/kernel/src/arch/x86_64/gdt.rs
2024-09-17 09:47:11 -05:00

59 lines
1.5 KiB
Rust

use {
spin::Lazy,
x86_64::{
structures::{
gdt::{Descriptor, GlobalDescriptorTable, SegmentSelector},
tss::TaskStateSegment,
},
VirtAddr,
},
};
pub const DOUBLE_FAULT_IX: u16 = 0;
const STACK_SIZE: usize = 5 * 1024;
const STACK_ALIGNMENT: usize = 1;
pub unsafe fn init() {
use x86_64::instructions::{
segmentation::{Segment, CS, SS},
tables::load_tss,
};
log::trace!("Initialising GDT");
GDT.0.load();
CS::set_reg(GDT.1.kcode);
SS::set_reg(GDT.1.kdata);
load_tss(GDT.1.tss);
}
struct Selectors {
kcode: SegmentSelector,
kdata: SegmentSelector,
tss: SegmentSelector,
}
static TSS: Lazy<TaskStateSegment> = Lazy::new(|| {
let mut tss = TaskStateSegment::new();
let stack_ptr = unsafe {
let layout = alloc::alloc::Layout::from_size_align(STACK_SIZE, STACK_ALIGNMENT)
.expect("Failed to create stack layout");
let stack = alloc::alloc::alloc(layout);
VirtAddr::from_ptr(stack) + STACK_SIZE as u64
};
tss.interrupt_stack_table[usize::from(DOUBLE_FAULT_IX)] = stack_ptr;
tss
});
static GDT: Lazy<(GlobalDescriptorTable, Selectors)> = Lazy::new(|| {
let mut gdt = GlobalDescriptorTable::new();
let sels = Selectors {
kcode: gdt.append(Descriptor::kernel_code_segment()),
kdata: gdt.append(Descriptor::kernel_data_segment()),
tss: gdt.append(Descriptor::tss_segment(&TSS)),
};
(gdt, sels)
});