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:
F
represents memory flags (must implementCopy
)PT
represents the page table typeB
represents 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
MappingBackend
trait 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)