From 92ed4f6668efccf6af73f45654405d333e6a318c Mon Sep 17 00:00:00 2001 From: salmonik Date: Sat, 1 Aug 2026 02:19:07 +0200 Subject: fat: mount every FAT32 volume under /disk//, fix multi-entry LFN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - fat.rs: VOL: Option → VOLS: Vec; 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) --- CONTEXT.md | 34 +++++---- rsdos/src/main.rs | 8 +- rsnix/src/fat.rs | 201 ++++++++++++++++++++++++++++++++++++--------------- rsnix/src/fs.rs | 76 +++++++++++-------- scripts/mkdisk.sh | 8 +- scripts/test-disk.sh | 35 ++++++--- 6 files changed, 241 insertions(+), 121 deletions(-) diff --git a/CONTEXT.md b/CONTEXT.md index 39ce0bd..0d43b9f 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -168,19 +168,27 @@ Single Rust crate (`x86_64-unknown-uefi` target). Module breakdown: geometry. Verified in QEMU: edit/type/navigate/insert/save/exit, exact bytes via `cat`/`hexdump`, syntax colours via framebuffer dump. ✅ **AHCI + FAT32 (persistent disk)** — a SATA AHCI driver (polling DMA, - no interrupts) plus a FAT32 filesystem, mounted as `/disk`; every shell - command works on disk paths: `ls`/`cat`/`hexdump`/`echo >`/`>>`/ - `mkdir`/`touch`/`rm`/`edit`. The driver scans **all** implemented - ports (CAP.NP/PI) and starts every port with a device; `fat::init` - tries each disk in port order and mounts the first valid FAT32 - volume — so the kernel finds the disk no matter which AHCI port the - firmware/QEMU put it on (real hardware included). Whole-FAT cache with write-back to both - FAT copies, checksum-validated LFN read/write, multi-cluster files, - space-padded `.`/`..` dot entries (`..` → cluster 0 under the root), - FSInfo free-count maintenance (fsck-clean after a session, verified - with `fsck.fat -n`). **Files survive reboot** — verified by - poweroff → `mdir`/`mtype` on the image and by a fresh boot seeing the - prior session's files. + no interrupts) plus a FAT32 filesystem, mounted under `/disk//`; + every shell command works on disk paths: `ls`/`cat`/`hexdump`/ + `echo >`/`>>`/`mkdir`/`touch`/`rm`/`edit`. The driver scans **all** + implemented ports (CAP.NP/PI) and starts every port with a device; + `fat::init` mounts **every** valid FAT32 volume it finds, each under + `/disk//` where UID = `