File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ use x86_64:: {
2+ instructions:: segmentation,
3+ structures:: {
4+ gdt:: { Descriptor , GlobalDescriptorTable } ,
5+ paging:: PhysFrame ,
6+ } ,
7+ VirtAddr ,
8+ } ;
9+
10+ pub fn create_and_load ( frame : PhysFrame ) {
11+ let phys_addr = frame. start_address ( ) ;
12+ log:: info!( "Creating GDT at {:?}" , phys_addr) ;
13+ let virt_addr = VirtAddr :: new ( phys_addr. as_u64 ( ) ) ; // utilize identity mapping
14+
15+ let ptr: * mut GlobalDescriptorTable = virt_addr. as_mut_ptr ( ) ;
16+
17+ let mut gdt = GlobalDescriptorTable :: new ( ) ;
18+ let code_selector = gdt. add_entry ( Descriptor :: kernel_code_segment ( ) ) ;
19+ let data_selector = gdt. add_entry ( Descriptor :: kernel_data_segment ( ) ) ;
20+ let gdt = unsafe {
21+ ptr. write ( gdt) ;
22+ & * ptr
23+ } ;
24+
25+ gdt. load ( ) ;
26+ unsafe {
27+ segmentation:: set_cs ( code_selector) ;
28+ segmentation:: load_ds ( data_selector) ;
29+ segmentation:: load_es ( data_selector) ;
30+ segmentation:: load_ss ( data_selector) ;
31+ }
32+ }
Original file line number Diff line number Diff line change @@ -24,6 +24,7 @@ pub mod bios;
2424#[ cfg( feature = "uefi_bin" ) ]
2525mod uefi;
2626
27+ mod gdt;
2728/// Provides a frame allocator based on a BIOS or UEFI memory map.
2829pub mod legacy_memory_region;
2930/// Provides a type to keep track of used entries in a level 4 page table.
@@ -170,6 +171,18 @@ where
170171 }
171172 }
172173
174+ // create, load, and identity-map GDT (required for working `iretq`)
175+ let gdt_frame = frame_allocator
176+ . allocate_frame ( )
177+ . expect ( "failed to allocate GDT frame" ) ;
178+ gdt:: create_and_load ( gdt_frame) ;
179+ match unsafe {
180+ kernel_page_table. identity_map ( gdt_frame, PageTableFlags :: PRESENT , frame_allocator)
181+ } {
182+ Ok ( tlb) => tlb. flush ( ) ,
183+ Err ( err) => panic ! ( "failed to identity map frame {:?}: {:?}" , gdt_frame, err) ,
184+ }
185+
173186 // map framebuffer
174187 let framebuffer_virt_addr = if CONFIG . map_framebuffer {
175188 log:: info!( "Map framebuffer" ) ;
You can’t perform that action at this time.
0 commit comments