Allocator — A no_std Physical & Virtual Memory Allocator in Rust This project provides a fully‑featured memory allocator designed for no_std environments. It includes:
a physical allocator based on a bitmap, a virtual memory layer using multiple segments (IdEntry), automatic fragmentation handling, a quarantine system preventing memory leaks, safe Read/Write operations over virtual addresses, and a robust best‑effort allocation strategy suitable for embedded and kernel contexts.
This allocator is intended for kernels, bare‑metal OS projects, bootloaders, embedded systems, or any environment without the standard library.
✨ Key Features 🧱 Physical Allocation (Bitmap System)
Physical memory divided into F frames. Allocation of contiguous frame ranges when possible. Automatic hole detection (first‑fit). Efficient forward offset to avoid rescanning the bitmap. Proper physical deallocation with offset recalculation. Memory cleanup (unlock) after freeing.
🧊 Fragmentation Handling If a contiguous block of frames cannot be allocated:
the allocator performs split allocations using a halving strategy (size / 2), collects multiple smaller physical fragments, and merges them virtually into a single contiguous virtual region.
This is similar to a lightweight buddy allocator.
🗂 Virtual Memory Layer Each allocation returns a VirtualAddr: RustVirtualAddr { id: process_id, pos: virtual_offset_in_bytes }Afficher plus de lignes
Virtual memory is always contiguous, even when physical memory is fragmented. A virtual region may consist of one or more IdEntry segments. Segments for the same process never overlap. The allocator prevents forged VirtualAddr values via PID matching and segment bounds checking.
🛡 Quarantine System (Anti‑Leak Mechanism) During deallocation:
If physical memory cannot be freed cleanly → the block is stored in a quarantine buffer, → preventing “dangling virtual entries” or leaks.
A purge() operation:
frees all quarantined blocks, wipes the corresponding physical memory, clears the quarantine table and counter.
📖 Read / Write API The allocator provides safe, virtualized access to memory: Rustread::(&self, pid, addr) -> IoStatuswrite::(&mut self, pid, addr, &[u8; L]) -> IoStatusAfficher plus de lignes Features:
automatic resolution of virtual → physical addressing, strict boundary validation, no cross‑page read/write (by design), PID‑based access control, detailed error reporting via:
ReadOk([u8; L]) WriteOk OutOfRangeLow OutOfRangeHigh NoSegment
🧪 Comprehensive Test Suite (15+ tests) Tests cover:
bitmap allocation and hole detection, virtual allocation fragmentation, full deallocation cycles, quarantine behavior and purge, Read/Write correctness, offset handling, PID access restrictions, error cases (OutOfRangeHigh, NoSegment), corruption injection (bitmap tampering).
🧬 Design Philosophy This allocator follows a best‑effort model, ideal for no_std:
No rollback on partial allocations. Partial allocation allowed when enabled. Quarantine handles inconsistent physical state. API remains deterministic, simple, panic‑free.
The goal is a clean, robust, low‑level allocator suitable for experimental OS/kernels.
🚀 Minimal Example Rustlet mut alloc = Allocator::<4096, 64, 64>::new().unwrap();// Allocate 256 virtual bytes for process 8let (addr, status) = alloc.alloc(8, 256);// Write into virtual memorylet data = *b"Hello World!";alloc.write::<12>(8, addr.unwrap(), &data);// Read it backlet res = alloc.read::<12>(8, addr.unwrap());assert_eq!(res, IoStatus::ReadOk(data));// Deallocatealloc.desalloc(8);Afficher plus de lignes
🧩 Internal Structures
bytes: physical memory buffer (N bytes) bitmap: allocation state of each frame ids: virtual segments (IdEntry) PhysFrame: (start_frame, frame_count) VirtualAddr: process + virtual offset quarantine: pending inconsistent physical blocks IoStatus: results of memory IO
The entire design is deterministic, allocation‑free, and does not require the Rust standard library.