From 2eea065a6795415b655f42cca9cc91f9ff86ab6d Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Thu, 15 Oct 2026 17:08:58 +0800 Subject: [PATCH] =?UTF-8?q?chore(debug):=20fat32=20dir=5Ffind/win=5Fread?= =?UTF-8?q?=20=E5=8A=A0=E5=8F=96=E8=AF=81=E6=8E=A2=E9=92=88=20-=20?= =?UTF-8?q?=E8=AF=B7=E6=B1=828.3=E7=9F=AD=E5=90=8D=20vs=20=E7=A3=81?= =?UTF-8?q?=E7=9B=98=E7=9B=AE=E5=BD=95=E9=A1=B9=E3=80=81=E8=AF=BB=E7=9B=98?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E6=89=87=E5=8C=BA=E3=80=81win=5Fdirty=20?= =?UTF-8?q?=E5=86=99=E7=9B=98=E7=97=95=E8=BF=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Kernel/drivers/fs/fat32/fat32_types.vp | 58 ++++++++++++++++++- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/VKernel/Kernel/drivers/fs/fat32/fat32_types.vp b/VKernel/Kernel/drivers/fs/fat32/fat32_types.vp index a338348..68378a1 100644 --- a/VKernel/Kernel/drivers/fs/fat32/fat32_types.vp +++ b/VKernel/Kernel/drivers/fs/fat32/fat32_types.vp @@ -12,6 +12,16 @@ def _read32(buf: uint8*, off: uint32) -> uint32: def _read16(buf: uint8*, off: uint32) -> uint16: return uint16(buf[off]) | (uint16(buf[off + 1]) << 8) +# [临时探针] FAT32 目录枚举/读盘取证:请求短名 vs 磁盘目录项、win_read 失败扇区、是否发生过写盘 +# (定位 spawn 失败用,定位后连同调用点一起删除) +_f32_dbg: int = 0 + +def _f32_dbg_on() -> int: + global _f32_dbg + if _f32_dbg >= 200: return 0 + _f32_dbg = _f32_dbg + 1 + return 1 + def _write32(buf: uint8*, off: uint32, val: uint32): buf[off + 0] = uint8(val & 0xFF) buf[off + 1] = uint8((val >> 8) & 0xFF) @@ -347,6 +357,9 @@ class volinfo: last_error: uint32 = 0 def win_read(self, sector: uint64) -> FRESULT: + # [临时探针] win_dirty 非 0 = 此前发生过写盘(镜像被改动的直接证据) + if self.win_dirty != 0 and _f32_dbg_on(): + serial.puts("[f32] win_read: win_dirty=1 -> 之前有未落盘的写\n") if self.winsect == sector: return FRESULT.FR_OK if self.win_dirty: res: FRESULT = self.win_flush() @@ -356,7 +369,14 @@ class volinfo: win_addr: rawptr = &self.win[0] res2: DRESULT = diskio.read(self.pdrv, win_addr, uint32(abs_sector), 1) self.lock.unlock() - if res2 != DRESULT.RES_OK: return FRESULT.FR_DISK_ERR + if res2 != DRESULT.RES_OK: + # [临时探针] 读盘失败的绝对扇区:判断是否越界/镜像异常 + if _f32_dbg_on(): + _fb: [160]char + viperlib.snprintf(&_fb, 160, "[f32] winread FAIL sec=%lu abs=%lu hid=%lu pdrv=%lu res=%d\n", + sector, abs_sector, uint64(self.hidden_sectors), uint64(self.pdrv), int(res2)) + serial.puts(&_fb) + return FRESULT.FR_DISK_ERR self.winsect = sector return FRESULT.FR_OK @@ -709,14 +729,41 @@ class volinfo: def dir_find(self, dp: dirobj*, name: const str, lfn_buf: uint16*) -> FRESULT: sfn: [12]char sfn_from_lfn(name, &sfn[0]) + # [临时探针] 请求名 与 生成的 8.3 短名 + if _f32_dbg_on(): + _rn: [16]char + sfn_to_str(&sfn[0], &_rn[0]) + _rb: [96]char + viperlib.snprintf(&_rb, 96, "[f32] find req='%s' sfn='%s'\n", name, &_rn[0]) + serial.puts(&_rb) while True: res: FRESULT = self.dir_read_entry(dp, lfn_buf) if res != FRESULT.FR_OK: + # [临时探针] 枚举结束时游标位置(扫到哪、返回什么) + if _f32_dbg_on(): + _eb: [128]char + viperlib.snprintf(&_eb, 128, "[f32] find end res=%d sec=%lu off=%lu\n", + int(res), dp.sector, uint64(dp.offset)) + serial.puts(&_eb) return res entry_sector: uint64 = dp.sector + (dp.offset / (512 / ENTRY_SIZE)) entry_offset_in_sector: uint32 = (dp.offset % (512 / ENTRY_SIZE)) * ENTRY_SIZE res2: FRESULT = self.win_read(entry_sector) - if res2 != FRESULT.FR_OK: return FRESULT.FR_DISK_ERR + if res2 != FRESULT.FR_OK: + if _f32_dbg_on(): + _wb: [128]char + viperlib.snprintf(&_wb, 128, "[f32] find winread fail ent_sec=%lu off=%lu\n", + entry_sector, uint64(dp.offset)) + serial.puts(&_wb) + return FRESULT.FR_DISK_ERR + # [临时探针] 磁盘上逐项的 8.3 短名 + 属性(用来和请求 sfn 对照) + if _f32_dbg_on(): + _en: [16]char + sfn_to_str(str(&self.win[0] + entry_offset_in_sector), &_en[0]) + _nb: [144]char + viperlib.snprintf(&_nb, 144, "[f32] ent sec=%lu off=%lu name='%s' attr=%02x\n", + entry_sector, uint64(dp.offset), &_en[0], uint32(self.win[entry_offset_in_sector + 11])) + serial.puts(&_nb) match_found: int = 1 i: int for i in range(11): @@ -727,7 +774,10 @@ class volinfo: if a != b: match_found = 0 break - if match_found: return FRESULT.FR_OK + if match_found: + if _f32_dbg_on(): + serial.puts("[f32] find HIT (sfn)\n") + return FRESULT.FR_OK if lfn_buf and dp.lfn_ofs != 0xFFFFFFFF and dp.lfn_ofs < dp.offset: lfn_matched: int = 1 li: int = 0 @@ -744,6 +794,8 @@ class volinfo: if lfn_matched: lfn_end: uint16 = *(uint16*(uint64(lfn_buf) + li * 2)) if lfn_end == 0 or lfn_end == 0xFFFF: + if _f32_dbg_on(): + serial.puts("[f32] find HIT (lfn)\n") return FRESULT.FR_OK dp.offset += 1