Add support for mapping new pages

This commit is contained in:
Yash Karandikar 2021-09-19 13:49:59 -05:00
parent 15d14ed67f
commit e51b3a53e7
Signed by: karx
GPG key ID: A794DA2529474BA5
2 changed files with 32 additions and 22 deletions

View file

@ -29,7 +29,6 @@ fn init() {
#[no_mangle]
pub extern "C" fn _start(boot_info: &'static BootInfo) {
use crate::vga_buffer::{change_color, Color};
use x86_64::{VirtAddr, structures::paging::Translate};
init();
print!("[ ");
@ -38,26 +37,6 @@ pub extern "C" fn _start(boot_info: &'static BootInfo) {
change_color(Color::White, Color::Black);
println!(" ] Initialized GDT and interrupts");
let phys_mem_offset = VirtAddr::new(boot_info.physical_memory_offset);
let mapper = unsafe { memory::init(phys_mem_offset) };
let addresses = [
// the identity-mapped vga buffer page
0xb8000,
// some code page
0x201008,
// some stack page
0x0100_0020_1a10,
// virtual address mapped to physical address 0
boot_info.physical_memory_offset,
];
for &address in &addresses {
let virt = VirtAddr::new(address);
let phys = mapper.translate_addr(virt);
println!("{:?} -> {:?}", virt, phys);
}
print!("Welcome to ");
change_color(Color::Blue, Color::Black);
println!("KarxOS!");

View file

@ -1,4 +1,5 @@
use x86_64::{VirtAddr, structures::paging::{PageTable, OffsetPageTable}};
use x86_64::{PhysAddr, VirtAddr, structures::paging::{FrameAllocator, Mapper, OffsetPageTable, Page, PageTable, PhysFrame, Size4KiB}};
use bootloader::bootinfo::{MemoryMap, MemoryRegionType};
pub unsafe fn init(physical_memory_offset: VirtAddr) -> OffsetPageTable<'static> {
let level_4_table = active_level_4_table(physical_memory_offset);
@ -16,3 +17,33 @@ unsafe fn active_level_4_table(physical_memory_offset: VirtAddr) -> &'static mut
&mut *page_table_ptr
}
pub struct BootInfoFrameAllocator {
memory_map: &'static MemoryMap,
next: usize,
}
impl BootInfoFrameAllocator {
pub unsafe fn init(memory_map: &'static MemoryMap) -> Self {
BootInfoFrameAllocator {
memory_map,
next: 0
}
}
fn usable_frames(&self) -> impl Iterator<Item = PhysFrame> {
let regions = self.memory_map.iter();
let usable_regions = regions.filter(|r| r.region_type == MemoryRegionType::Usable);
let addr_ranges = usable_regions.map(|r| r.range.start_addr()..r.range.end_addr());
let frame_addresses = addr_ranges.flat_map(|r| r.step_by(4096));
frame_addresses.map(|addr| PhysFrame::containing_address(PhysAddr::new(addr)))
}
}
unsafe impl FrameAllocator<Size4KiB> for BootInfoFrameAllocator {
fn allocate_frame(&mut self) -> Option<PhysFrame> {
let frame = self.usable_frames().nth(self.next);
self.next += 1;
frame
}
}