//! Writing an [OS] in Rust //! //! [os]: https://os.phil-opp.com #![no_std] #![no_main] #![feature(custom_test_frameworks)] #![test_runner(rustos::test_runner)] #![reexport_test_harness_main = "test_main"] #![feature(abi_x86_interrupt)] extern crate rustos; use core::panic::PanicInfo; use rustos::println; #[no_mangle] pub extern "C" fn _start() -> ! { println!("Welcome to the real world!"); init(); use x86_64::registers::control::Cr3; let (level_4_page_table, _) = Cr3::read(); println!("Level 4 page table at: {:?}", level_4_page_table); #[cfg(test)] test_main(); println!("It did not crash!!!"); rustos::hlt_loop(); } #[cfg(not(test))] #[panic_handler] fn panic(info: &PanicInfo) -> ! { println!("{}", info); rustos::hlt_loop(); } #[cfg(test)] #[panic_handler] fn panic(info: &PanicInfo) -> ! { rustos::test_panic_handler(info) } extern crate lazy_static; extern crate x86_64; use lazy_static::lazy_static; use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode}; fn init() { IDT.load(); } lazy_static! { static ref IDT: InterruptDescriptorTable = { let mut idt = InterruptDescriptorTable::new(); idt.page_fault.set_handler_fn(page_fault_handler); idt }; } extern "x86-interrupt" fn page_fault_handler( stack_frame: &mut 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); rustos::hlt_loop(); }