feat: paging + cleanup across memory management and other stuff

This commit is contained in:
Zoe
2026-08-20 06:29:39 -05:00
parent 35d18495ec
commit af24a5a783
9 changed files with 815 additions and 158 deletions
+59 -21
View File
@@ -8,7 +8,11 @@ mod boot;
mod debug;
mod memory;
use crate::debug::serial;
use crate::{
arch::paging,
debug::serial,
memory::{PhysicalAddr, VirtualAddr},
};
#[unsafe(no_mangle)]
pub extern "C" fn _start() -> ! {
@@ -16,38 +20,72 @@ pub extern "C" fn _start() -> ! {
arch::init();
let boot_info = boot::load_boot_info().unwrap();
let direct_map = memory::DirectMap::new(boot_info.hhdm_offset);
let mut allocator = memory::FrameAllocator::new(
let mut allocator = memory::FrameAllocator::new(boot_info.memory_regions(), direct_map)
.expect("failed to create frame allocator");
let mut page_table = paging::AddressSpace::new(
direct_map,
boot_info.memory_regions(),
memory::DirectMap::new(boot_info.hhdm_offset),
boot_info.kernel_address,
&mut allocator,
)
.expect("failed to create frame allocator");
.expect("failed to create page table");
let initial = allocator.free_frames();
// safety: trust me bro
unsafe { page_table.activate() };
let first = allocator.alloc().unwrap();
let second = allocator.alloc().unwrap();
let third = allocator.alloc().unwrap();
let frame = allocator.alloc().unwrap();
assert_ne!(first, second);
assert_ne!(second, third);
assert_eq!(allocator.free_frames(), initial - 3);
let direct_mapped = direct_map.translate(frame.start_address()).unwrap();
let translated = page_table.translate(direct_mapped).unwrap();
println!("{:?}", translated);
let new_virtual = VirtualAddr::new(0x8000_0000);
assert!(page_table.translate(new_virtual).is_none());
let page = paging::Page::from_start_address(new_virtual).unwrap();
page_table
.map(
page,
frame,
paging::PagePermissions::KERNEL_DATA,
&mut allocator,
)
.unwrap();
assert_eq!(
page_table.translate(new_virtual),
Some(frame.start_address())
);
assert_eq!(
page_table.translate(VirtualAddr::new(new_virtual.as_usize() + 123)),
Some(PhysicalAddr::new(frame.start_address().as_usize() + 123))
);
// write to the page and read it back via HHDM
unsafe {
allocator.dealloc(second);
allocator.dealloc(first);
allocator.dealloc(third);
core::ptr::write_bytes(new_virtual.as_mut_ptr::<u8>(), 0xFF, 0x1000);
}
assert_eq!(allocator.free_frames(), initial);
let slice = unsafe { core::slice::from_raw_parts(direct_mapped.as_ptr::<u8>(), 0x1000) };
let a = allocator.alloc().unwrap();
let b = allocator.alloc().unwrap();
let c = allocator.alloc().unwrap();
assert!(slice.iter().all(|&byte| byte == 0xFF));
assert_ne!(a, b);
assert_ne!(b, c);
assert_ne!(a, c);
println!("{:#X}", slice[0]);
let unmapped_frame = page_table.unmap(page, &mut allocator).unwrap();
assert_eq!(unmapped_frame, frame);
unsafe { allocator.dealloc(unmapped_frame) };
assert!(page_table.translate(new_virtual).is_none());
hcf();
}