File tree Expand file tree Collapse file tree 3 files changed +42
-0
lines changed Expand file tree Collapse file tree 3 files changed +42
-0
lines changed Original file line number Diff line number Diff line change @@ -25,6 +25,7 @@ features = ["unicode"]
25
25
default = []
26
26
vga_320x200 = []
27
27
recursive_level_4_table = []
28
+ map_physical_memory = []
28
29
29
30
[profile .dev ]
30
31
panic = " abort"
Original file line number Diff line number Diff line change 4
4
#[ cfg( feature = "recursive_level_4_table" ) ]
5
5
pub const RECURSIVE_LEVEL_4_TABLE_ADDR : u64 = 0o_177777_777_777_777_777_0000 ;
6
6
7
+ /// The offset into the virtual address space where the physical memory is mapped.
8
+ ///
9
+ /// Physical addresses can be converted to virtual addresses by adding this offset to them.
10
+ ///
11
+ /// The mapping of the physical memory allows to access arbitrary physical frames. Accessing
12
+ /// frames that are also mapped at other virtual addresses can easily break memory safety and
13
+ /// cause undefined behavior. Only frames reported as `USABLE` by the memory map in the `BootInfo`
14
+ /// can be safely accessed.
15
+ #[ cfg( feature = "map_physical_memory" ) ]
16
+ pub const PHYSICAL_MEMORY_OFFSET : u64 = 0o_177777_770_000_000_000_0000 ;
17
+
7
18
pub use bootinfo:: BootInfo ;
8
19
9
20
pub mod bootinfo;
Original file line number Diff line number Diff line change @@ -111,6 +111,13 @@ fn load_elf(
111
111
112
112
let mut memory_map = boot_info:: create_from ( memory_map_addr, memory_map_entry_count) ;
113
113
114
+ #[ cfg( feature = "map_physical_memory" ) ]
115
+ let max_phys_addr = memory_map
116
+ . iter ( )
117
+ . map ( |r| r. range . end_addr ( ) )
118
+ . max ( )
119
+ . expect ( "no physical memory regions found" ) ;
120
+
114
121
// Extract required information from the ELF file.
115
122
let mut preallocated_space = alloc_stack ! ( [ ProgramHeader64 ; 32 ] ) ;
116
123
let mut segments = FixedVec :: new ( & mut preallocated_space) ;
@@ -222,6 +229,29 @@ fn load_elf(
222
229
page
223
230
} ;
224
231
232
+ #[ cfg( feature = "map_physical_memory" ) ]
233
+ {
234
+ fn virt_for_phys ( phys : PhysAddr ) -> VirtAddr {
235
+ VirtAddr :: new ( phys. as_u64 ( ) + bootloader:: PHYSICAL_MEMORY_OFFSET )
236
+ }
237
+
238
+ let start_frame = PhysFrame :: < Size2MiB > :: containing_address ( PhysAddr :: new ( 0 ) ) ;
239
+ let end_frame = PhysFrame :: < Size2MiB > :: containing_address ( PhysAddr :: new ( max_phys_addr) ) ;
240
+ for frame in PhysFrame :: range_inclusive ( start_frame, end_frame) {
241
+ let page = Page :: containing_address ( virt_for_phys ( frame. start_address ( ) ) ) ;
242
+ let flags = PageTableFlags :: PRESENT | PageTableFlags :: WRITABLE ;
243
+ page_table:: map_page (
244
+ page,
245
+ frame,
246
+ flags,
247
+ & mut rec_page_table,
248
+ & mut frame_allocator,
249
+ )
250
+ . expect ( "Mapping of bootinfo page failed" )
251
+ . flush ( ) ;
252
+ }
253
+ }
254
+
225
255
// Construct boot info structure.
226
256
let mut boot_info = BootInfo :: new ( memory_map) ;
227
257
boot_info. memory_map . sort ( ) ;
You can’t perform that action at this time.
0 commit comments