feat: add pmm, add vmm, add allocator, create memory management foundation
This commit is contained in:
89
kernel/src/mem/allocator.rs
Normal file
89
kernel/src/mem/allocator.rs
Normal file
@@ -0,0 +1,89 @@
|
||||
use core::alloc::{GlobalAlloc, Layout};
|
||||
use core::ptr::null_mut;
|
||||
use core::sync::atomic::{AtomicBool, Ordering};
|
||||
use core::ops::{Deref, DerefMut};
|
||||
|
||||
pub struct Locked<A> {
|
||||
inner: core::cell::UnsafeCell<A>,
|
||||
lock: AtomicBool,
|
||||
}
|
||||
|
||||
pub struct LockedGuard<'a, A> {
|
||||
lock: &'a AtomicBool,
|
||||
data: &'a mut A,
|
||||
}
|
||||
|
||||
unsafe impl<A> Sync for Locked<A> {}
|
||||
|
||||
impl<A> Locked<A> {
|
||||
pub const fn new(inner: A) -> Self {
|
||||
Self {
|
||||
inner: core::cell::UnsafeCell::new(inner),
|
||||
lock: AtomicBool::new(false),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lock(&self) -> LockedGuard<'_, A> {
|
||||
while self.lock.compare_exchange_weak(false, true, Ordering::Acquire, Ordering::Relaxed).is_err() {
|
||||
core::hint::spin_loop();
|
||||
}
|
||||
LockedGuard {
|
||||
lock: &self.lock,
|
||||
data: unsafe { &mut *self.inner.get() },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A> Drop for LockedGuard<'_, A> {
|
||||
fn drop(&mut self) {
|
||||
self.lock.store(false, Ordering::Release);
|
||||
}
|
||||
}
|
||||
|
||||
impl<A> Deref for LockedGuard<'_, A> {
|
||||
type Target = A;
|
||||
fn deref(&self) -> &Self::Target { self.data }
|
||||
}
|
||||
|
||||
impl<A> DerefMut for LockedGuard<'_, A> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target { self.data }
|
||||
}
|
||||
|
||||
pub struct BumpAllocator {
|
||||
start: usize,
|
||||
end: usize,
|
||||
next: usize,
|
||||
}
|
||||
|
||||
impl BumpAllocator {
|
||||
pub const fn new() -> Self {
|
||||
Self { start: 0, end: 0, next: 0 }
|
||||
}
|
||||
|
||||
pub fn init(&mut self, start: usize, size: usize) {
|
||||
self.start = start;
|
||||
self.next = start;
|
||||
self.end = start + size;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl GlobalAlloc for Locked<BumpAllocator> {
|
||||
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
||||
let mut bump = self.lock();
|
||||
|
||||
let alloc_start = (bump.next + layout.align() - 1) & !(layout.align() - 1);
|
||||
let alloc_end = alloc_start + layout.size();
|
||||
|
||||
if alloc_end > bump.end {
|
||||
null_mut()
|
||||
} else {
|
||||
bump.next = alloc_end;
|
||||
alloc_start as *mut u8
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
|
||||
}
|
||||
|
||||
#[global_allocator]
|
||||
pub static ALLOCATOR: Locked<BumpAllocator> = Locked::new(BumpAllocator::new());
|
||||
Reference in New Issue
Block a user