mirror of
https://github.com/mii443/nel_os.git
synced 2025-12-03 03:08:25 +00:00
add physical memory map
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
12
src/lib.rs
12
src/lib.rs
@@ -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();
|
||||
|
||||
24
src/main.rs
24
src/main.rs
@@ -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
23
src/memory.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user