<feed xmlns='http://www.w3.org/2005/Atom'>
<title>rs-dos/rsnix/src/gop.rs, branch qemu</title>
<subtitle>Simple, kernel-only, 64bit OS, early stage.
</subtitle>
<id>https://git.2137697.xyz/rs-dos/atom?h=qemu</id>
<link rel='self' href='https://git.2137697.xyz/rs-dos/atom?h=qemu'/>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/'/>
<updated>2026-08-17T18:28:48Z</updated>
<entry>
<title>vt → per-instance Terminal rendering into a pixel buffer</title>
<updated>2026-08-17T18:28:48Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-08-17T18:28:48Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/commit/?id=7bd3459f4f8bae69509202e5aa0dbd04a42c656f'/>
<id>urn:sha1:7bd3459f4f8bae69509202e5aa0dbd04a42c656f</id>
<content type='text'>
- Refactor vt.rs into a per-instance Terminal struct (owned cell/rendered
  grids, cursor, ANSI parser, scroll state), rendering glyphs into a
  caller-owned pixel buffer with dirty-region blitting
- Add gop buffer primitives (buffer_glyph_px, buffer_shift_up) and keep
  the legacy vt:: API as thin wrappers around the home terminal
- Remove the now-obsolete scroll hook and shadow scroll path
- Home terminal renders into its own buffer; window_id stays None until
  the WM integration lands
</content>
</entry>
<entry>
<title>wm: keep windows in place when the console scrolls beneath them</title>
<updated>2026-08-17T17:08:47Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-08-17T17:08:47Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/commit/?id=f4fab5a2b06c37df08d2d315bcb44d15af1786a4'/>
<id>urn:sha1:f4fab5a2b06c37df08d2d315bcb44d15af1786a4</id>
<content type='text'>
The console's batched scroll (gop::shift_up_n) shifts the whole shared
shadow, which dragged any composited window pixels up with it.  Add a
scroll hook so the window manager re-composites every visible window
after a console scroll, restoring them at their fixed positions.
</content>
</entry>
<entry>
<title>Windowed GUI: wm module, input routing, and the paint app</title>
<updated>2026-08-17T16:56:04Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-08-17T16:56:04Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/commit/?id=5558e3509d020a0e021a77f0617044497b2f2aee'/>
<id>urn:sha1:5558e3509d020a0e021a77f0617044497b2f2aee</id>
<content type='text'>
- Add the wm window-manager facility per ADR 0004: overlapping
  pixel-surface windows, damage-rectangle compositing, WM-drawn title
  bar, focus/minimize/close, and F1-F4 keybindings
- Add gop shadow compositing primitives and vt::repaint_region so the
  console stays layer 0 beneath windows
- Route mouse (absolute coords, press/release edges) and keyboard
  (focus-aware input pump) to the focused window
- Add the rspaint drawing-program crate (pen, 8 colors, clear) and shell
  draw/windows/restore commands
- Extend TaskMsg with AppMouse/Focus/Close and document the design in
  CONTEXT.md + ADR 0004
</content>
</entry>
<entry>
<title>USB2/1.1 (EHCI/UHCI) drivers + real-hardware bring-up hardening</title>
<updated>2026-08-17T12:53:52Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-08-17T12:53:52Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/commit/?id=be868a43185826b02bf6d091019bb779678525bb'/>
<id>urn:sha1:be868a43185826b02bf6d091019bb779678525bb</id>
<content type='text'>
- Add polled EHCI (USB2) and UHCI (USB1.1) host-controller drivers with
  HID boot mouse support, wired into cursor polling and the 'usb' shell cmd
- Add USB Legacy ownership handoff (claim_usb_legacy) plus config_write_byte
- Harden boot: verify the PIT/timer ticks before shell entry, EOI stray
  interrupts in the LAPIC to stop interrupt storms, bound PS/2 controller
  waits, and INTx-disable AHCI (polled driver)
- Add boot stage markers, klog screen echo, and QR lock; scheduler
  mark_shell_running; NO_USB stopgap to keep BIOS USB-Legacy input alive
