summaryrefslogtreecommitdiffstats
path: root/rsnix
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-08-02 23:28:29 +0200
committersalmonik <salmonik@tuta.io>2026-08-02 23:28:29 +0200
commitf846a9551bf30d61026fa9c9ccea78479ced321b (patch)
tree10158ca300cc51f44fc9afee9c2b3092554d880b /rsnix
parentv0.5.7: guard reports the drop's size/align — identifies the clobbered struct (diff)
downloadrs-dos-f846a9551bf30d61026fa9c9ccea78479ced321b.tar.gz
rs-dos-f846a9551bf30d61026fa9c9ccea78479ced321b.zip
v0.5.7: drop test-poison hooks; vt heap-struct verify at shell entry
The OptiPlex's first banner write #GPs when the vt cells VecData holds firmware 0xAA fill instead of a real buffer pointer. The poison/fill test hooks (stack + free-heap + free-page 0x00AAAAAA) were removed from the release image — they changed boot behavior and may walk a corrupt free list over live blocks. Added vt::debug_verify() (cells/rendered ptr/cap/len + in-heap check) at shell entry: the next real-hardware boot shows whether the corruption is present at shell entry or lands during the banner write.
Diffstat (limited to 'rsnix')
-rw-r--r--rsnix/src/vt.rs42
1 files changed, 42 insertions, 0 deletions
diff --git a/rsnix/src/vt.rs b/rsnix/src/vt.rs
index 4578f6c..6343b78 100644
--- a/rsnix/src/vt.rs
+++ b/rsnix/src/vt.rs
@@ -138,6 +138,48 @@ pub fn size() -> (usize, usize) {
138 unsafe { (ROWS, COLS) } 138 unsafe { (ROWS, COLS) }
139} 139}
140 140
141/// Shell-entry self-check: dump the vt grid's heap structs so a real-
142/// hardware boot shows whether the cells VecData / data arrays are sane
143/// at shell entry (the OptiPlex's first banner write #GPs when the
144/// cells buffer holds firmware 0xAA fill instead of real pointers).
145pub fn debug_verify() {
146 unsafe {
147 let total = ROWS * COLS;
148 let msg = |m: &str| {
149 crate::serial_println!("vt: {}", m);
150 };
151 if CELLS.is_null() || RENDERED.is_null() {
152 msg("verify: cells/renderd NULL — vt::init did not run");
153 return;
154 }
155 let c = &*(CELLS as *const Vec<Cell>);
156 let r = &*(RENDERED as *const Vec<Cell>);
157 msg(&alloc::format!(
158 "verify: cells ptr={:#x} cap={:#x} len={:#x} rendered ptr={:#x} cap={:#x} len={:#x} want={:#x}",
159 c.as_ptr() as usize,
160 c.capacity(),
161 c.len(),
162 r.as_ptr() as usize,
163 r.capacity(),
164 r.len(),
165 total
166 ));
167 // The cells array must cover rows*cols and be inside the heap.
168 let heap_ok = crate::memory::heap_range()
169 .map(|(hs, he)| {
170 let p = c.as_ptr() as usize;
171 let bytes = c.capacity().saturating_mul(core::mem::size_of::<Cell>());
172 p >= hs && p + bytes <= he
173 })
174 .unwrap_or(false);
175 if c.len() != total || r.len() != total || !heap_ok {
176 msg("verify: FAILED — cells/rendered not sane at shell entry");
177 } else {
178 msg("verify: ok");
179 }
180 }
181}
182
141pub fn set_cursor_visible(v: bool) { 183pub fn set_cursor_visible(v: bool) {
142 sync_scroll(); 184 sync_scroll();
143 unsafe { 185 unsafe {