pub trait PhysicalMemoryAllocator {
unsafe fn allocate_frame(&mut self) -> Option<usize>;
unsafe fn deallocate_frame(&mut self, frame: usize);
}
pub trait VirtualMemoryManager {
unsafe fn map(&mut self, virtual_address: usize, physical_address: usize) -> Result<(), ()>;
unsafe fn unmap(&mut self, virtual_address: usize) -> Result<(), ()>;
}
#[cfg(test)]
mod tests {
use super::{PhysicalMemoryAllocator, VirtualMemoryManager};
use std::collections::BTreeMap;
struct TestAllocator {
next: usize,
}
impl TestAllocator {
fn new() -> Self {
Self { next: 1 }
}
}
impl PhysicalMemoryAllocator for TestAllocator {
unsafe fn allocate_frame(&mut self) -> Option<usize> {
let frame = self.next;
self.next = self.next.saturating_add(1);
Some(frame)
}
unsafe fn deallocate_frame(&mut self, _frame: usize) {
}
}
struct TestVirtualMemory {
mappings: BTreeMap<usize, usize>,
}
impl TestVirtualMemory {
fn new() -> Self {
Self {
mappings: BTreeMap::new(),
}
}
}
impl VirtualMemoryManager for TestVirtualMemory {
unsafe fn map(
&mut self,
virtual_address: usize,
physical_address: usize,
) -> Result<(), ()> {
self.mappings.insert(virtual_address, physical_address);
Ok(())
}
unsafe fn unmap(&mut self, virtual_address: usize) -> Result<(), ()> {
self.mappings.remove(&virtual_address);
Ok(())
}
}
#[test]
fn allocate_and_map_frame() {
let mut allocator = TestAllocator::new();
let mut vm = TestVirtualMemory::new();
let frame = unsafe { allocator.allocate_frame() }.expect("frame");
unsafe { vm.map(0x1000, frame).expect("map") };
}
}