From 7a2c54645dff0dcfff847a6154b61ae7a8c7cd45 Mon Sep 17 00:00:00 2001 From: Mathieu Strypsteen Date: Sat, 16 Nov 2024 11:34:24 +0100 Subject: [PATCH] Print to screen on panic --- kernel/src/main.rs | 45 +++++++++++++++++++++++++++------------ kernel/src/sys/display.rs | 8 +++++++ loader/src/main.rs | 14 +++++++----- 3 files changed, 48 insertions(+), 19 deletions(-) diff --git a/kernel/src/main.rs b/kernel/src/main.rs index a873a83..51e2571 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -13,6 +13,7 @@ use core::{ use acpi::AcpiTables; use acpica_rs::{AcpiEnableSubsystem, AcpiInitializeObjects, AcpiInitializeSubsystem, AcpiInitializeTables, AcpiLoadTables, ACPI_FULL_INITIALIZATION}; +use alloc::format; use buddy_system_allocator::LockedHeap; use cpu::{gdt::setup_gdt, idt::setup_idt, paging::setup_paging}; use kernel_common::{ @@ -23,7 +24,17 @@ use kernel_common::{ }; use log::{error, info}; use spin::Mutex; -use sys::{acpica_osl::AE_OK, display::setup_display, early_acpi::EarlyACPIHandler, hpet::setup_hpet, lapic::setup_lapic_timer, madt::parse_madt, pic::disable_pic, task::setup_multitasking}; +use sys::{ + acpica_osl::AE_OK, + display::{display_print, setup_display}, + early_acpi::EarlyACPIHandler, + hpet::setup_hpet, + lapic::setup_lapic_timer, + madt::parse_madt, + pic::disable_pic, + sync::LOCKS_HELD, + task::setup_multitasking, +}; mod cpu; mod misc; @@ -54,22 +65,23 @@ extern "C" fn early_main(temp_loader_struct: *const LoaderStruct) -> ! { unsafe { ALLOC.lock().init(KERNEL_HEAP_START as usize, KERNEL_HEAP_INITIAL_SIZE); } - let mut loader_struct = LOADER_STRUCT.lock(); - unsafe { - temp_loader_struct.copy_to(&mut *loader_struct, 1); + { + let mut loader_struct = LOADER_STRUCT.lock(); + unsafe { + temp_loader_struct.copy_to(&mut *loader_struct, 1); + } + assert_eq!(loader_struct.magic, LOADER_STRUCT_MAGIC); + init_logger(loader_struct.vm != 0); + info!("Starting kernel..."); + setup_gdt(); + setup_idt(); + setup_paging(&loader_struct, loader_struct.phys_kernel_start, loader_struct.phys_heap_start); + RSDP_ADDRESS.store(loader_struct.rsdp_address, Ordering::SeqCst); } - assert_eq!(loader_struct.magic, LOADER_STRUCT_MAGIC); - init_logger(loader_struct.vm != 0); - info!("Starting kernel..."); - setup_gdt(); - setup_idt(); - setup_paging(&loader_struct, loader_struct.phys_kernel_start, loader_struct.phys_heap_start); - setup_display(loader_struct.framebuffer); disable_pic(); - RSDP_ADDRESS.store(loader_struct.rsdp_address, Ordering::SeqCst); let early_acpi_tables; unsafe { - early_acpi_tables = AcpiTables::from_rsdp(EarlyACPIHandler {}, loader_struct.rsdp_address as usize).unwrap(); + early_acpi_tables = AcpiTables::from_rsdp(EarlyACPIHandler {}, RSDP_ADDRESS.load(Ordering::SeqCst) as usize).unwrap(); } parse_madt(&early_acpi_tables); setup_hpet(&early_acpi_tables); @@ -78,6 +90,8 @@ extern "C" fn early_main(temp_loader_struct: *const LoaderStruct) -> ! { } fn main() { info!("Starting main kernel task"); + let loader_struct = LOADER_STRUCT.lock(); + setup_display(loader_struct.framebuffer); let mut status = unsafe { AcpiInitializeSubsystem() }; assert_eq!(status, AE_OK); status = unsafe { AcpiInitializeTables(null_mut(), 0, 0) }; @@ -91,8 +105,11 @@ fn main() { } #[panic_handler] fn panic(info: &PanicInfo) -> ! { - error!("{}", info); cli(); + LOCKS_HELD.fetch_add(1, Ordering::SeqCst); + error!("{}", info); + let str = format!("PANIC at {}: {}\n", info.location().unwrap(), info.message().as_str().unwrap()); + display_print(&str); loop { hlt(); } diff --git a/kernel/src/sys/display.rs b/kernel/src/sys/display.rs index 9017aa6..2b8fed2 100644 --- a/kernel/src/sys/display.rs +++ b/kernel/src/sys/display.rs @@ -15,7 +15,10 @@ use spin::Mutex; use crate::{cpu::paging::map_physical, misc::draw_target::FramebufferTarget}; +use super::sync::Spinlock; + static FRAMEBUFFER: Mutex> = Mutex::new(None); +static FRAMEBUFFER_LOCK: Spinlock = Spinlock::new(); static FRAMEBUFFER_ADDR: AtomicPtr = AtomicPtr::new(null_mut()); static WIDTH: AtomicUsize = AtomicUsize::new(0); static HEIGHT: AtomicUsize = AtomicUsize::new(0); @@ -49,6 +52,10 @@ fn copy_to_fb() { } } pub fn display_print(str: &str) { + if FRAMEBUFFER_ADDR.load(Ordering::SeqCst) == null_mut() { + return; + } + FRAMEBUFFER_LOCK.lock(); let mut current_x = CURRENT_X.load(Ordering::SeqCst); let mut current_y = CURRENT_Y.load(Ordering::SeqCst); let width = WIDTH.load(Ordering::SeqCst); @@ -73,6 +80,7 @@ pub fn display_print(str: &str) { CURRENT_X.store(current_x, Ordering::SeqCst); CURRENT_Y.store(current_y, Ordering::SeqCst); copy_to_fb(); + FRAMEBUFFER_LOCK.unlock(); } pub fn setup_display(info: FramebufferInfo) { let addr = unsafe { map_physical(info.address, info.height * info.stride * 4, true) }; diff --git a/loader/src/main.rs b/loader/src/main.rs index c94296d..c666e3b 100644 --- a/loader/src/main.rs +++ b/loader/src/main.rs @@ -7,7 +7,7 @@ extern crate alloc; use core::{ mem, panic::PanicInfo, - sync::atomic::{AtomicU64, Ordering}, + sync::atomic::{AtomicBool, AtomicU64, Ordering}, }; use display::setup_display; @@ -24,9 +24,8 @@ use paging::setup_paging; use raw_cpuid::CpuId; use static_alloc::Bump; use uefi::{ - boot::{allocate_pages, exit_boot_services}, - boot::{AllocateType, MemoryType}, - entry, + boot::{allocate_pages, exit_boot_services, AllocateType, MemoryType}, + entry, println, system::with_config_table, Status, }; @@ -38,6 +37,7 @@ mod paging; #[global_allocator] static ALLOC: Bump<[u8; 8 * 1024 * 1024]> = Bump::uninit(); +static BOOT_SERVICES_ACTIVE: AtomicBool = AtomicBool::new(true); const KERNEL: &[u8] = include_bytes!("../../target/x86_64-unknown-none/release/kernel"); @@ -65,6 +65,7 @@ fn main() -> Status { } }); assert_ne!(rsdp.load(Ordering::SeqCst), 0, "RSDP not found"); + BOOT_SERVICES_ACTIVE.store(false, Ordering::SeqCst); let framebuffer_info = setup_display(); let memory_map = unsafe { exit_boot_services(MemoryType::LOADER_DATA) }; let pml4 = setup_paging(&memory_map, heap_start); @@ -77,8 +78,11 @@ fn main() -> Status { } #[panic_handler] fn panic(info: &PanicInfo) -> ! { - error!("{}", info); cli(); + error!("{}", info); + if BOOT_SERVICES_ACTIVE.load(Ordering::SeqCst) { + println!("{}!", info); + } loop { hlt(); }