summaryrefslogtreecommitdiffstats
path: root/rsdos/src/main.rs
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-08-02 01:59:45 +0200
committersalmonik <salmonik@tuta.io>2026-08-02 01:59:45 +0200
commit5185fe98d404c6c15a52f513313042ced16c350a (patch)
tree0fd00f065d9d566e59da1af463befeace36b1fc9 /rsdos/src/main.rs
parentv0.5.5: visible boot progress + panic-on-screen for real hardware (diff)
downloadrs-dos-5185fe98d404c6c15a52f513313042ced16c350a.tar.gz
rs-dos-5185fe98d404c6c15a52f513313042ced16c350a.zip
v0.5.5: self-diagnosing boot — vt refuses 0x0 geometry, panic band shows last stage
The user's real-hardware boot showed 'PANIC: index out of bounds (len 0, index 0) at vt.rs:146' — the vt grid was created empty because the framebuffer geometry was 0x0 at vt::init (GOP missing or the active mode reporting zero resolution). The v0.5.4 blank screen was the same panic, previously invisible (no screen dump in the panic handler). - vt::init: rows/cols == 0 now halts with a visible white-on-red 'FATAL: no framebuffer geometry — GOP missing or active mode is 0x0' band instead of building an empty grid that panics at the first cell write. - boot_marker records the last boot stage; the panic band appends it as a 4th line so a crash shows exactly how far boot got. - The gop+vt marker now carries the measured geometry ('rsnix: gop 800x600 vt 100x37 ok') so a good boot is self-confirming on the screen. - All 5 test suites pass; build/clippy clean.
Diffstat (limited to 'rsdos/src/main.rs')
-rw-r--r--rsdos/src/main.rs16
1 files changed, 14 insertions, 2 deletions
diff --git a/rsdos/src/main.rs b/rsdos/src/main.rs
index b6393ee..aa116e4 100644
--- a/rsdos/src/main.rs
+++ b/rsdos/src/main.rs
@@ -5,6 +5,8 @@
5use core::panic::PanicInfo; 5use core::panic::PanicInfo;
6use rsnix::uefi::*; 6use rsnix::uefi::*;
7 7
8extern crate alloc;
9
8// --------------------------------------------------------------------------- 10// ---------------------------------------------------------------------------
9// Panic handler 11// Panic handler
10// --------------------------------------------------------------------------- 12// ---------------------------------------------------------------------------
@@ -47,9 +49,11 @@ fn panic(info: &PanicInfo) -> ! {
47 } 49 }
48 // Real hardware has no serial console — put the panic on the screen 50 // Real hardware has no serial console — put the panic on the screen
49 // too (white-on-red band), so a pre-shell panic is not a silent 51 // too (white-on-red band), so a pre-shell panic is not a silent
50 // blank screen. 52 // blank screen. The last boot stage is appended so the user can
53 // see how far boot got before the crash.
51 let mut loc_buf = [0u8; 96]; 54 let mut loc_buf = [0u8; 96];
52 let mut msg_buf = [0u8; 128]; 55 let mut msg_buf = [0u8; 128];
56 let mut stage_buf = [0u8; 96];
53 let loc_n = { 57 let loc_n = {
54 let mut w = rsnix::strbuf::FmtBuf::new(&mut loc_buf); 58 let mut w = rsnix::strbuf::FmtBuf::new(&mut loc_buf);
55 if let Some(loc) = info.location() { 59 if let Some(loc) = info.location() {
@@ -64,10 +68,17 @@ fn panic(info: &PanicInfo) -> ! {
64 let _ = write!(&mut w, "{}", info.message()); 68 let _ = write!(&mut w, "{}", info.message());
65 w.len() 69 w.len()
66 }; 70 };
71 let stage_n = {
72 let s = rsnix::gop::last_boot_stage();
73 let n = s.len().min(stage_buf.len());
74 stage_buf[..n].copy_from_slice(&s.as_bytes()[..n]);
75 n
76 };
67 let lines = [ 77 let lines = [
68 "*** PANIC ***", 78 "*** PANIC ***",
69 core::str::from_utf8(&msg_buf[..msg_n]).unwrap_or("?"), 79 core::str::from_utf8(&msg_buf[..msg_n]).unwrap_or("?"),
70 core::str::from_utf8(&loc_buf[..loc_n]).unwrap_or("?"), 80 core::str::from_utf8(&loc_buf[..loc_n]).unwrap_or("?"),
81 core::str::from_utf8(&stage_buf[..stage_n]).unwrap_or(""),
71 ]; 82 ];
72 rsnix::gop::dump_lines(&lines); 83 rsnix::gop::dump_lines(&lines);
73 loop { 84 loop {
@@ -150,7 +161,8 @@ pub unsafe extern "efiapi" fn efi_main(image_handle: Handle, system_table: *mut
150 rsnix::vt::init(); 161 rsnix::vt::init();
151 let (rows, cols) = rsnix::vt::size(); 162 let (rows, cols) = rsnix::vt::size();
152 rsnix::serial_println!("vt: terminal ready ({}x{})", rows, cols); 163 rsnix::serial_println!("vt: terminal ready ({}x{})", rows, cols);
153 rsnix::gop::boot_marker("rsnix: gop+vt ok"); 164 let (fw, fh) = rsnix::gop::pixel_dims();
165 rsnix::gop::boot_marker(&alloc::format!("rsnix: gop {}x{} vt {}x{} ok", fw, fh, cols, rows));
154 166
155 // ExitBootServices — we now own the machine 167 // ExitBootServices — we now own the machine
156 if unsafe { (bs.exit_boot_services)(image_handle, map_key) } != EFI_SUCCESS { 168 if unsafe { (bs.exit_boot_services)(image_handle, map_key) } != EFI_SUCCESS {