kernel/arch/x86_64/tables/
gdt.rs1use crate::kinfo;
8use spin::Once;
9use x86_64::registers::segmentation::{Segment, CS, DS, ES, SS};
10use x86_64::instructions::tables::load_tss;
11use x86_64::structures::gdt::{GlobalDescriptorTable, Descriptor};
12
13pub struct Gdt {
16 table: Once<GlobalDescriptorTable>,
17}
18
19impl Gdt {
20 pub const fn new() -> Self {
22 Self { table: Once::new() }
23 }
24
25 pub fn init(&'static self, tss: &'static super::tss::Tss) {
30 let mut gdt = GlobalDescriptorTable::new();
31
32 let code = gdt.append(Descriptor::kernel_code_segment());
33 let data = gdt.append(Descriptor::kernel_data_segment());
34 let _ucode = gdt.append(Descriptor::user_code_segment());
35 let _udata = gdt.append(Descriptor::user_data_segment());
36 let tss_sel = gdt.append(Descriptor::tss_segment(tss.get()));
37
38 self.table.call_once(|| gdt);
39 self.table.get().unwrap().load();
40
41 unsafe {
44 CS::set_reg(code);
45 SS::set_reg(data);
46 DS::set_reg(data);
47 ES::set_reg(data);
48 load_tss(tss_sel);
49 }
50
51 kinfo!("Initialized GDT");
52 }
53}