feat: implement capability-based memory management foundation
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
use crate::mem::address::{PhysAddr};
|
||||
use crate::mem::address::PhysAddr;
|
||||
use crate::mem::allocator::Locked;
|
||||
|
||||
pub const PAGE_SIZE: u64 = 4096;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct BitmapPMM {
|
||||
bitmap: &'static mut [u8],
|
||||
total_pages: usize,
|
||||
@@ -10,7 +10,7 @@ pub struct BitmapPMM {
|
||||
last_idx: usize,
|
||||
}
|
||||
|
||||
static mut PMM: Option<BitmapPMM> = None;
|
||||
pub static PMM: Locked<Option<BitmapPMM>> = Locked::new(None);
|
||||
|
||||
impl BitmapPMM {
|
||||
#[allow(dead_code)]
|
||||
@@ -33,7 +33,6 @@ impl BitmapPMM {
|
||||
.expect("PMM: Insufficient memory for bitmap");
|
||||
|
||||
let bitmap_virt_ptr = (bitmap_phys_addr + hhdm_offset) as *mut u8;
|
||||
// Оборачиваем небезопасные операции
|
||||
let bitmap_slice = unsafe { core::slice::from_raw_parts_mut(bitmap_virt_ptr, bitmap_size) };
|
||||
bitmap_slice.fill(0xFF);
|
||||
|
||||
@@ -58,9 +57,7 @@ impl BitmapPMM {
|
||||
|
||||
pmm.lock_frame(PhysAddr(0));
|
||||
|
||||
unsafe {
|
||||
core::ptr::write(core::ptr::addr_of_mut!(PMM), Some(pmm));
|
||||
}
|
||||
*PMM.lock() = Some(pmm);
|
||||
}
|
||||
|
||||
pub fn free_frame(&mut self, phys_addr: PhysAddr) {
|
||||
@@ -87,42 +84,48 @@ impl BitmapPMM {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn alloc_frame(&mut self) -> Option<PhysAddr> {
|
||||
for i in self.last_idx..self.total_pages {
|
||||
let byte_idx = i / 8;
|
||||
if self.bitmap[byte_idx] == 0xFF { continue; }
|
||||
|
||||
let bit_idx = i % 8;
|
||||
if (self.bitmap[byte_idx] & (1 << bit_idx)) == 0 {
|
||||
let addr = PhysAddr(i as u64 * PAGE_SIZE);
|
||||
self.lock_frame(addr);
|
||||
self.last_idx = i;
|
||||
return Some(addr);
|
||||
pub fn alloc_frame(&mut self) -> Option<PhysAddr> {
|
||||
let start_byte = self.last_idx / 8;
|
||||
for i in start_byte..(self.bitmap.len()) {
|
||||
if self.bitmap[i] != 0xFF {
|
||||
for bit in 0..8 {
|
||||
let idx = i * 8 + bit;
|
||||
if idx >= self.total_pages { return None; }
|
||||
|
||||
let addr = PhysAddr(idx as u64 * PAGE_SIZE);
|
||||
if !self.is_locked(addr) {
|
||||
self.lock_frame(addr);
|
||||
self.last_idx = idx;
|
||||
return Some(addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub unsafe fn get_pmm_unchecked() -> &'static BitmapPMM {
|
||||
let pmm_ptr = core::ptr::addr_of!(PMM);
|
||||
unsafe { (*pmm_ptr).as_ref().expect("PMM: Not initialized") }
|
||||
}
|
||||
|
||||
pub fn alloc_page() -> Option<PhysAddr> {
|
||||
unsafe {
|
||||
let pmm_ptr = core::ptr::addr_of_mut!(PMM);
|
||||
(*pmm_ptr).as_mut()?.alloc_frame()
|
||||
#[inline]
|
||||
fn is_locked(&self, addr: PhysAddr) -> bool {
|
||||
let idx = (addr.0 / PAGE_SIZE) as usize;
|
||||
(self.bitmap[idx / 8] & (1 << (idx % 8))) != 0
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn free_page(addr: PhysAddr) {
|
||||
unsafe {
|
||||
let pmm_ptr = core::ptr::addr_of_mut!(PMM);
|
||||
if let Some(pmm) = (*pmm_ptr).as_mut() {
|
||||
pmm.free_frame(addr);
|
||||
}
|
||||
|
||||
pub fn alloc_frame() -> Option<PhysAddr> {
|
||||
PMM.lock().as_mut()?.alloc_frame()
|
||||
}
|
||||
|
||||
pub fn free_frame(addr: PhysAddr) {
|
||||
if let Some(pmm) = PMM.lock().as_mut() {
|
||||
pmm.free_frame(addr);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_stats() -> (usize, usize) {
|
||||
if let Some(pmm) = PMM.lock().as_ref() {
|
||||
(pmm.used_pages(), pmm.total_pages())
|
||||
} else {
|
||||
(0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user