memory_set

Data structures and operations for managing memory mappings.
It is useful to implement mmap
, munmap
and mprotect
.
Examples
use memory_addr::{va, va_range, VirtAddr};
use memory_set::{MappingBackend, MemoryArea, MemorySet};
const MAX_ADDR: usize = 0x10000;
type MockFlags = u8;
type MockPageTable = [MockFlags; MAX_ADDR];
#[derive(Clone)]
struct MockBackend;
let mut pt = [0; MAX_ADDR];
let mut memory_set = MemorySet::<MockBackend>::new();
memory_set.map(
MemoryArea::new(va!(0x1000), 0x4000, 1, MockBackend),
&mut pt,
false,
).unwrap();
memory_set.unmap(va!(0x2000), 0x2000, &mut pt).unwrap();
let areas = memory_set.iter().collect::<Vec<_>>();
assert_eq!(areas.len(), 2);
assert_eq!(areas[0].va_range(), va_range!(0x1000..0x2000));
assert_eq!(areas[1].va_range(), va_range!(0x4000..0x5000));
impl MappingBackend for MockBackend {
type Addr = VirtAddr;
type Flags = MockFlags;
type PageTable = MockPageTable;
fn map(&self, start: VirtAddr, size: usize, flags: MockFlags, pt: &mut MockPageTable) -> bool {
for entry in pt.iter_mut().skip(start.as_usize()).take(size) {
if *entry != 0 {
return false;
}
*entry = flags;
}
true
}
fn unmap(&self, start: VirtAddr, size: usize, pt: &mut MockPageTable) -> bool {
for entry in pt.iter_mut().skip(start.as_usize()).take(size) {
if *entry == 0 {
return false;
}
*entry = 0;
}
true
}
fn protect(
&self,
start: VirtAddr,
size: usize,
new_flags: MockFlags,
pt: &mut MockPageTable,
) -> bool {
for entry in pt.iter_mut().skip(start.as_usize()).take(size) {
if *entry == 0 {
return false;
}
*entry = new_flags;
}
true
}
}