ableos/kernel/src/arch/x86_64/memory.rs

65 lines
1.8 KiB
Rust

use limine::{LimineMemmapEntry, LimineMemoryMapEntryType};
use spin::{Mutex, Once};
use x86_64::{
structures::paging::{FrameAllocator, FrameDeallocator, OffsetPageTable, PhysFrame, Size4KiB},
PhysAddr, VirtAddr,
};
pub static PAGE_TABLE: Once<Mutex<OffsetPageTable>> = Once::new();
pub static FRAME_ALLOC: Once<Mutex<FrameAlloc>> = Once::new();
/// Initialise page table
pub unsafe fn init_pt(phys_base: VirtAddr) {
PAGE_TABLE.call_once(|| {
Mutex::new(OffsetPageTable::new(
&mut *((phys_base
+ x86_64::registers::control::Cr3::read()
.0
.start_address()
.as_u64())
.as_mut_ptr()),
phys_base,
))
});
}
/// Initialise page frame allocator
pub unsafe fn init_falloc(mmap: &'static [LimineMemmapEntry]) {
FRAME_ALLOC.call_once(|| Mutex::new(FrameAlloc::new(mmap)));
}
pub struct FrameAlloc {
mmap: &'static [LimineMemmapEntry],
next: usize,
}
impl FrameAlloc {
pub unsafe fn new(mmap: &'static [LimineMemmapEntry]) -> Self {
Self { mmap, next: 0 }
}
fn usable_frames(&self) -> impl Iterator<Item = PhysFrame> {
self.mmap
.iter()
.filter(|e| e.typ == LimineMemoryMapEntryType::Usable)
.map(|e| e.base..e.base + e.len)
.flat_map(|r| r.step_by(4096))
.map(PhysAddr::new)
.map(PhysFrame::containing_address)
}
}
unsafe impl FrameAllocator<Size4KiB> for FrameAlloc {
fn allocate_frame(&mut self) -> Option<PhysFrame<Size4KiB>> {
let f = self.usable_frames().nth(self.next);
self.next += 1;
f
}
}
impl FrameDeallocator<Size4KiB> for FrameAlloc {
unsafe fn deallocate_frame(&mut self, frame: PhysFrame<Size4KiB>) {
// TODO
}
}