- alloc_pages_above for DMA buffers that must avoid low conventional memory
- Expand DEBUG_NOTES with EHCI/QEMU bring-up findings
</content>
</entry>
<entry>
<title>v0.5.9: fix OptiPlex heap crash — EBS retry must not rebuild the free list</title>
<updated>2026-08-03T23:44:05Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-08-03T23:44:05Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/commit/?id=3e2261d83176752f3ea21e0c97f330b4c1757437'/>
<id>urn:sha1:3e2261d83176752f3ea21e0c97f330b4c1757437</id>
<content type='text'>
Root cause: on real hardware SetMode can invalidate the pre-captured
ExitBootServices map key, so EBS fails and the retry refreshed the map
via capture_memory_map -&gt; init_heap, which REBUILT the free list from
the raw map and wiped the allocation state of every pre-EBS live object
(the display shadow and the vt grids). Their spans became free while
still live, later allocations carved inside the shadow, and the display
writes clobbered them — zeroed back-pointers (family A ptr=0x404443e0
block=0x0) and gray glyph pixels (family B 0xaaaaaa00aaaaaa = 0x00AAAAAA
= PALETTE[7] fg-7 text colour, not a firmware scrub).

Fix: refresh_and_exit now re-captures the map and returns a fresh EBS
key without rebuilding the free list (refresh_map_key); the free list is
the authoritative live-allocation state. Verified in QEMU under a forced
EBS failure (SIMULATE_EBS_FAILURE test hook): verify ok, probe NOT free,
flhead outside the shadow — identical to a clean boot, and the full
shell sequence is crash-free.

Also: removed the crash-family debug markers from the screen (boot-time
heapdbg lines, vt verify marker, shadow marker) — the vt grid self-check
stays serial-only. Version 0.5.8 -&gt; 0.5.9.
</content>
</entry>
<entry>
<title>v0.5.8: heap-free QR encoder + crash-dump QR on framebuffer</title>
<updated>2026-08-03T00:23:35Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-08-03T00:23:35Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/commit/?id=9fde94d068f87b34e0bc6bfa48388d89bb54f1e4'/>
<id>urn:sha1:9fde94d068f87b34e0bc6bfa48388d89bb54f1e4</id>
<content type='text'>
Real hardware has no serial console, so a kernel crash only leaves a
frozen screen.  Every dump_lines() report now also renders the crash
text as a scannable QR below the white-on-red band (photograph the
screen instead of relaying text).

- rsnix/src/qr.rs: from-scratch no_std/no_alloc byte-mode QR encoder
  (EC-L, v1..v40, .bss statics only — safe on the fault path):
  RS over GF(256), codeword interleave, zigzag placement, 8 masks with
  N1-N4 penalty auto-selection, format/version info.
- gop.rs: dump_qr() joins dump lines into a static buffer, truncates
  with '...' at the v40-L capacity, encodes, and renders centered
  black-on-white with a 4-module quiet zone.
- tools/qrcheck: host harness (embedds qr.rs) + qrcheck.py cross-check
  against segno's placement primitives.  Verified bit-exact: 12
  versions x 8 masks forced, plus auto-mask choice matches segno's
  penalty evaluation.  Caught 3 encoder bugs (multi-block interleave
  offsets, transposed version info, mask eval ordering).
- QEMU e2e: page-fault dump screendump decodes via zbarimg, content
  matches the serial log line-for-line.
- test-msg.sh and test-fault.sh both PASS; debug+release 0 warnings.
</content>
</entry>
<entry>
<title>v0.5.7: fix vt verify content check — expect BLANK (0x70020), not zero</title>
<updated>2026-08-02T23:34:31Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-08-02T23:34:31Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/commit/?id=d5f41d6e057300c82b83653b4afadeffb45a9f19'/>
<id>urn:sha1:d5f41d6e057300c82b83653b4afadeffb45a9f19</id>
<content type='text'>
The pre-verify 0x70020 'mystery' was a debug artifact, not corruption:
BLANK = {ch:32, fg:7, bg:0} = raw 0x70020, and vec![BLANK; n] fills both
grids with it at init.  The old check compared cells against 0 and its
probe loop break-ed on the first non-zero cell, so probes 1-3 stayed at
their zero-initialized slots — c=[0x70020,0,0,0] was bogus on every
healthy boot.  A full-grid dump proves QEMU grids are 100% BLANK at
shell entry (nz=3700 blank=3700).

Fix: probes compare against blank_raw (0x70020), record all four values
(no early break), probe both cells and rendered, and add a full-grid
nz/blank summary line.  The OptiPlex firmware 0x00AAAAAA scrub remains
cleanly distinguishable (scrub != blank).

Markers: the shell banner occupies grid rows 0-1 and the prompt row 2
(proven by screendump), and a stale crash.log replays at rows 2+, so the
shadow and vt markers moved to the bottom of the screen via the new
gop::text_rows()/bottom_row(off) helpers instead of rows 1-2.

