Starting to understand paging

This commit is contained in:
August 2025-09-26 19:50:45 -04:00
parent e0dab176b6
commit c8886495a2
Signed by: shibedrill
GPG Key ID: 5FE0CB25945EFAA2
5 changed files with 53 additions and 8 deletions

View File

@ -28,6 +28,12 @@ pub fn write_cr3(val: u64) {
unsafe { asm!("mov cr3, {0:r}", in(reg) val) } unsafe { asm!("mov cr3, {0:r}", in(reg) val) }
} }
pub fn read_cr4() -> u64 {
let cr4: u64;
unsafe { asm!("mov {0:r}, cr4", out(reg) cr4) }
cr4
}
pub fn interrupt_disable() { pub fn interrupt_disable() {
unsafe { unsafe {
asm!("cli"); asm!("cli");

View File

@ -1,7 +1,8 @@
// Copyright (c) 2025 shibedrill // Copyright (c) 2025 shibedrill
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
use crate::format; use crate::LogLevel;
use crate::{LOGGER, arch::asm::read_cr2, format, log_trace};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use x86_64::structures::idt::*; use x86_64::structures::idt::*;
@ -25,6 +26,12 @@ extern "x86-interrupt" fn double_fault(info: InterruptStackFrame, _: u64) -> ! {
#[allow(dead_code)] #[allow(dead_code)]
extern "x86-interrupt" fn page_fault(info: InterruptStackFrame, errcode: PageFaultErrorCode) { extern "x86-interrupt" fn page_fault(info: InterruptStackFrame, errcode: PageFaultErrorCode) {
let addr = read_cr2();
log_trace!(
"Fault: Page fault with address 0x{:x}, error code 0b{:b}",
addr,
errcode
);
if errcode.contains(PageFaultErrorCode::USER_MODE) { if errcode.contains(PageFaultErrorCode::USER_MODE) {
// Fault occurred in usermode. Non fatal. // Fault occurred in usermode. Non fatal.
todo!() todo!()
@ -35,13 +42,10 @@ extern "x86-interrupt" fn page_fault(info: InterruptStackFrame, errcode: PageFau
if errcode.contains(PageFaultErrorCode::PROTECTION_VIOLATION) if errcode.contains(PageFaultErrorCode::PROTECTION_VIOLATION)
| errcode.contains(PageFaultErrorCode::MALFORMED_TABLE) | errcode.contains(PageFaultErrorCode::MALFORMED_TABLE)
{ {
let addr = unsafe {
let a: usize;
core::arch::asm! {"mov {}, cr2", out(reg) a};
a
};
let info_formatted = format!("{info:#?}"); let info_formatted = format!("{info:#?}");
crate::interrupt::page_fault(addr, info_formatted) crate::interrupt::page_fault(addr, info_formatted)
} else {
todo!()
} }
} }
} }

View File

@ -65,7 +65,7 @@ impl PageMapLevel5Entry {
} }
pub struct PageMapLevel4 { pub struct PageMapLevel4 {
entries: [PageMapLevel4Entry; 512], pub entries: [PageMapLevel4Entry; 512],
} }
pub struct PageMapLevel4Entry { pub struct PageMapLevel4Entry {

View File

@ -25,6 +25,7 @@ use arch::x86_64::serial::Serialport;
use boot::{modules::*, params, *}; use boot::{modules::*, params, *};
use constants::*; use constants::*;
use intbits::Bits;
use limine::firmware_type::FirmwareType; use limine::firmware_type::FirmwareType;
use log::*; use log::*;
use memory::alloc::{format, string::*, vec}; use memory::alloc::{format, string::*, vec};
@ -35,11 +36,17 @@ use limine::memory_map::EntryType;
#[allow(unused_imports)] #[allow(unused_imports)]
use lzma_rs::lzma_decompress; use lzma_rs::lzma_decompress;
use crate::arch::paging::PageMapLevel4;
use crate::arch::x86_64::interrupts::IDT;
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
unsafe extern "C" fn main() -> ! { unsafe extern "C" fn main() -> ! {
// Assert supported bootloader version // Assert supported bootloader version
assert!(BASE_REVISION.is_supported()); assert!(BASE_REVISION.is_supported());
// Ensure IDT exists
IDT.load();
// Set up logging level from params // Set up logging level from params
// Nothing we can do here if this fails since no log subscribers are initialized yet // Nothing we can do here if this fails since no log subscribers are initialized yet
if let Some(level) = PARAMS.get("-loglevel") if let Some(level) = PARAMS.get("-loglevel")
@ -196,6 +203,30 @@ unsafe extern "C" fn main() -> ! {
log_info!("HHDM offset: 0x{:X}", HHDM_RESPONSE.offset()); log_info!("HHDM offset: 0x{:X}", HHDM_RESPONSE.offset());
log_info!("Paging: {}", arch::asm::read_cr0().bit(31));
log_info!("Protection: {}", arch::asm::read_cr0().bit(0));
log_info!(
"Physical Address Extensions: {}",
arch::asm::read_cr4().bit(5)
);
log_info!("Page Size Extensions: {}", arch::asm::read_cr4().bit(4));
log_info!(
"Paging mode: {}",
match memory::PAGING_REQUEST.get_response().unwrap().mode() {
limine::paging::Mode::FOUR_LEVEL => "Four-Level",
limine::paging::Mode::FIVE_LEVEL => "Five-Level",
_ => unreachable!(),
}
);
log_info!("CR3 Value: 0b{:064b}", arch::asm::read_cr3());
// Physical address of Page Map Level 4 Table
let pml4_ptr = ((arch::asm::read_cr3().bits(12..=63) << 12) + HHDM_RESPONSE.offset())
as *const PageMapLevel4;
log_info!("Page Map Level 4 Table Address: 0x{:x}", pml4_ptr.addr());
log_info!("Physical address of first entry: {}", unsafe {
(*pml4_ptr).entries[0].physical_address()
});
panic!("Bailing"); panic!("Bailing");
#[allow(unreachable_code)] #[allow(unreachable_code)]

View File

@ -3,7 +3,7 @@
use lazy_static::lazy_static; use lazy_static::lazy_static;
use limine::{ use limine::{
request::{ExecutableAddressRequest, HhdmRequest, MemoryMapRequest}, request::{ExecutableAddressRequest, HhdmRequest, MemoryMapRequest, PagingModeRequest},
response::HhdmResponse, response::HhdmResponse,
}; };
@ -11,6 +11,10 @@ use talc::*;
pub extern crate alloc; pub extern crate alloc;
#[used]
#[unsafe(link_section = ".requests")]
pub static PAGING_REQUEST: PagingModeRequest = limine::request::PagingModeRequest::new();
#[used] #[used]
#[unsafe(link_section = ".requests")] #[unsafe(link_section = ".requests")]
pub static ADDRESS_REQUEST: ExecutableAddressRequest = pub static ADDRESS_REQUEST: ExecutableAddressRequest =