Core Concepts
Relevant source files
This document explains the fundamental building blocks of the memory_set crate: MemorySet
, MemoryArea
, and MappingBackend
. These three types work together to provide a flexible abstraction for memory mapping operations similar to mmap
, munmap
, and mprotect
system calls.
For detailed implementation specifics, see Implementation Details. For practical usage examples, see Basic Usage Patterns.
The Three Core Types
The memory_set crate is built around three primary abstractions that work together to manage memory mappings:
flowchart TD subgraph subGraph0["Generic Parameters"] F["F: Memory Flags"] PT["PT: Page Table Type"] B["B: Backend Implementation"] end MemorySet["MemorySet"] MemoryArea["MemoryArea"] MappingBackend["MappingBackend"] BTreeMap["BTreeMap"] VirtAddrRange["VirtAddrRange"] PageTable["Page Table (PT)"] B --> MemorySet F --> MemorySet MappingBackend --> PageTable MemoryArea --> MappingBackend MemoryArea --> VirtAddrRange MemorySet --> BTreeMap MemorySet --> MappingBackend MemorySet --> MemoryArea PT --> MemorySet
Sources: README.md(L18 - L41)
MemorySet: Collection Management
MemorySet<F, PT, B>
serves as the primary interface for managing collections of memory areas. It maintains a sorted collection of non-overlapping memory regions and provides high-level operations for mapping, unmapping, and protecting memory.
Key Responsibilities
Operation | Description | Overlap Handling |
---|---|---|
map() | Add new memory area | Can split/remove existing areas |
unmap() | Remove memory regions | Automatically splits affected areas |
protect() | Change permissions | Updates flags for matching areas |
iter() | Enumerate areas | Provides ordered traversal |
The MemorySet
uses a BTreeMap<VirtAddr, MemoryArea>
internally to maintain areas sorted by their starting virtual address, enabling efficient overlap detection and range queries.
flowchart TD subgraph Operations["Operations"] VR1["VirtAddrRange: 0x1000-0x2000"] VR2["VirtAddrRange: 0x3000-0x4000"] VR3["VirtAddrRange: 0x5000-0x6000"] end subgraph subGraph1["Area Organization"] A1["va!(0x1000) -> MemoryArea"] A2["va!(0x3000) -> MemoryArea"] A3["va!(0x5000) -> MemoryArea"] end subgraph subGraph0["MemorySet Internal Structure"] MS["MemorySet"] BT["BTreeMap"] end A1 --> VR1 A2 --> VR2 A3 --> VR3 BT --> A1 BT --> A2 BT --> A3 MS --> BT
Sources: README.md(L34 - L48)
MemoryArea: Individual Memory Regions
MemoryArea<F, B>
represents a contiguous region of virtual memory with specific properties including address range, permissions flags, and an associated backend for page table operations.
Core Properties
Each MemoryArea
encapsulates:
- Virtual Address Range: Start address and size defining the memory region
- Flags: Memory permissions (read, write, execute, etc.)
- Backend: Implementation for actual page table manipulation
Area Lifecycle Operations
Sources: README.md(L37 - L38)
MappingBackend: Page Table Interface
The MappingBackend<F, PT>
trait defines the interface between memory areas and the underlying page table implementation. This abstraction allows the memory_set crate to work with different page table formats and memory management systems.
Required Operations
All backends must implement three core operations:
Method | Parameters | Purpose |
---|---|---|
map() | start: VirtAddr, size: usize, flags: F, pt: &mut PT | Establish new memory mappings |
unmap() | start: VirtAddr, size: usize, pt: &mut PT | Remove existing mappings |
protect() | start: VirtAddr, size: usize, new_flags: F, pt: &mut PT | Change mapping permissions |
Example Implementation Pattern
The mock backend demonstrates the interface pattern:
flowchart TD subgraph subGraph1["MappingBackend Trait"] map_method["map()"] unmap_method["unmap()"] protect_method["protect()"] end subgraph subGraph0["MockBackend Implementation"] MockBackend["MockBackend struct"] MockFlags["MockFlags = u8"] MockPageTable["MockPageTable = [u8; MAX_ADDR]"] end MockBackend --> map_method MockBackend --> protect_method MockBackend --> unmap_method MockFlags --> MockPageTable map_method --> MockPageTable protect_method --> MockPageTable unmap_method --> MockPageTable
Sources: README.md(L51 - L87)
Generic Type System
The memory_set crate uses a sophisticated generic type system to provide flexibility while maintaining type safety:
Type Parameters
- F: Memory flags type (must implement
Copy
) - PT: Page table type (can be any structure)
- B: Backend implementation (must implement
MappingBackend<F, PT>
)
This design allows the crate to work with different:
- Flag representations (bitfields, enums, integers)
- Page table formats (arrays, trees, hardware tables)
- Backend strategies (direct manipulation, system calls, simulation)
flowchart TD subgraph Usage["Usage"] MemorySet_Concrete["MemorySet"] end subgraph subGraph1["Concrete Example"] MockFlags_u8["MockFlags = u8"] MockPT_Array["MockPageTable = [u8; MAX_ADDR]"] MockBackend_Impl["MockBackend: MappingBackend"] end subgraph subGraph0["Generic Constraints"] F_Copy["F: Copy"] B_Backend["B: MappingBackend"] PT_Any["PT: Any type"] end B_Backend --> MockBackend_Impl F_Copy --> MockFlags_u8 MockBackend_Impl --> MemorySet_Concrete MockFlags_u8 --> MemorySet_Concrete MockPT_Array --> MemorySet_Concrete PT_Any --> MockPT_Array
Sources: README.md(L24 - L31)
Coordinated Operation Flow
The three core types work together in a coordinated fashion to handle memory management operations:
sequenceDiagram participant Client as Client participant MemorySet as MemorySet participant MemoryArea as MemoryArea participant MappingBackend as MappingBackend participant PageTable as PageTable Note over Client,PageTable: Memory Mapping Operation Client ->> MemorySet: "map(area, page_table, unmap_overlap)" MemorySet ->> MemorySet: "check for overlapping areas" alt overlaps exist and unmap_overlap=true MemorySet ->> MemoryArea: "split/shrink existing areas" MemorySet ->> MappingBackend: "unmap() overlapping regions" MappingBackend ->> PageTable: "clear page table entries" end MemorySet ->> MemoryArea: "get backend reference" MemoryArea ->> MappingBackend: "map(start, size, flags, pt)" MappingBackend ->> PageTable: "set page table entries" MappingBackend -->> MemorySet: "return success/failure" MemorySet ->> MemorySet: "insert area into BTreeMap" MemorySet -->> Client: "return MappingResult" Note over Client,PageTable: Memory Unmapping Operation Client ->> MemorySet: "unmap(start, size, page_table)" MemorySet ->> MemorySet: "find affected areas" loop for each affected area MemorySet ->> MemoryArea: "determine overlap relationship" alt area fully contained MemorySet ->> MemorySet: "remove area from BTreeMap" else area partially overlapping MemorySet ->> MemoryArea: "split area at boundaries" MemorySet ->> MemorySet: "update BTreeMap with new areas" end MemorySet ->> MappingBackend: "unmap(start, size, pt)" MappingBackend ->> PageTable: "clear page table entries" end MemorySet -->> Client: "return MappingResult"
Sources: README.md(L42 - L43)