feat: paging + cleanup across memory management and other stuff
This commit is contained in:
+59
-21
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user