| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
| |
- 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
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
- 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
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
- 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
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Polled xHCI driver (mouse-only): controller bring-up, port reset,
enable-slot -> address-device -> config-descriptor walk -> HID boot
mouse IN endpoint, one outstanding IN TRB drained on poll. Cursor
task polls usb first, PS/2 second. New 'usb'/'usb rescan' shell cmds.
Verified in QEMU (q35 + OVMF + qemu-xhci + usb-mouse): movement and
all three buttons tracked exactly; heap stays clean.
Fixes en route: MaxPorts=HCSPARAMS1[31:24]; operational regs CRCR=0x18
DCBAAP=0x30 CONFIG=0x38; pass input-context ptr in Address-Device;
Input Control Context DW0=Drop DW1=Add; HID walker bInterfaceClass at
+5; async discovery from cursor task.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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 -> 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 -> 0.5.9.
|
| |
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
| |
The OptiPlex crashes free garbage (0xaaaaaa, 0xaaaaaa00aaaaaa) whose
value is the firmware's 0x00AAAAAA scrub pattern left in stack/heap.
The drop size/align (the dealloc layout) now prints on the band, so the
next repro shows both the garbage ptr AND the size it was freed with —
cap×elem_size pinpoints which struct's fields were clobbered.
|
| |
|
|
|
|
|
|
| |
The OptiPlex repro copies are truncated at the ~110-char band width, so
the old single-line 'stk:' (12 words, >200 chars) lost the return chain
after a few words. Split mem/stk dumps into 4-words-per-line blocks:
mem+mem2 (8 words around the corruption) and stk..stk4 (16 words) —
the drop caller chain now survives hand transcription.
|
| |
|
|
|
|
|
| |
The OptiPlex heap-corruption repro (guard report) came in hand-copied
and garbled; the exact heap start/end was the missing datum. The heap
self-test range was serial-only; now it is also a boot marker, so the
next boot shows 'rsnix: heap 0x..-0x.. (N MiB) ok' on the framebuffer.
|
| |
|
|
|
|
|
|
|
|
|
| |
- fault_dump prints img= (kernel image base) on the serial line and
the on-screen band, so a real-hardware repro can be resolved against
the PDB without serial
- backtrace: rbp-chain walk then a raw scan of the stack above the
interrupted rsp; both filter to the .text range (PE-header parse via
memory::text_range) so only code addresses are collected
- on-screen boot marker shows the kernel image range at every boot
- crash.log now records img= + bt= lines alongside rip/rsp
|
| |
|
|
|
|
|
| |
Real hardware has no serial console, and the ahci/fat/fs boot
diagnostics were serial-only — a silent fs failure left the user with
no way to see where boot stopped. Add boot_marker lines for the AHCI
disk count, FAT volume count, and the VFS tree + fs self-test result.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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/<uid>/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
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Real hardware has no serial console: a pre-shell panic was a silent
blank screen (the panic handler only wrote to serial, then cli;hlt).
v0.5.4's shadow change made this window reachable — if the fb-aware
page allocation or the heap fallback failed on hardware, the kernel
halted before the shell banner with zero screen output.
- gop::boot_marker(): every boot stage now draws straight to the
framebuffer (row 0, white-on-black). The last marker visible before
a hang identifies where the kernel died.
- Panic handler: pre-shell panics now draw a white-on-red
'*** PANIC *** <msg> at file:line' band via gop::dump_lines.
- init_shadow(): heap fallback is panic-proof (try_reserve_exact +
resize instead of vec![0; words] which aborts on OOM); page-alloc
result defensively re-checked against the fb region; any failure
degrades to no-shadow mode with a visible warning band.
- Verified: full chain (rsboot -> kernel) boots with markers, shell
banner renders, all 5 test suites pass.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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 @ <addr> ... 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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The real-hardware scroll crash (white bands + instant freeze, QEMU-clean)
was invisible because the only trace was a single serial line on machines
with no serial console. This makes every crash self-identifying and
hardens the real-hardware failure surfaces:
- Every CPU exception vector 0-31 now has an IDT entry (macro-generated
stubs; 8/14 keep their IST stacks). A fault in the shell prints a
white-on-red band to the framebuffer via gop::dump_lines (raw fb
writes bypassing the vt, fully clamped) plus a parseable serial line:
'!!! <kind> vec=N err=… rip=… cr2=… rsp=… rflags=… task=N "name"',
then halts — instead of converging to a cryptic double fault.
Background-task faults abort the task as before.
- Boot log now reports the authoritative post-SetMode geometry:
'gop: fb base=… size=… pitch=… WxH bpp=… bgr=…', so the next real
machine's report identifies whether pitch*height exceeds the mapping.
- Framebuffer writes (clear, push_rect, shift_up_n bulk push, cursor
overlay) are clamped to the firmware's framebuffer_size: a pitch-
padded mode degrades to a truncated view instead of faulting past
the mapping.
- The GOP framebuffer region is excluded from the page allocator (and
subtracted from the heap's conventional-region pick) even when the
firmware lists it as ConventionalMemory — kernel allocations can
never overwrite the display again. The GOP protocol is located and
peeked before the memory map is captured so the exclusion is known
at heap-init time.
- Shell gains a hidden 'fault' command (deliberate unmapped write) and
'make test-fault' verifies the dump: vec=14, cr2=0x400000000000,
task=0, halt — no triple fault. All other suites re-pass.
- CONTEXT.md: fault-dump format documented for real-hardware reports.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The first visible GUI surface: real rect primitives, a single
shadow→display push path, and an on-screen mouse cursor that can
never race the text surface.
gop:
- fill_rect + push_rect(x,y,w,h): every raster op rasterises into the
RAM shadow, then push_rect copies the rect to the display (write-only,
still never read) and composites the cursor on top. blit_glyph and
scroll shifts now route through it.
- cursor overlay: 12x16 pointer (const-fn built from column lists) drawn
white with a black offset outline; position in one AtomicU64 (x:high
32, y:low 32) — unpack masks the low word (a bare 'as usize' cast is
a no-op on 64-bit). The cursor never enters the shadow, so erasing is
just a shadow push of the old rect.
- cursor_redraw after scroll shifts and once at spawn (the vt diff never
re-blits idle cells).
cursor task (task 2, spawned at boot when a mouse is present):
- owns the PS/2 ring; polls every 10 ms, moves the cursor (clamped),
tracks buttons, and forwards every event to a task's queue when
'mouse <id>' armed it (the window-manager input path).
- /dev/mouse is now a position device (x/y/buttons snapshot); 'mouse'
watches the cursor live (prints on change); 'cursor' prints one-shot
state; 'gfx' draws a status-bar demo; 'gfx check' is an in-kernel
pixel self-test (shadow readback, display readback, cursor overlay
purity) — PASS/FAIL per stage.
Tests (headless QEMU + monitor injection):
- make test-gfx (new): all four compositor checks PASS.
- make test-mouse (rewritten): cursor tracks mouse_move deltas, buttons
ride along, /dev/mouse snapshot, live watch, real-event queue routing.
- make test-msg: task numbering shifted (cursor is task 2; msgrecv is
task 3) — updated, still PASS.
- make test-disk regression re-passes. 0 build warnings.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
Mouse (IRQ12, stream mode): ByteRing generalized for both PS/2 devices,
ISR routes data-port bytes by the controller's aux bit; mouse_init with
bounded-ACK handshake (boots without a mouse); packet decoder with
bit-3 resync, screen-relative deltas, buttons. Exposed as /dev/mouse,
the `mouse` stream command, and `make test-mouse`.
Message queues (ADR 0003's GUI-era primitive): every task gets a static
16-slot TaskMsg ring; send/recv/recv_blocking with direct wake + tick
scan safety net for the lost-wakeup race; `msgrecv`/`send` commands,
`mouse <id>` routes real IRQ12 events into a task's queue, jobs shows
q=. `make test-msg` + `make test-disk` regression pass.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
(fmtbuf/scripts/hexdump/cat/ahci/pci)
- memory.rs: self-test Layout::from_size_align no longer panics — the
test fails cleanly on an invalid layout
- fat.rs: v() no longer unwraps the active-volume slot — invariant
violation logs + halts instead of panicking mid-disk-io
- strbuf: shared FmtBuf replaces the duplicated PanicBuf/FmtBuf
(main.rs + sched.rs)
- test-disk.sh: SC2046 — conditional --fresh arg no longer relies on
word splitting
- scripts: boot.sh/boot-image.sh share lib-boot-args.sh (dup args loop)
- shell: cat/hexdump stdin pairs unified with Option<&str> marker;
hexdump format_row folded into format_partial
- ahci: read/write_sectors unified behind dma_sectors
- pci: config_read/write share config_addr
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
176-byte frames
- sched: 16-slot static table, shell=task 0, idle=task 1, spawn with
guard page + 8 KiB stack, RR on the 100 Hz tick, int 0x60 yield,
sleep_ms, lazy reap, jobs/bg/sleep/kill shell commands
- gdt: own GDT mirroring UEFI selectors + TSS with IST1/IST2
(guard-page overflows die gracefully instead of triple-faulting)
- interrupts: isr_dispatch returns next frame in rax; IntFrame grows
rsp/ss fields — QEMU's 64-bit iretq always pops all five slots from
a 176-byte frame, so synthetic task frames must carry rsp=top+ss
(a 160-byte frame made the first iretq pop rsp/ss from the unmapped
page beyond the frame)
- panic handler: task panics abort the task, shell keeps running
- main: sched::init moved after page allocator + adopted tables
(the idle's stack+guard need both; it was silently not spawning)
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
- edition = "2024" in the workspace manifest and rsdosedit
- extern blocks must be unsafe: interrupts.rs ISR stubs -> unsafe extern "C"
- #[no_mangle] -> #[unsafe(no_mangle)] (efi_main, isr_dispatch)
- One missed static-mut read in free_list_insert wrapped in an explicit
unsafe block (edition 2024 removed the implicit unsafe context inside
unsafe fns)
- rustfmt reflows for 2024: nested if-lets become let-chains, imports
re-sorted, rsdosedit help-screen box rows wrapped
No codegen-affecting changes. Validated: cargo check/clippy/fmt clean
(host + uefi target), make test-disk PASS, editor round-trip PASS.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Warning cleanup (cargo check + clippy now 0 across the workspace):
- Migrate all 21 static_mut_refs sites to &raw mut accessors (fat, gop,
ps2, vt, ahci, interrupts, memory) so edition 2024 won't deny them
- panic = "abort" profiles: bare cargo check/build now works without
nightly/-Zbuild-std
- Wire TICKS in the timer ISR (it was never incremented, so the vt scroll
batching trigger was dead code)
- Clippy: efi_main becomes unsafe extern "efiapi" with a # Safety doc,
KeyBuf::new uses inline-const array repeat (no interior-mutable const),
editor main loop is a while-let, PIT control byte regrouped
- [workspace.lints.clippy] allows result_unit_err + needless_range_loop
(deliberate kernel style); large_enum_variant allowed on LineInput
- Drop now-stale static_mut_refs allow from the rsdos bin
FAT32 correctness fixes (both pre-existing, exposed by the SFN fix):
- Unique 8.3 short names: to_8_3() never disambiguated collisions, so
files sharing a long-name prefix got identical SFNs and fsck reported
duplicate directory entries. Add dir_short_names() + unique_short_name()
(~N tails, Windows-style) and force LFN when the SFN changes.
- Multi-cluster directories: scan_dir/dir_short_names stopped at the first
0x00 slot, hiding every entry written into a chained cluster (writes
failed with 'cannot write', duplicate SFNs accumulated); add_dir_entry
now packs the cluster (0xE5 deleted-markers) before extending so other
FAT readers (mtools, Windows) see the continuation too.
Other: delete dead fields (Disk.fis, Volume.fat_count), drop timer_irq/
keyboard_irq/rendered, refresh_and_exit is a documented unsafe fn, CONTEXT
.md corrected (stable toolchain, IRQ input, 4-crate layout), .gitignore
excludes .pi-subagents artifacts.
Validated: cargo check/clippy/fmt clean, make test-disk PASS on fresh and
reused images (incl. two directory-chain extensions and ~10 SFN tails),
editor round-trip smoke test PASS.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- fat.rs: VOL: Option<Volume> → VOLS: Vec<Volume>; try_mount() returns
a Volume per disk and init() mounts every valid FAT32 volume found.
Volume UID = sanitized uppercase label + 8-hex volume serial
(e.g. RSDOS-5BD1E55F): unique per format, stable across reboots,
human-recognizable, machine-parseable (^[A-Z0-9_]+-[0-9A-F]{8}$);
cloned volumes get a -N suffix. Public ops take a vol index and
select it (select_vol also picks the backing AHCI disk), matching
the ahci::select pattern
- fs.rs: /disk is now a plain directory whose children are one Disk
node per mounted volume, named by UID; DiskInfo carries vol
- LFN fix: entries are stored last-first on disk — both the writer
(head-entry first) and reader (append in disk order) were reversed
and cancelled out for ≤13-char names; multi-entry names (>13 chars)
read back mangled (e.g. 'from-kernel.txt' as 'xt'). Writer now
places seq=1 closest to the SFN and seq=N|0x40 first; reader places
chunks by sequence number and trims at the first NUL. Verified with
a 25-char filename round trip: kernel ls/cat correct, mtools shows
the full LFN, fsck clean on both volumes
- test-disk.sh: test file renamed to disk-test-.txt (>13 chars,
exercises multi-entry LFN); UID discovered from the boot log; QEMU
stdio redirected to a log file + EXIT trap so an orphaned QEMU can
never hang a piped caller (it previously did, 400s)
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- ahci.rs: polling AHCI on PCI class 1/6/1, bus mastering + ABAR map,
port 0 up, IDENTIFY + READ/WRITE DMA EXT through one 4KiB DMA buffer
- fat.rs: BPB parse, whole-FAT RAM cache with write-back to both copies,
LFN read/write, dirs, multi-cluster files, FSInfo free-count sync,
space-padded dot entries ('..' = cluster 0 under root), fsck-clean
- fs.rs: /disk mount node + 24-slot ephemeral node pool; ls/cat/hexdump/
echo/mkdir/touch/rm/edit all work on disk paths unchanged
- QEMU: explicit bus assignment (disk=ide.0, ESP=ide.1); the implicit
fat:rw:esp drive was stealing AHCI port 0
- Debugged against QEMU source: header DW0 is CFL in bits 4:0 / PRDTL in
bits 31:16 (Linux libahci layout), FIS count at bytes 12-13, device at
byte 7; QEMU rejects H2D FIS flags bits 6:4, so direction is the
header W bit only
- Verified: full shell round-trip on /disk, reboot persistence (poweroff
then mdir/mtype and a fresh boot), fsck.fat clean
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The editor's gutter '│' (U+2502) appeared as '???' — write_bytes fed
each UTF-8 byte to the state machine, which mapped every byte >= 0x80
to '?', and the Latin-1 font has no box-drawing glyphs anyway.
- vt.write_bytes now decodes UTF-8 sequences; printable non-ASCII
dispatches to the glyph path instead of the byte parser.
- gop: unicode_glyph_bits() procedurally rasterises box-drawing
(U+2500-257F light/heavy/double), arrows (U+2190-2193) and the em
dash (U+2014) — pure geometry, no font data needed; blit_glyph falls
back to it for ch >= 256.
Verified via framebuffer dumps: editor gutter │ renders as a vertical
line, help screen ═ separators and ←→↑↓ all render as lines (no '?').
Shell banner em dash renders too.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Kernel now has the classic UNIX console split, so full-screen ANSI apps
can run in ring 0:
- vt.rs: terminal emulator owning the text screen — cell grid (char +
fg/bg), logical cursor (inverse-video), scrolling, and a small ANSI
CSI parser (cursor position H/f, erase J/K, moves A-D, SGR 16-colour
with correct ANSI→VGA mapping, cursor show/hide ?25). Blits only
changed cells; scroll shifts cell grids + pixels and re-rasterises
only the exposed bottom row. gop_println!/clear_screen now render
through the vt; gop.rs is the raw rasteriser (colored glyph blits,
pixel shift).
- tty.rs: line discipline — canonical read_line (echo, line buffer,
^C cancel, ^D EOF) moved out of the shell, and raw read_byte that
translates KeyEvents to the terminal byte protocol (arrows → ESC[A-D,
Backspace → 0x7f, ^X → 0x18, Ctrl+arrows → ESC[1;5A-D, Home/End/PgUp/
PgDn/Delete). interrupt_pressed() stays for streaming commands.
- ps2: generic Ctrl(char) + CtrlArrow events (was: only CtrlC/CtrlD).
- rsdosedit: no_std port of the RNG rsedit editor as the first real
app — undo, syntax highlighting (verified green/gray/yellow on the
framebuffer), search, word nav, smart indent, ^S save / ^X exit /
^X again to discard. termios → tty raw, stdout → vt, std::fs → VFS
(ramfs), SIGWINCH → fixed geometry, force-exit window → key counter.
- shell: 'edit <path>' command; read_line/strbuf moved to rsnix.
- CONTEXT.md: layout + milestones + known-issue perf notes.
Verified in QEMU: full edit → type → arrow-move → insert → save → exit
round trip with byte-exact file content; ANSI colors via screendump.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- fs.rs: node-table VFS (root /dev /tmp /etc). Regular files are
in-memory ramfs; char devices regenerate content on every read so
'cat /dev/rtc' shows the live time. Nodes are stable handles with
tombstone removal; . and .. path resolution.
- /dev devices: mem (raw physical RAM, offset = address), rtc, pci,
version, meminfo, null, zero, console (write prints to screen+serial),
serial. /etc/motd static file.
- shell: ls, cat, hexdump (hexdump -C style), mkdir, touch, rm; echo
gains '>' overwrite and '>>' append redirection (append bug fixed:
first '>' in '>>' was parsed as overwrite)
- boot: fs init + self-test (create/read/write/remove) before the shell
- QEMU verified: file lifecycle, redirection, console/null writes,
mkdir/touch/rm, hexdump /dev/mem and /tmp/x byte-exact
|
| |
|
|
|
|
|
|
|
|
| |
- rtc.rs: read the PC RTC via CMOS ports 0x70/0x71 (UIP wait, BCD/12h
normalization, century sanity-check with 2000+ fallback); boot prints
the wall clock, shell gains 'date'
- pci.rs: legacy config-space access (0xCF8/0xCFC) with full enumeration
of buses 0-255; boot reports device count, shell gains 'pci' (lspci
style listing with class names)
- QEMU q35 verified: Q35 host bridge, stdvga, e1000, ICH9 LPC
|
| |
|
|
|
|
|
|
|
|
|
| |
- uefi.rs: full EFI_RUNTIME_SERVICES layout with reset_system at index 10
(spec order); EfiResetSystem type + RESET_* constants
- power.rs: stash the runtime-services table pre-EBS; poweroff() calls
ResetSystem(EfiResetShutdown) — still callable after ExitBootServices
because we never call SetVirtualAddressMap, so the pointers keep
working with physical addresses; falls back to the hlt loop
- shell: 'poweroff' and 'exit' shut the machine down (QEMU exits),
'halt' keeps the plain hlt loop
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
- uefi.rs: full EfiMemoryType constants (0-14) + memory_type_name(); fix
MEMORY_TYPE_LOADER_DATA from 6 to 2 per the UEFI spec
- memory.rs: replace the bump allocator with a first-fit free-list heap
(splitting, coalescing, 8-byte back-pointer for alignment-safe free);
add a bitmap physical page allocator (heap region reserved, page-0
guard, aligned runs); grow the heap from the page allocator on demand
- paging.rs: identity page-table helpers — adopt_tables() rebuilds the
firmware map into our own tables (OVMF maps its tables read-only, so
the firmware tree can't be modified in place) and switches CR3;
map_page/unmap_page/is_mapped with 2 MB/1 GB large-page splitting
- main.rs: boot self-tests for heap, pages, and paging
|
|
|
Architecture:
rs-dos/ (workspace root, was raisernics/)
├── rsnix/ — kernel lib crate (uefi, serial, gop, ps2, interrupts, memory)
├── shell/ — shell lib crate (prompt, commands, line input)
├── rsdos/ — binary crate (efi_main, init, panic handler)
└── rsboot/ — future git submodule
No functional changes — boots to shell prompt identically.
Version auto-pulled from Cargo.toml via env!("CARGO_PKG_VERSION").
|