Trap Records新增Trap05:探针名.fschk非法致无限重格式化全根因链与证伪记录

This commit is contained in:
2026-09-20 13:42:20 +08:00
parent d77747ec43
commit be6cd046a2
@@ -132,3 +132,63 @@ if (ok) {
- 返回“连续区间”的辅助函数,其返回值是起点还是终点必须在注释/命名中明确,
调用方与实现必须一致
- 这类错位 bug 往往只在“区间贴到设备边界”时才触发,正常情况能过,建议测试覆盖边界块
## Trap 05 — FatFs 探针文件名非法 → 无限重格式化(已修复,2026-09-20)
**发现时间**:2026-09-20(症状自卷健康探针引入之日起长期存在)
**现象**:
每次软件复位(ST-LINK Reset&Run / 上电)开机日志都出现
`[FS] volume FAT invalid (fr=6), reformatting...`,`/config.ini` 永远
"file missing, factory template generated";journal head 每 boot 前进
~300 页(持续磨损);in-boot 一切正常(挂载/写文件都好)。
**真根因(纯软件,NAND/驱动/电源全部无罪)**:
卷健康探针 `f_open("/.fschk", FA_WRITE|FA_OPEN_ALWAYS)` 的名字非法——
本移植 `FF_USE_LFN=0`,`ff.c create_short` 把 `.fschk` 点后的 "FSCHK"
当**扩展域**解析(5 字符 > 3 上限)→ `f_open` 返回 `FR_INVALID_NAME(6)`,
**纯 RAM 名字判定、根本不碰盘**(FF_RPATH≠0 时点开头还会走 `.`/`..`
特殊目录分支同样拒绝)。而 `FR_INVALID_NAME` 被误归入"结构性错误集合"
→ 每 boot 假失败 → 触发 `f_mkfs` → **无限重格式化**。
**修复**(commit 81a11c8):
1. 探针文件名改 `/fschk.tmp`(严格 8.3:名≤8、扩展≤3、不以点开头);
2. `FR_INVALID_NAME` 移出重格式化触发集合(名字语法错误与卷健康无关)。
**验证**(gen 45~48,@test 连续复位):
`Map resumed: 197→198→199→200 sectors used`(卷随 boot 正常增量持久)、
无 reformat 行、`[CFG] load: OK (523B)`(config.ini 跨复位存活)、VERDICT PASS。
**调查中被证伪的假设(重要反面记录)**:
1. **低 VDD"幻影编程"假设——证伪**:怀疑 3.1V 供电下 program 状态报成功
但 cell 未 latch。裸 NAND 持久性自检(块 2040/2041:擦→写 4 页图案→
立即回读→跨复位再回读 seq 递增)实测 4/4 全过:芯片、驱动原语、供电
在同一台架上的持久性完全正常。
2. **"journal 混合页/数据损坏"假设——误读**:所谓"LPN16 恒为 `RRaA`
垃圾、LPN0 全零、LPN15 全 FF"实为**合法卷内容**——本移植
`f_mkfs(FM_FAT32)` 创建的是 **MBR 分区卷**(分区起点 LBA 63):
LPN0=MBR 页(前 446 字节引导区本来就全零)、LPN15 页尾(扇区 63)=BPB
(页首扇区 60-62 未用=FF)、LPN16 页首=备份 FSInfo(`52 52 61 41` =
0x41615252 "RRaA" 是合法签名!)。判定"损坏"前默认了几何=整盘 FAT32,
把合法结构当成了花屏。
3. 三个先前修复(mkfs 前清 FTL 树 ac2087e、page_read 二次发令 38b70ad、
读后 2ms settle)**都没有终结循环**——它们是合理硬化(全部保留),
但不是根因。
**定界决定性手段**:
- 裸 NAND 跨复位持久性自检 → 排除介质/驱动/电源,指向文件系统层;
- glue 层 wsrc/flush/proglog 写链路追踪 → 暴露 mkfs 真实落盘几何
(boot 记录写向扇区 63/64/69/70/95 = 标准 MBR 布局);
- `fr=6=FR_INVALID_NAME` 枚举语义 → "路径名格式非法"不可能来自盘。
**经验教训**:
- `FF_USE_LFN=0` 时一切文件名必须严格 8.3,`.hidden` 风格点开头名字
完全不可用;新建文件的代码路径先按 `create_short` 解析规则推演一遍
- 磁盘健康探针必须**按错误语义分诊**:名字/参数类纯软件错误
(FR_INVALID_NAME / FR_INVALID_PARAMETER 等)绝不能触发整卷擦除
- 判定"存储数据损坏"前必须先确认**实际卷几何**(f_mkfs 默认 MBR 分区、
b_vol=63;全零/全 FF/RRaA/EB FE 90 都可能是合法结构而非花屏)
- 分层定界优先做**最小闭环自下而上测试**(裸介质跨复位持久性),
一次实验即可排除/坐实整个故障域,远胜在上层猜机制
- 探针自身也可能有 bug:错误码要记录"是哪次调用返回的 + 枚举语义"——
本例 fr=6 在日志里挂了几十个 boot 没人查过枚举表