add physical memory map

This commit is contained in:
mii443
2025-04-14 17:00:40 +09:00
parent 3b20f48161
commit 3d976b0de4
6 changed files with 83 additions and 6 deletions

View File

@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2018"
[dependencies]
bootloader = "0.9"
bootloader = { version = "0.9", features = ["map_physical_memory"] }
volatile = "0.2.6"
spin = "0.5.2"
x86_64 = "0.14.2"
@@ -17,6 +17,10 @@ version = "1.0"
features = ["spin_no_std"]
[package.metadata.bootimage]
run-args = [
"-serial",
"stdio"
]
test-args = [
"-device",
"isa-debug-exit,iobase=0xf4,iosize=0x04",

View File

@@ -13,6 +13,8 @@ lazy_static! {
.set_handler_fn(double_fault_handler)
.set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX);
}
idt.page_fault.set_handler_fn(page_fault_handler);
idt[InterruptIndex::Timer.as_usize()].set_handler_fn(timer_interrupt_handler);
idt[InterruptIndex::Keyboard.as_usize()].set_handler_fn(keyboard_interrupt_handler);
@@ -35,6 +37,22 @@ extern "x86-interrupt" fn double_fault_handler(
panic!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame);
}
use crate::hlt_loop;
use x86_64::structures::idt::PageFaultErrorCode;
extern "x86-interrupt" fn page_fault_handler(
stack_frame: InterruptStackFrame,
error_code: PageFaultErrorCode,
) {
use x86_64::registers::control::Cr2;
println!("EXCEPTION: PAGE FAULT");
println!("Accessed Address: {:?}", Cr2::read());
println!("Error Code: {:?}", error_code);
println!("{:#?}", stack_frame);
hlt_loop();
}
pub const PIC_1_OFFSET: u8 = 32;
pub const PIC_2_OFFSET: u8 = PIC_1_OFFSET + 8;

View File

@@ -7,11 +7,17 @@
pub mod gdt;
pub mod interrupts;
pub mod memory;
pub mod serial;
pub mod vga_buffer;
use core::panic::PanicInfo;
#[cfg(test)]
use bootloader::entry_point;
#[cfg(test)]
use bootloader::BootInfo;
pub trait Testable {
fn run(&self) -> ();
}
@@ -43,8 +49,10 @@ pub fn test_panic_handler(info: &PanicInfo) -> ! {
}
#[cfg(test)]
#[unsafe(no_mangle)]
pub extern "C" fn _start() -> ! {
entry_point!(test_kernel_main);
#[cfg(test)]
fn test_kernel_main(_boot_info: &'static BootInfo) -> ! {
init();
test_main();
hlt_loop();

View File

@@ -4,8 +4,10 @@
#![test_runner(nel_os::test_runner)]
#![reexport_test_harness_main = "test_main"]
use bootloader::{entry_point, BootInfo};
use core::panic::PanicInfo;
use nel_os::println;
use nel_os::{memory, println};
use x86_64::{structures::paging::Translate, VirtAddr};
#[cfg(not(test))]
#[panic_handler]
@@ -20,12 +22,28 @@ fn panic(info: &PanicInfo) -> ! {
nel_os::test_panic_handler(info)
}
#[no_mangle]
pub extern "C" fn _start() -> ! {
entry_point!(kernel_main);
fn kernel_main(boot_info: &'static BootInfo) -> ! {
println!("NelOS v{}", env!("CARGO_PKG_VERSION"));
nel_os::init();
let phys_mem_offset = VirtAddr::new(boot_info.physical_memory_offset);
let mapper = unsafe { memory::init(phys_mem_offset) };
let addresses = [
0xb8000,
0x201008,
0x0100_0020_1a10,
boot_info.physical_memory_offset,
];
for &address in &addresses {
let virt = VirtAddr::new(address);
let phys = mapper.translate_addr(virt);
println!("{:?} -> {:?}", virt, phys);
}
#[cfg(test)]
test_main();

23
src/memory.rs Normal file
View File

@@ -0,0 +1,23 @@
use x86_64::{
structures::paging::{OffsetPageTable, PageTable},
VirtAddr,
};
unsafe fn active_level_4_table(physical_memory_offset: VirtAddr) -> &'static mut PageTable {
use x86_64::registers::control::Cr3;
let (level_4_table_frame, _) = Cr3::read();
let phys = level_4_table_frame.start_address();
let virt = physical_memory_offset + phys.as_u64();
let page_table_ptr: *mut PageTable = virt.as_mut_ptr();
unsafe { &mut *page_table_ptr }
}
pub unsafe fn init(physical_memory_offset: VirtAddr) -> OffsetPageTable<'static> {
unsafe {
let level_4_table = active_level_4_table(physical_memory_offset);
OffsetPageTable::new(level_4_table, physical_memory_offset)
}
}

View File

@@ -4,6 +4,8 @@ use lazy_static::lazy_static;
use spin::Mutex;
use volatile::Volatile;
use crate::serial::SERIAL1;
lazy_static! {
pub static ref WRITER: Mutex<Writer> = Mutex::new(Writer {
column_position: 0,
@@ -30,6 +32,10 @@ pub fn _print(args: fmt::Arguments) {
interrupts::without_interrupts(|| {
WRITER.lock().write_fmt(args).unwrap();
SERIAL1
.lock()
.write_fmt(args)
.expect("Printing to serial failed");
});
}