wip
This commit is contained in:
@@ -13,7 +13,7 @@ pub const HEAP_START: usize = 0x4444_4444_0000;
|
||||
pub const HEAP_SIZE: usize = 128 * 1024;
|
||||
|
||||
pub const PAGE_SIZE: usize = 4096;
|
||||
pub const MAX_MEMORY: usize = 16 * 1024 * 1024 * 1024;
|
||||
pub const MAX_MEMORY: usize = 1024 * 1024 * 1024 * 1024; // 1 TiB
|
||||
pub const FRAME_COUNT: usize = MAX_MEMORY / PAGE_SIZE;
|
||||
pub const BITS_PER_ENTRY: usize = 8 * core::mem::size_of::<usize>();
|
||||
pub const ENTRY_COUNT: usize = FRAME_COUNT / BITS_PER_ENTRY;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use core::slice;
|
||||
|
||||
use nel_os_common::memory::{self, UsableMemory};
|
||||
use x86_64::{
|
||||
structures::paging::{FrameAllocator, PhysFrame, Size4KiB},
|
||||
@@ -7,31 +9,52 @@ use x86_64::{
|
||||
use crate::constant::{BITS_PER_ENTRY, ENTRY_COUNT, PAGE_SIZE};
|
||||
|
||||
pub struct BitmapMemoryTable {
|
||||
pub used_map: [usize; ENTRY_COUNT],
|
||||
pub used_map: &'static mut [usize],
|
||||
pub start: usize,
|
||||
pub end: usize,
|
||||
}
|
||||
|
||||
impl BitmapMemoryTable {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
used_map: [0; ENTRY_COUNT],
|
||||
pub fn init(usable_memory: &UsableMemory) -> Self {
|
||||
let mut max_addr = 0u64;
|
||||
for range in usable_memory.ranges() {
|
||||
max_addr = max_addr.max(range.end);
|
||||
}
|
||||
|
||||
let bitmap_size = ENTRY_COUNT * core::mem::size_of::<usize>();
|
||||
|
||||
let bitmap_addr = ((max_addr as usize).saturating_sub(bitmap_size)) & !(PAGE_SIZE - 1);
|
||||
|
||||
let used_map = unsafe {
|
||||
let ptr = bitmap_addr as *mut usize;
|
||||
slice::from_raw_parts_mut(ptr, ENTRY_COUNT)
|
||||
};
|
||||
|
||||
(0..ENTRY_COUNT).for_each(|i| {
|
||||
used_map[i] = 0;
|
||||
});
|
||||
|
||||
let mut table = Self {
|
||||
used_map,
|
||||
start: 0,
|
||||
end: usize::MAX,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub fn init(usable_memory: &UsableMemory) -> Self {
|
||||
let mut table = Self::default();
|
||||
for range in usable_memory.ranges() {
|
||||
table.set_range(range);
|
||||
}
|
||||
|
||||
let bitmap_start_frame = Self::addr_to_pfn(bitmap_addr);
|
||||
let bitmap_frames = bitmap_size.div_ceil(PAGE_SIZE);
|
||||
for i in 0..bitmap_frames {
|
||||
table.set_frame(bitmap_start_frame + i, false);
|
||||
}
|
||||
|
||||
for i in 0..ENTRY_COUNT {
|
||||
let index = ENTRY_COUNT - i - 1;
|
||||
if table.used_map[index] != 0 {
|
||||
let offset = 63 - table.used_map[index].leading_zeros();
|
||||
table.end = (index + 1) * BITS_PER_ENTRY + offset as usize;
|
||||
table.end = index * BITS_PER_ENTRY + (BITS_PER_ENTRY - offset as usize);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -91,12 +114,6 @@ impl BitmapMemoryTable {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for BitmapMemoryTable {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl FrameAllocator<Size4KiB> for BitmapMemoryTable {
|
||||
fn allocate_frame(&mut self) -> Option<PhysFrame<Size4KiB>> {
|
||||
if let Some(frame) = self.get_free_pfn() {
|
||||
|
||||
@@ -1,9 +1,36 @@
|
||||
use x86_64::{
|
||||
registers::control::Cr3,
|
||||
structures::paging::{page_table::FrameError, PageTable, PhysFrame},
|
||||
structures::paging::{
|
||||
page_table::FrameError, FrameAllocator, PageTable, PageTableFlags, PhysFrame, Size4KiB,
|
||||
},
|
||||
PhysAddr, VirtAddr,
|
||||
};
|
||||
|
||||
pub fn init_page_table(frame_allocator: &mut impl FrameAllocator<Size4KiB>) -> PhysFrame {
|
||||
let (lv4_frame, lv4_table) = new_page_table(frame_allocator);
|
||||
let (lv3_frame, lv3_table) = new_page_table(frame_allocator);
|
||||
|
||||
let base_flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE | PageTableFlags::GLOBAL;
|
||||
|
||||
unsafe {
|
||||
let lv4: &mut PageTable = &mut *lv4_table;
|
||||
lv4[0].set_frame(lv3_frame, base_flags);
|
||||
}
|
||||
|
||||
lv4_frame
|
||||
}
|
||||
|
||||
fn new_page_table(
|
||||
frame_allocator: &mut impl FrameAllocator<Size4KiB>,
|
||||
) -> (PhysFrame, *mut PageTable) {
|
||||
let frame = frame_allocator.allocate_frame().unwrap();
|
||||
|
||||
(
|
||||
frame,
|
||||
VirtAddr::new(frame.start_address().as_u64()).as_mut_ptr(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_active_level_4_table() -> &'static mut PageTable {
|
||||
let (level_4_table_frame, _) = Cr3::read();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user