mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-16 06:17:49 +00:00
Merge pull request #595 from phil-opp/redesign-frame-allocator
Avoid generic impl trait parameters in BootInfoFrameAllocator
This commit is contained in:
@@ -11,14 +11,14 @@ use core::panic::PanicInfo;
|
||||
entry_point!(kernel_main);
|
||||
|
||||
fn kernel_main(boot_info: &'static BootInfo) -> ! {
|
||||
use blog_os::memory;
|
||||
use blog_os::memory::{self, BootInfoFrameAllocator};
|
||||
use x86_64::{structures::paging::Page, VirtAddr};
|
||||
|
||||
println!("Hello World{}", "!");
|
||||
blog_os::init();
|
||||
|
||||
let mut mapper = unsafe { memory::init(boot_info.physical_memory_offset) };
|
||||
let mut frame_allocator = memory::init_frame_allocator(&boot_info.memory_map);
|
||||
let mut frame_allocator = BootInfoFrameAllocator::init(&boot_info.memory_map);
|
||||
|
||||
// map a previously unmapped page
|
||||
let page = Page::containing_address(VirtAddr::new(0xdeadbeaf000));
|
||||
|
||||
@@ -23,24 +23,6 @@ pub unsafe fn init(physical_memory_offset: u64) -> impl MapperAllSizes {
|
||||
MappedPageTable::new(level_4_table, phys_to_virt)
|
||||
}
|
||||
|
||||
/// Create a FrameAllocator from the passed memory map
|
||||
pub fn init_frame_allocator(
|
||||
memory_map: &'static MemoryMap,
|
||||
) -> BootInfoFrameAllocator<impl Iterator<Item = PhysFrame>> {
|
||||
// get usable regions from memory map
|
||||
let regions = memory_map
|
||||
.iter()
|
||||
.filter(|r| r.region_type == MemoryRegionType::Usable);
|
||||
// map each region to its address range
|
||||
let addr_ranges = regions.map(|r| r.range.start_addr()..r.range.end_addr());
|
||||
// transform to an iterator of frame start addresses
|
||||
let frame_addresses = addr_ranges.flat_map(|r| r.step_by(4096));
|
||||
// create `PhysFrame` types from the start addresses
|
||||
let frames = frame_addresses.map(|addr| PhysFrame::containing_address(PhysAddr::new(addr)));
|
||||
|
||||
BootInfoFrameAllocator { frames }
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the active level 4 table.
|
||||
///
|
||||
/// This function is unsafe because the caller must guarantee that the
|
||||
@@ -83,18 +65,39 @@ impl FrameAllocator<Size4KiB> for EmptyFrameAllocator {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BootInfoFrameAllocator<I>
|
||||
where
|
||||
I: Iterator<Item = PhysFrame>,
|
||||
{
|
||||
frames: I,
|
||||
/// A FrameAllocator that returns usable frames from the bootloader's memory map.
|
||||
pub struct BootInfoFrameAllocator {
|
||||
memory_map: &'static MemoryMap,
|
||||
next: usize,
|
||||
}
|
||||
|
||||
impl<I> FrameAllocator<Size4KiB> for BootInfoFrameAllocator<I>
|
||||
where
|
||||
I: Iterator<Item = PhysFrame>,
|
||||
{
|
||||
fn allocate_frame(&mut self) -> Option<PhysFrame> {
|
||||
self.frames.next()
|
||||
impl BootInfoFrameAllocator {
|
||||
/// Create a FrameAllocator from the passed memory map.
|
||||
pub fn init(memory_map: &'static MemoryMap) -> Self {
|
||||
BootInfoFrameAllocator {
|
||||
memory_map,
|
||||
next: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an iterator over the usable frames specified in the memory map.
|
||||
fn usable_frames(&self) -> impl Iterator<Item = PhysFrame> {
|
||||
// get usable regions from memory map
|
||||
let regions = self.memory_map.iter();
|
||||
let usable_regions = regions.filter(|r| r.region_type == MemoryRegionType::Usable);
|
||||
// map each region to its address range
|
||||
let addr_ranges = usable_regions.map(|r| r.range.start_addr()..r.range.end_addr());
|
||||
// transform to an iterator of frame start addresses
|
||||
let frame_addresses = addr_ranges.flat_map(|r| r.step_by(4096));
|
||||
// create `PhysFrame` types from the start addresses
|
||||
frame_addresses.map(|addr| PhysFrame::containing_address(PhysAddr::new(addr)))
|
||||
}
|
||||
}
|
||||
|
||||
impl FrameAllocator<Size4KiB> for BootInfoFrameAllocator {
|
||||
fn allocate_frame(&mut self) -> Option<PhysFrame> {
|
||||
let frame = self.usable_frames().nth(self.next);
|
||||
self.next += 1;
|
||||
frame
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user