Skip to content

Commit 21a3e6d

Browse files
committed
Add a feature to map the complete physical memory into the virtual address space
1 parent dd0c143 commit 21a3e6d

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ features = ["unicode"]
2525
default = []
2626
vga_320x200 = []
2727
recursive_level_4_table = []
28+
map_physical_memory = []
2829

2930
[profile.dev]
3031
panic = "abort"

src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@
44
#[cfg(feature = "recursive_level_4_table")]
55
pub const RECURSIVE_LEVEL_4_TABLE_ADDR: u64 = 0o_177777_777_777_777_777_0000;
66

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+
718
pub use bootinfo::BootInfo;
819

920
pub mod bootinfo;

src/main.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,13 @@ fn load_elf(
111111

112112
let mut memory_map = boot_info::create_from(memory_map_addr, memory_map_entry_count);
113113

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+
114121
// Extract required information from the ELF file.
115122
let mut preallocated_space = alloc_stack!([ProgramHeader64; 32]);
116123
let mut segments = FixedVec::new(&mut preallocated_space);
@@ -222,6 +229,29 @@ fn load_elf(
222229
page
223230
};
224231

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+
225255
// Construct boot info structure.
226256
let mut boot_info = BootInfo::new(memory_map);
227257
boot_info.memory_map.sort();

0 commit comments

Comments
 (0)