QEMU verified: verify: ok every boot; test-msg + test-fault PASS; debug
and release builds 0 warnings.
</content>
</entry>
<entry>
<title>v0.5.7: guard dumps block-header math + 16-word window; vt content verify; shadow marker</title>
<updated>2026-08-02T22:21:52Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-08-02T22:21:52Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/commit/?id=834b931d068a9a76e2c2a85267f24a22e93276cf'/>
<id>urn:sha1:834b931d068a9a76e2c2a85267f24a22e93276cf</id>
<content type='text'>
The klog -t 2 crash drops a 126-byte String (the vt verify klog line)
whose data ptr 0x40444970 points into the first-heap-block region whose
content is the firmware 0x00AAAAAA scrub — a stale pointer, not a real
allocation (back-pointer slot never written).  Upgrades so the next
real-hardware crash shows the full picture:
- guard: explicit candidate block bases (b=ptr-24 / b16=ptr-32) with
  their size/free fields, plus a 16-word window (mem..mem4) from
  ptr-0x30 instead of the old 8 words
- vt::debug_verify: content probe of the cells grid (must be all-BLANK
  at shell entry) — catches a stale in-heap cells pointer that passes
  the range checks
- gop: on-screen marker for shadow carved vs NO-SHADOW fallback
  (the scrub content at the crash ptr suggests the shadow was rejected
  and its block stayed free + firmware-scrubbed)
</content>
</entry>
<entry>
<title>v0.5.5: crash reports go to a dedicated CRASHLOG USB stick</title>
<updated>2026-08-02T13:21:34Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-08-02T13:21:34Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/commit/?id=c7d92071e1dd11c45999457b16554b4abaa73b28'/>
<id>urn:sha1:c7d92071e1dd11c45999457b16554b4abaa73b28</id>
<content type='text'>
The fault handler now writes crash.log to the volume labeled CRASHLOG
(label-selected via fat::crash_vol), falling back to slot 0.  On real
hardware the boot USB may be unwritable, so a second stick labeled
CRASHLOG survives the write; the shell auto-prints the previous crash
report from it at next boot (read_crash_log resolves /disk/&lt;uid&gt;/crash.log
through the FAT path, since Disk nodes hold no cached children).

- fat.rs: volume_label() + crash_vol() (no allocation)
- fs.rs: write_crash_log targets crash_vol(); read_crash_log prefers the
  CRASHLOG disk node; drop now-unused first_disk()
- mkdisk.sh: --label option
- test-fault.sh: boots with a dedicated CRASHLOG stick (mkfs -F 32 -n
  CRASHLOG), verifies crash.log lands there and NOT on the ESP
</content>
</entry>
<entry>
<title>v0.5.5: fix real-hardware boot crash — shadow back in heap as first allocation</title>
<updated>2026-08-02T00:16:40Z</updated>
<author>
<name>salmonik</name>
<email>salmonik@tuta.io</email>
</author>
<published>2026-08-02T00:16:40Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/rs-dos/commit/?id=d9fe082ef07b6e5c599585d6911dbad2bbe4c787'/>
<id>urn:sha1:d9fe082ef07b6e5c599585d6911dbad2bbe4c787</id>
<content type='text'>
User's machine: boot reached 'rsnix: boot done — shell' then panicked
'len is 0, index 0' at the first cell write — CELLS (the vt grid) was
valid at vt::init and empty at the first shell paint, i.e. something
stomped the heap between vt::init and the shell banner.  The only
change in that window vs the working v0.5.3 was the v0.5.4 move of the
1.9 MB display shadow from the heap to the fb-aware page allocator:
on this machine's memory layout the page-allocator shadow's fill loop
(480K words) clobbered the heap's vt vectors.

- Shadow is again the *first* heap allocation, in gop::init before
  vt::init builds its grids (the v0.5.3 layout that provably boots on
  the user's hardware) — nothing else in the heap can collide with it.
- init_heap now splits the free list at the GOP framebuffer hole
  instead of subtracting its size from one block that still *spanned*
  the hole — no heap allocation of any size can land on the display.
- Kept the panic-proof try_reserve + fb-overlap rejection + no-shadow
  warning band; dropped the late init_shadow() call in main.rs.
- Verified on QEMU: shadow @ 0x1980020 origin=heap, allocated before
  vt::init, fb clean at 0x80000000; all 5 suites PASS; 0 warnings.
</content>
</entry>
</feed>
