File tree Expand file tree Collapse file tree 2 files changed +45
-0
lines changed Expand file tree Collapse file tree 2 files changed +45
-0
lines changed 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;
24
24
#[ cfg( feature = "uefi_bin" ) ]
25
25
mod uefi;
26
26
27
+ mod gdt;
27
28
/// Provides a frame allocator based on a BIOS or UEFI memory map.
28
29
pub mod legacy_memory_region;
29
30
/// Provides a type to keep track of used entries in a level 4 page table.
@@ -170,6 +171,18 @@ where
170
171
}
171
172
}
172
173
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
+
173
186
// map framebuffer
174
187
let framebuffer_virt_addr = if CONFIG . map_framebuffer {
175
188
log:: info!( "Map framebuffer" ) ;
You can’t perform that action at this time.
0 commit comments