Setup paging

This commit is contained in:
Mathieu Strypsteen 2024-06-29 21:36:15 +02:00
parent 026b2df25a
commit 56e7e65d85
2 changed files with 67 additions and 1 deletions

View file

@ -7,6 +7,7 @@ use core::panic::PanicInfo;
use elf::load_kernel;
use log::{error, info};
use paging::setup_paging;
use static_alloc::Bump;
use uefi::{
entry,
@ -15,6 +16,7 @@ use uefi::{
};
mod elf;
mod paging;
#[global_allocator]
static A: Bump<[u8; 8 * 1024 * 1024]> = Bump::uninit();
@ -27,7 +29,8 @@ fn main(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
info!("Starting bootloader...");
uefi::helpers::init(&mut system_table).unwrap();
load_kernel(KERNEL, &system_table);
let _memory_map = system_table.exit_boot_services(MemoryType::LOADER_DATA).1;
let memory_map = system_table.exit_boot_services(MemoryType::LOADER_DATA).1;
setup_paging(&memory_map);
loop {}
}
#[panic_handler]

63
loader/src/paging.rs Normal file
View file

@ -0,0 +1,63 @@
use core::alloc::Layout;
use alloc::alloc::alloc_zeroed;
use uefi::table::boot::{MemoryMap, MemoryType};
use x86_64::{
registers::control::{Cr3, Cr3Flags},
structures::paging::{PageTable, PageTableFlags, PhysFrame},
PhysAddr,
};
fn get_table_entry(table: &mut PageTable, i: usize) -> &mut PageTable {
if table[i].is_unused() {
let layout = Layout::new::<PageTable>().align_to(0x1000).unwrap();
let new_table;
unsafe {
new_table = alloc_zeroed(layout);
}
let addr = PhysAddr::new(new_table as u64);
table[i].set_addr(addr, PageTableFlags::PRESENT | PageTableFlags::WRITABLE);
}
let ptr = table[i].addr().as_u64() as *mut PageTable;
unsafe {
return ptr.as_mut().unwrap();
}
}
fn map(pml4: &mut PageTable, mut virt: usize, phys: usize) {
virt /= 0x1000;
let table_i = virt % 512;
let directory_i = virt / 512 % 512;
let pdpt_i = virt / 512 / 512 % 512;
let pml4_i = virt / 512 / 512 / 512 % 512;
let pdpt = get_table_entry(pml4, pml4_i);
let directory = get_table_entry(pdpt, pdpt_i);
let table = get_table_entry(directory, directory_i);
let phys_addr = PhysAddr::new(phys as u64);
table[table_i].set_addr(phys_addr, PageTableFlags::PRESENT | PageTableFlags::WRITABLE)
}
pub fn setup_paging(memory_map: &MemoryMap) {
let pml4;
let layout = Layout::new::<PageTable>().align_to(0x1000).unwrap();
unsafe {
pml4 = (alloc_zeroed(layout) as *mut PageTable).as_mut().unwrap();
}
for i in memory_map.entries() {
if i.ty == MemoryType::LOADER_CODE
|| i.ty == MemoryType::LOADER_DATA
|| i.ty == MemoryType::RUNTIME_SERVICES_CODE
|| i.ty == MemoryType::RUNTIME_SERVICES_DATA
|| i.ty == MemoryType::BOOT_SERVICES_CODE
|| i.ty == MemoryType::BOOT_SERVICES_DATA
{
for j in 0..i.page_count {
let addr = i.phys_start + j * 0x1000;
map(pml4, addr as usize, addr as usize);
}
}
}
let pml4_addr = PhysAddr::new(pml4 as *const PageTable as u64);
let frame = PhysFrame::from_start_address(pml4_addr).unwrap();
unsafe {
Cr3::write(frame, Cr3Flags::empty());
}
}