Overview
Relevant source files
The memory_set crate provides building blocks for memory mapping management in Rust, offering data structures and operations similar to Unix system calls like mmap, munmap, and mprotect. This document covers the core architecture, components, and design patterns of the memory management system.
Note: This repository has been archived and the code has been moved to the axmm_crates repository as indicated in the README.
For detailed implementation specifics of individual components, see Implementation Details. For practical usage examples and patterns, see Usage and Examples.
Core Components and Structure
The memory_set crate is built around three primary components that work together to provide flexible memory mapping management:
Core Components Overview
flowchart TD
subgraph Storage["Storage"]
BT["BTreeMap<VirtAddr, MemoryArea>"]
end
subgraph subGraph1["Supporting Types"]
MR["MappingResult<T>"]
ME["MappingError"]
VA["VirtAddr"]
VAR["VirtAddrRange"]
end
subgraph subGraph0["Primary Types"]
MS["MemorySet<F,PT,B>"]
MA["MemoryArea<F,B>"]
MB["MappingBackend<F,PT> trait"]
end
MA --> MB
MA --> VAR
MR --> ME
MS --> BT
MS --> MA
MS --> MR
VAR --> VA
Sources: src/lib.rs(L12 - L13) src/lib.rs(L15 - L27) README.md(L18 - L41)
The system uses a generic type parameter approach where:
Frepresents memory flags (must implementCopy)PTrepresents the page table typeBrepresents the mapping backend implementation
System Architecture and Data Flow
The memory management system follows a layered architecture where high-level operations are decomposed into area management and low-level page table manipulation:
Memory Management Operation Flow
sequenceDiagram
participant Client as Client
participant MemorySet as MemorySet
participant BTreeMap as BTreeMap
participant MemoryArea as MemoryArea
participant MappingBackend as MappingBackend
Note over Client,MappingBackend: map() operation
Client ->> MemorySet: "map(area, page_table, unmap_overlap)"
MemorySet ->> BTreeMap: "Check for overlaps"
BTreeMap -->> MemorySet: "Overlapping areas found"
alt unmap_overlap = true
MemorySet ->> MemorySet: "Split/remove overlapping areas"
MemorySet ->> MappingBackend: "unmap existing regions"
else unmap_overlap = false
MemorySet -->> Client: "MappingError::AlreadyExists"
end
MemorySet ->> MemoryArea: "Get backend reference"
MemoryArea ->> MappingBackend: "map(start, size, flags, page_table)"
MappingBackend -->> MemorySet: "Success/failure"
MemorySet ->> BTreeMap: "Insert new area"
MemorySet -->> Client: "MappingResult"
Note over Client,MappingBackend: unmap() operation
Client ->> MemorySet: "unmap(start, size, page_table)"
MemorySet ->> BTreeMap: "Find affected areas"
loop For each affected area
alt Fully contained
MemorySet ->> BTreeMap: "Remove area"
else Partially overlapping
MemorySet ->> MemoryArea: "split(boundary_addr)"
MemoryArea -->> MemorySet: "New area created"
MemorySet ->> BTreeMap: "Update area collection"
end
MemorySet ->> MappingBackend: "unmap(start, size, page_table)"
end
MemorySet -->> Client: "MappingResult"
Sources: README.md(L36 - L48) src/lib.rs(L15 - L27)
Generic Type System Design
The crate achieves flexibility through careful use of Rust generics, allowing different implementations for flags, page tables, and backends while maintaining type safety:
Generic Type Relationships
flowchart TD
subgraph subGraph2["Mock Implementation Example"]
MF["MockFlags = u8"]
MPT["MockPageTable = [u8; MAX_ADDR]"]
MOCK["MockBackend"]
MS_CONCRETE["MemorySet<MockFlags, MockPageTable, MockBackend>"]
end
subgraph subGraph1["Core Generic Types"]
MS["MemorySet<F,PT,B>"]
MA["MemoryArea<F,B>"]
MBT["MappingBackend<F,PT>"]
end
subgraph subGraph0["Generic Parameters"]
F["F: Copy"]
PT["PT"]
B["B: MappingBackend<F,PT>"]
end
B --> MA
B --> MBT
B --> MS
F --> MA
F --> MBT
F --> MS
MF --> MS_CONCRETE
MOCK --> MBT
MOCK --> MS_CONCRETE
MPT --> MS_CONCRETE
PT --> MBT
PT --> MS
Sources: README.md(L24 - L34) README.md(L51 - L87) src/lib.rs(L12 - L13)
Error Handling Strategy
The crate uses a dedicated error type system to handle various failure scenarios in memory operations:
| Error Type | Description | Usage Context |
|---|---|---|
| MappingError::InvalidParam | Invalid parameters likeaddr,size,flags | Input validation |
| MappingError::AlreadyExists | Range overlaps with existing mapping | Overlap detection |
| MappingError::BadState | Backend page table in bad state | Backend operation failures |
The MappingResult<T> type alias provides a convenient Result type for all memory operations, defaulting to MappingResult<()> for operations that return no meaningful data on success.
Sources: src/lib.rs(L15 - L27)
Key Design Principles
- Generic Flexibility: The system uses three generic type parameters (
F,PT,B) to allow customization of flags, page tables, and backend implementations - Area-Based Management: Memory is managed in discrete areas that can be split, merged, and manipulated independently
- Backend Abstraction: The
MappingBackendtrait abstracts actual page table manipulation, enabling different implementation strategies - Overlap Handling: Sophisticated overlap detection and resolution with options for automatic unmapping of conflicting regions
- Type Safety: Rust's type system ensures memory safety and prevents common memory management errors
This overview establishes the foundation for understanding the detailed implementation covered in Implementation Details and the practical usage patterns demonstrated in Usage and Examples.
Sources: README.md(L9 - L14) src/lib.rs(L1 - L13)