fix(fat32,devfs): c.Set 坏模式静默不写——lfn_extract/lfn_set_char 从未写入 LFN 缓冲,dir_find 长文件名匹配永远失败;devfs 键盘/鼠标 buffer 未写入;改 c.Set(c.Deref(ptr),val) 与下标赋值,并补 sfn 超 8 字符生成 ~1 短名;elf bad magic 加 hex dump 诊断

This commit is contained in:
TermiNexus committed 2026-08-27 00:32:54 +08:00
1 parent 3418bc6a59
commit 25d2628cd4
3 files changed
+32 -9

No files matched your search

+6 -4
View File
@@ -436,7 +436,9 @@ class keyboard_device(devfs_file):
sc: t.CUInt8T = keyboard.read_scancode()
ch: t.CChar = keyboard.scancode_to_ascii(sc)
if ch != '\0':
c.Set(t.CChar(buffer, t.CPtr)[count], ch)
# c.Set(t.CChar(...)[count], ch) 是 Subscript 左值,translate_c_set
# 不处理 → 静默丢弃。改普通下标赋值(AssignGen 支持 Subscript store)。
t.CChar(buffer, t.CPtr)[count] = ch
count += 1
return count
@@ -468,11 +470,11 @@ class mouse_device(devfs_file):
pkt: mouse.mouse_packet
mouse.read_packet(c.Addr(pkt))
if size >= 1:
c.Set(t.CUInt8T(buffer, t.CPtr)[0], pkt.buttons)
t.CUInt8T(buffer, t.CPtr)[0] = pkt.buttons
if size >= 5:
buf: t.CUInt32T | t.CPtr = t.CVoid(t.CUInt64T(buffer) + 1, t.CPtr)
c.Set(t.CInt32T(buf, t.CPtr)[0], mouse.get_x())
c.Set(t.CInt32T(buf, t.CPtr)[1], mouse.get_y())
t.CInt32T(buf, t.CPtr)[0] = mouse.get_x()
t.CInt32T(buf, t.CPtr)[1] = mouse.get_y()
return 5
return 1
+15 -5
View File
@@ -211,8 +211,12 @@ def lfn_set_char(entry_bytes: t.CUInt8T | t.CPtr, idx: t.CInt, ch: t.CUInt16T):
off = 14 + (idx - 5) * 2
else:
off = 28 + (idx - 11) * 2
c.Set(t.CUInt8T(t.CUInt64T(entry_bytes) + off, t.CPtr), t.CUInt8T(ch & 0xFF))
c.Set(t.CUInt8T(t.CUInt64T(entry_bytes) + off + 1, t.CPtr), t.CUInt8T(ch >> 8))
# c.Set(类型转换表达式, 值) 是坏模式:translate_c_set 对非 c.Deref 的
# Call 直接 return b_val(静默不写)。必须 c.Set(c.Deref(ptr), 值) = *ptr = 值。
# 此前 lfn_set_char/lfn_extract 从未写入 entry_bytes/lfn_buf → LFN 条目
# 读写全失效 → dir_find 的 LFN 匹配(gargantua.elf 等长文件名)永远失败。
c.Set(c.Deref(t.CUInt8T(t.CUInt64T(entry_bytes) + off, t.CPtr)), t.CUInt8T(ch & 0xFF))
c.Set(c.Deref(t.CUInt8T(t.CUInt64T(entry_bytes) + off + 1, t.CPtr)), t.CUInt8T(ch >> 8))
def lfn_extract(entry_bytes: t.CUInt8T | t.CPtr, lfn: t.CUInt16T | t.CPtr, ord_val: t.CUInt8T) -> t.CInt:
seq: t.CInt = (ord_val & 0x3F) - 1
@@ -221,11 +225,11 @@ def lfn_extract(entry_bytes: t.CUInt8T | t.CPtr, lfn: t.CUInt16T | t.CPtr, ord_v
for i in range(LFN_ENTRY_CHARS):
ch: t.CUInt16T = lfn_get_char(entry_bytes, i)
if ch == 0x0000 or ch == 0xFFFF:
c.Set(t.CUInt16T(t.CUInt64T(lfn) + (base + i) * 2, t.CPtr), 0)
c.Set(c.Deref(t.CUInt16T(t.CUInt64T(lfn) + (base + i) * 2, t.CPtr)), 0)
return base + i
c.Set(t.CUInt16T(t.CUInt64T(lfn) + (base + i) * 2, t.CPtr), ch)
c.Set(c.Deref(t.CUInt16T(t.CUInt64T(lfn) + (base + i) * 2, t.CPtr)), ch)
if ord_val & LFN_FLAG_LAST:
c.Set(t.CUInt16T(t.CUInt64T(lfn) + (base + LFN_ENTRY_CHARS) * 2, t.CPtr), 0)
c.Set(c.Deref(t.CUInt16T(t.CUInt64T(lfn) + (base + LFN_ENTRY_CHARS) * 2, t.CPtr)), 0)
return base + LFN_ENTRY_CHARS
def sfn_from_lfn(lfn: t.CConst | t.CChar | t.CPtr, sfn: t.CChar | t.CPtr):
@@ -251,6 +255,12 @@ def sfn_from_lfn(lfn: t.CConst | t.CChar | t.CPtr, sfn: t.CChar | t.CPtr):
else:
if ext_i < 3: sfn[8 + ext_i] = uc; ext_i += 1
si += 1
# 主名超 8 字符:生成 8.3 短名(前 6 字符 + ~1),对齐 FAT32 规范
# (此前直接截断到 8 字符 → "gargantua.elf" 生成 "GARGANTU.ELF",
# 与磁盘的 "GARGAN~1.ELF" 不匹配 → dir_find 找不到 → FR_NO_FILE)
if dot_pos > 8:
sfn[6] = '~'
sfn[7] = '1'
sfn[11] = 0
def sfn_to_str(sfn: t.CConst | t.CChar | t.CPtr, out: t.CChar | t.CPtr):
+11
View File
@@ -139,6 +139,17 @@ def load_elf(path: t.CConst | str, do_map: t.CInt = 1) -> t.CVoid | t.CPtr:
if ehdr.e_ident[0] != ELFMAG0 or ehdr.e_ident[1] != ELFMAG1 or ehdr.e_ident[2] != ELFMAG2 or ehdr.e_ident[3] != ELFMAG3:
serial.puts("[elf] bad magic\n")
# [DIAG] 一次性定位 bad magic:dump ehdr_buf 前 16 字节 + read_len,
# 区分全 0(read 未写)/ 目录数据(sector 错)/ 垃圾(seek 或缓冲错)。
_dbg_mg: t.CArray[t.CChar, 120]
viperlib.snprintf(c.Addr(_dbg_mg), 120,
"[elf] mg=%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x rl=%lu fp=%lu/%lu/%lu/%lu\n",
ehdr_buf[0], ehdr_buf[1], ehdr_buf[2], ehdr_buf[3],
ehdr_buf[4], ehdr_buf[5], ehdr_buf[6], ehdr_buf[7],
ehdr_buf[8], ehdr_buf[9], ehdr_buf[10], ehdr_buf[11],
ehdr_buf[12], ehdr_buf[13], ehdr_buf[14], ehdr_buf[15],
read_len, fp.first_cluster, fp.current_cluster, fp.file_pos, fp.file_size)
serial.puts(c.Addr(_dbg_mg))
fat32.close(fp)
return None