Skip to content

Memory manager #621

@ethindp

Description

@ethindp

So, I have a paging frame allocator, as the guide prompted (with my own modifications), but it looks similar. Here's what it is:

use x86_64::registers::control::*;
use bootloader::bootinfo::*;
use x86_64::{structures::paging::{FrameAllocator, MappedPageTable, Mapper, MapperAllSizes, Page, PageTable, PhysFrame, Size4KiB}, PhysAddr, VirtAddr};

pub unsafe fn init(physical_memory_offset: u64) -> impl MapperAllSizes {
let (level_4_table, _) = get_active_l4_table(physical_memory_offset);
let phys_to_virt = move |frame: PhysFrame| -> *mut PageTable {
let phys = frame.start_address().as_u64();
let virt = VirtAddr::new(phys + physical_memory_offset);
virt.as_mut_ptr()
    };
MappedPageTable::new(level_4_table, phys_to_virt)
}

pub unsafe fn get_active_l4_table(physical_memory_offset: u64)->(&'static mut PageTable, Cr3Flags) {
use x86_64::VirtAddr;
let (table_frame, flags) = Cr3::read();
let phys = table_frame.start_address();
let virt = VirtAddr::new(phys.as_u64() + physical_memory_offset);
let page_table_ptr: *mut PageTable = virt.as_mut_ptr();
(&mut *page_table_ptr, flags)
}

pub struct GlobalFrameAllocator {
memory_map: &'static MemoryMap,
next: usize,
}

impl GlobalFrameAllocator {
pub unsafe fn init (memory_map: &'static MemoryMap)->Self {
GlobalFrameAllocator {
memory_map,
next: 0,
}
}

fn iter_usable_frames(&self) -> impl Iterator<Item = PhysFrame> {
let regions = self.memory_map.iter();
let usable_regions = regions.filter(| region | region.region_type == MemoryRegionType::Usable);
let address_ranges = usable_regions.map(| region | region.range.start_addr() .. region.range.end_addr());
let frame_addresses = address_ranges.flat_map(| region | region.step_by(4096));
frame_addresses.map(| address | PhysFrame::containing_address(PhysAddr::new(address)))
}
}

unsafe impl FrameAllocator<Size4KiB> for GlobalFrameAllocator {
fn allocate_frame(&mut self)->Option<PhysFrame> {
let frame = self.iter_usable_frames().nth(self.next);
self.next += 1;
frame
}
}

How would I write a frame deallocator that works with this? I know how to allocate frames but how do I free them? Do I just use the x86_64 crate and clear the page, then set its unused flag?
Also, how would I go about implementing a heap/memory manager while I wait for the new post to come out? I can't find any memory manager that works with Rust that doesn't require some kind of host OS, and to do anything else (i.e. get keyboard input and store it in a buffer and so on) requires a memory manager or some way of allocating and freeing memory, something I don't have and am not sure how to code. Porting a memory manager would probably be a pain since (if I'm not mistaken) all the memory managers' source code out there requires an existnig host OS with frame freeing and all that, as well as a heap.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions