Trap Records新增Trap05:探针名.fschk非法致无限重格式化全根因链与证伪记录
This commit is contained in:
@@ -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 没人查过枚举表
|
||||
|
||||
Reference in New Issue
Block a user