From 94d40dadeddfb40cd4fd237294037a562405a2c2 Mon Sep 17 00:00:00 2001 From: salmonik Date: Sun, 2 Aug 2026 01:34:58 +0200 Subject: v0.5.4: shadow backbuffer can no longer alias the framebuffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Real-hardware scroll freeze (no exception, QEMU-clean) — the per-word push (0.5.3) did not fix it, so the wedge is upstream of the push. A QEMU slow-display simulation (new DISPLAY_STALL knob + shell 'stall' command busy-waits per display store, mimicking an uncached real-GPU framebuffer) proved the per-word push and shadow memmove are slow but finite — the shell keeps ticking, scrolls eventually complete. The freeze mechanism QEMU cannot exhibit is the shadow *landing on the framebuffer*: the heap free list spans the fb hole, so the 1.9 MB heap shadow can alias the display on machines where firmware reports the fb as ConventionalMemory — every scroll then becomes an MMIO->MMIO memcpy on an uncached framebuffer, which wedges real hardware (a stall, no fault, hence no dump). Fix: - gop::init_shadow(): allocate the shadow from the fb-aware page allocator (init_page_allocator marks fb pages used per-page), so it can never overlap the display; heap allocation kept only as a fallback with an explicit overlap rejection. Boot log now prints 'gop: shadow @ ... origin=page-alloc|heap|none'. - Scroll shadow memmove converted to per-word stores (belt and suspenders — immune to any future fb-aliased shadow). - Verified on QEMU: shadow @ 0x100000 vs fb 0x80000000..0x801d5000, overlap=false; all 5 test suites pass; scroll completes even under the stalled-display simulation. --- rsdos/src/main.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'rsdos/src') diff --git a/rsdos/src/main.rs b/rsdos/src/main.rs index 6dbad5f..3153930 100644 --- a/rsdos/src/main.rs +++ b/rsdos/src/main.rs @@ -172,6 +172,7 @@ pub unsafe extern "efiapi" fn efi_main(image_handle: Handle, system_table: *mut } else { rsnix::serial_println!("pages: init FAILED"); } + rsnix::gop::init_shadow(); if rsnix::memory::page_self_test() { rsnix::serial_println!("pages: self-test OK (alloc/free/runs)"); } else { -- cgit v1.2.3