diff --git a/src/main.rs b/src/main.rs index 4dd62e9..34148cf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,7 +29,6 @@ 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!("[ "); @@ -38,26 +37,6 @@ 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 index 7a86c6a..d173d37 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -1,4 +1,5 @@ -use x86_64::{VirtAddr, structures::paging::{PageTable, OffsetPageTable}}; +use x86_64::{PhysAddr, VirtAddr, structures::paging::{FrameAllocator, Mapper, OffsetPageTable, Page, PageTable, PhysFrame, Size4KiB}}; +use bootloader::bootinfo::{MemoryMap, MemoryRegionType}; pub unsafe fn init(physical_memory_offset: VirtAddr) -> OffsetPageTable<'static> { let level_4_table = active_level_4_table(physical_memory_offset); @@ -16,3 +17,33 @@ unsafe fn active_level_4_table(physical_memory_offset: VirtAddr) -> &'static mut &mut *page_table_ptr } + +pub struct BootInfoFrameAllocator { + memory_map: &'static MemoryMap, + next: usize, +} + +impl BootInfoFrameAllocator { + pub unsafe fn init(memory_map: &'static MemoryMap) -> Self { + BootInfoFrameAllocator { + memory_map, + next: 0 + } + } + + fn usable_frames(&self) -> impl Iterator { + let regions = self.memory_map.iter(); + let usable_regions = regions.filter(|r| r.region_type == MemoryRegionType::Usable); + let addr_ranges = usable_regions.map(|r| r.range.start_addr()..r.range.end_addr()); + let frame_addresses = addr_ranges.flat_map(|r| r.step_by(4096)); + frame_addresses.map(|addr| PhysFrame::containing_address(PhysAddr::new(addr))) + } +} + +unsafe impl FrameAllocator for BootInfoFrameAllocator { + fn allocate_frame(&mut self) -> Option { + let frame = self.usable_frames().nth(self.next); + self.next += 1; + frame + } +}