#![no_main] #![feature(compiler_builtins_lib)] #![feature(custom_test_frameworks)] #![feature(panic_info_message)] #![test_runner(crate::test_runner)] #![reexport_test_harness_main = "test_main"] #![no_std] extern crate compiler_builtins; mod io; use core::fmt::Write; use io::vga_text::OStream; use io::{qemu, serial, vga_text}; #[cfg(test)] pub fn test_runner(tests: &[&dyn Fn(&mut OStream)]) { let mut stdout = OStream::new(); stdout.clear(); write!(&mut stdout, "running {} tests\n", tests.len()).unwrap(); for test in tests { test(&mut stdout) } } #[no_mangle] pub extern "C" fn _start() -> ! { if cfg!(test) { #[cfg(test)] test_main(); qemu::exit_qemu(qemu::QemuExitCode::Success); } let mut stdout = OStream::new(); stdout.clear(); panic!("panic! at the disco"); core::iter::successors(Some(0), |n| Some(n + 1)) .for_each(|n| write!(&mut stdout, "hello world {}!", n).unwrap()); loop {} } #[panic_handler] #[no_mangle] pub extern "C" fn panic_handler(info: &core::panic::PanicInfo) -> ! { let mut stderr = OStream::new(); stderr.set_state(vga_text::CharState::from_colors( vga_text::Color::LightRed, vga_text::Color::Red, )); stderr.clear(); stderr.print(b"uff-os"); stderr.set_row(10); stderr.set_state(vga_text::CharState::from_colors( vga_text::Color::White, vga_text::Color::Red, )); stderr.print_centered(b""); stderr.set_row(14); stderr.set_state(vga_text::CharState::from_colors( vga_text::Color::Cyan, vga_text::Color::Red, )); stderr.set_centered(true); write!(&mut stderr, "{:?}", info.message() .unwrap_or(&format_args!("no panic information obtainable"))); //loop{} stderr.set_centered(false); if cfg!(test) { write!(serial::SerialStream::new(), "Testing failed\n").unwrap(); qemu::exit_qemu(qemu::QemuExitCode::Failed); } loop {} }