forked from AbleOS/ableos
65 lines
1.8 KiB
Rust
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
|
|
}
|
|
}
|