Setup paging
This commit is contained in:
parent
026b2df25a
commit
56e7e65d85
2 changed files with 67 additions and 1 deletions
|
@ -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
63
loader/src/paging.rs
Normal 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());
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue