kernel/arch/x86_64/cpu/tables/
gdt.rs1use super::tss::Tss;
8use crate::kinfo;
9use x86_64::instructions::tables::load_tss;
10use x86_64::registers::segmentation::{Segment, CS, DS, ES, SS};
11use x86_64::structures::gdt::{Descriptor, GlobalDescriptorTable, SegmentSelector};
12
13pub struct GdtSetupInfo {
14 pub kernel_code: SegmentSelector,
15 pub kernel_data: SegmentSelector,
16 pub user_code: SegmentSelector,
17 pub user_data: SegmentSelector,
18 pub tss_selector: SegmentSelector
19}
20
21pub fn gdt_init(tss: &'static Tss) -> (GlobalDescriptorTable, GdtSetupInfo) {
23 let mut gdt = GlobalDescriptorTable::new();
24
25 let kernel_code = gdt.append(Descriptor::kernel_code_segment());
26 let kernel_data = gdt.append(Descriptor::kernel_data_segment());
27 let user_data = gdt.append(Descriptor::user_data_segment());
28 let user_code = gdt.append(Descriptor::user_code_segment());
29 let tss_selector = gdt.append(Descriptor::tss_segment(unsafe { tss.tss() }));
30
31 (gdt, GdtSetupInfo {
32 kernel_code,
33 kernel_data,
34 user_data,
35 user_code,
36 tss_selector
37 })
38}
39
40pub unsafe fn gdt_load(gdt: &'static GlobalDescriptorTable, gdt_setup_info: &GdtSetupInfo) {
46 gdt.load();
47
48 unsafe {
49 CS::set_reg(gdt_setup_info.kernel_code);
50 SS::set_reg(gdt_setup_info.kernel_data);
51 DS::set_reg(gdt_setup_info.kernel_data);
52 ES::set_reg(gdt_setup_info.kernel_data);
53 load_tss(gdt_setup_info.tss_selector);
54 }
55
56 kinfo!("Initialized GDT");
57}