ruvix-physmem
Physical memory allocator for the RuVix Cognition Kernel (ADR-087).
Overview
This crate provides a buddy allocator for physical page frame allocation. The buddy system uses power-of-two block sizes (4KB to 2MB) for efficient allocation and deallocation with minimal external fragmentation.
Features
- Buddy Allocation: Power-of-two block sizes with automatic splitting and coalescing
- No External Dependencies: Pure
no_stdimplementation - Type-Safe Addresses:
PhysAddrnewtype wrapper for physical addresses - Comprehensive Statistics: Track allocations, frees, splits, and coalesces
- Page Frame Abstraction:
PageFrametype for safer memory management
Block Sizes
| Order | Pages | Size |
|---|---|---|
| 0 | 1 | 4KB |
| 1 | 2 | 8KB |
| 2 | 4 | 16KB |
| 3 | 8 | 32KB |
| 4 | 16 | 64KB |
| 5 | 32 | 128KB |
| 6 | 64 | 256KB |
| 7 | 128 | 512KB |
| 8 | 256 | 1MB |
| 9 | 512 | 2MB |
Usage
Basic Allocation
use ;
// Create allocator for 16MB of memory starting at physical address 0x1000_0000
let mut allocator = new;
// Allocate a single page (4KB)
let addr = allocator.alloc_pages.expect;
assert!;
// Allocate 4 contiguous pages (16KB)
let addr4 = allocator.alloc_pages.expect;
// Free the allocations
allocator.dealloc_pages;
allocator.dealloc_pages;
Using PageFrame
use ;
let mut allocator = new;
// Allocate and get a PageFrame
if let Some = allocator.alloc_frame
Error Handling
use ;
let mut allocator = new;
// Try to allocate with explicit error handling
match allocator.try_alloc_pages
Statistics
use ;
let mut allocator = new;
// Perform some allocations
let a1 = allocator.alloc_pages.unwrap;
let a2 = allocator.alloc_pages.unwrap;
allocator.dealloc_pages;
// Check statistics
let stats = allocator.stats;
println!;
println!;
println!;
println!;
println!;
// Per-order statistics
let order_stats = allocator.order_stats;
for in order_stats.iter.enumerate
Physical Address Operations
use PhysAddr;
let addr = new;
// Check alignment
assert!;
assert_eq!;
assert_eq!;
// Page frame number
assert_eq!;
assert_eq!;
// Address arithmetic
let next = addr.add_pages;
assert_eq!;
// From page frame number
let addr2 = from_pfn;
assert_eq!; // 1MB
Page Order Calculations
use ;
// Calculate order from page count
assert_eq!;
assert_eq!; // rounds up to 4 pages
assert_eq!;
// Calculate pages from order
assert_eq!;
assert_eq!;
assert_eq!;
// Calculate bytes from order
assert_eq!; // 4KB
assert_eq!; // 2MB
// Using PageOrder type
let order = from_pages.unwrap;
assert_eq!; // rounds up: 5 pages -> order 3 (8 pages)
assert_eq!;
assert_eq!;
Deferred Initialization
use ;
// Create uninitialized allocator (useful for static allocation)
let mut allocator = uninit;
// Later, initialize with actual memory
allocator.init.unwrap;
// Now ready for use
let addr = allocator.alloc_pages.unwrap;
Features
std: Enable standard library support (enablesstd::error::Errorimpl)alloc: Enable alloc crate supportstats: Enable detailed statistics collectiondebug-alloc: Enable debug assertions for allocation tracking
Implementation Details
Buddy System Algorithm
The buddy allocator works by:
- Initialization: Memory is organized into the largest possible power-of-two blocks
- Allocation:
- Find the smallest free block that fits the request
- Split larger blocks as needed (creating "buddies")
- Deallocation:
- Mark the block as free
- Coalesce with its buddy if the buddy is also free
- Repeat coalescing until no more merges are possible
Buddy Address Calculation
For a block at address A with order n:
- Block size:
2^n * PAGE_SIZEbytes - Buddy address:
A XOR (2^n * PAGE_SIZE)
This XOR property ensures that buddies always have the correct alignment for the next higher order.
Performance Characteristics
| Operation | Time Complexity |
|---|---|
| alloc_pages | O(MAX_ORDER) |
| free_pages | O(MAX_ORDER) |
| Split | O(1) per split |
| Coalesce | O(1) per merge |
Space overhead: O(n) where n is the number of free blocks (stored in free lists).
Integration with RuVix
This allocator is designed to be used by the RuVix kernel for managing physical memory. It integrates with:
ruvix-types: UsesKernelErrorfor error propagationruvix-region: Provides backing memory for virtual regionsruvix-nucleus: Called from the kernel's memory management syscalls
License
MIT OR Apache-2.0