From 8ae6c49138f82a8a224f27b45ef2f65dc3f6d7a3 Mon Sep 17 00:00:00 2001 From: mii443 Date: Mon, 14 Apr 2025 17:19:51 +0900 Subject: [PATCH] add frame allocator --- src/memory.rs | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/memory.rs b/src/memory.rs index 20a5ee3..64e7549 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -1,8 +1,39 @@ +use bootloader::bootinfo::{MemoryMap, MemoryRegionType}; use x86_64::{ - structures::paging::{OffsetPageTable, PageTable}, - VirtAddr, + structures::paging::{FrameAllocator, OffsetPageTable, PageTable, PhysFrame, Size4KiB}, + PhysAddr, VirtAddr, }; +pub struct BootInfoFrameAllocator { + memory_map: &'static MemoryMap, + next: usize, +} + +impl BootInfoFrameAllocator { + pub unsafe fn init(memory_map: &'static MemoryMap) -> Self { + Self { + 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 + } +} + unsafe fn active_level_4_table(physical_memory_offset: VirtAddr) -> &'static mut PageTable { use x86_64::registers::control::Cr3;