From 15d14ed67f7ae0392e6f14cd3953da5aa3fc4176 Mon Sep 17 00:00:00 2001 From: Yash Karandikar Date: Sun, 19 Sep 2021 13:29:37 -0500 Subject: [PATCH] Add support for translating virtual addresses to physical ones --- src/main.rs | 23 +++++++++++++++++++++++ src/memory.rs | 18 ++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 src/memory.rs diff --git a/src/main.rs b/src/main.rs index 530cf33..4dd62e9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,8 @@ mod gdt; mod interrupts; mod shell; mod vga_buffer; +mod memory; + use core::panic::PanicInfo; use bootloader::BootInfo; @@ -27,6 +29,7 @@ fn init() { #[no_mangle] pub extern "C" fn _start(boot_info: &'static BootInfo) { use crate::vga_buffer::{change_color, Color}; + use x86_64::{VirtAddr, structures::paging::Translate}; init(); print!("[ "); @@ -35,6 +38,26 @@ pub extern "C" fn _start(boot_info: &'static BootInfo) { change_color(Color::White, Color::Black); println!(" ] Initialized GDT and interrupts"); + let phys_mem_offset = VirtAddr::new(boot_info.physical_memory_offset); + let mapper = unsafe { memory::init(phys_mem_offset) }; + + let addresses = [ + // the identity-mapped vga buffer page + 0xb8000, + // some code page + 0x201008, + // some stack page + 0x0100_0020_1a10, + // virtual address mapped to physical address 0 + boot_info.physical_memory_offset, + ]; + + for &address in &addresses { + let virt = VirtAddr::new(address); + let phys = mapper.translate_addr(virt); + println!("{:?} -> {:?}", virt, phys); + } + print!("Welcome to "); change_color(Color::Blue, Color::Black); println!("KarxOS!"); diff --git a/src/memory.rs b/src/memory.rs new file mode 100644 index 0000000..7a86c6a --- /dev/null +++ b/src/memory.rs @@ -0,0 +1,18 @@ +use x86_64::{VirtAddr, structures::paging::{PageTable, OffsetPageTable}}; + +pub unsafe fn init(physical_memory_offset: VirtAddr) -> OffsetPageTable<'static> { + let level_4_table = active_level_4_table(physical_memory_offset); + OffsetPageTable::new(level_4_table, physical_memory_offset) +} + +unsafe fn active_level_4_table(physical_memory_offset: VirtAddr) -> &'static mut PageTable { + use x86_64::registers::control::Cr3; + + let (level_4_table_frame, _) = Cr3::read(); + + let phys = level_4_table_frame.start_address(); + let virt = physical_memory_offset + phys.as_u64(); + let page_table_ptr: *mut PageTable = virt.as_mut_ptr(); + + &mut *page_table_ptr +}