From 35fc8b8ea81a61c7e2e6f0a2c54e16d449604e8b Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Fri, 16 Oct 2026 20:17:50 +0800 Subject: [PATCH] =?UTF-8?q?chore(devfs):=20=E4=B8=B4=E6=97=B6=E6=8E=A2?= =?UTF-8?q?=E9=92=88=20-=20fb0=20ioctl=20=E6=89=93=E5=8D=B0=E6=94=B6?= =?UTF-8?q?=E5=88=B0=E7=9A=84=20request/arg=20=E4=B8=8E=E5=86=99=E5=85=A5?= =?UTF-8?q?=E5=9B=9E=E8=AF=BB=EF=BC=8C=E5=AE=9A=E4=BD=8D=20explorer=20fb?= =?UTF-8?q?=20=E4=BF=A1=E6=81=AF=E5=85=A8=200?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现场:explorer 打印 [explorer] fb 0x0 pitch=0 fmt=0 size=<垃圾> phys=0x130b90 —— 6 个字段里 3 个为 0、其余是残留,判定「这次 ioctl 没有真正写入用户缓冲」而非写错地址。两种可能:(a) syscall 派发把 request 传成别的值 ⇒ ioctl 直接 return -1;(b) 写入落在用户 VA 之外的地址空间。本探针在内核侧打印 fd/req/arg 与写入后回读的 w/h/pitch/fmt:若 req 不是 0x4600 ⇒ (a);若 req 正确且回读正常而 app 仍是残留 ⇒ (b)。app 侧应同时检查 ioctl 返回值(非 0 时绝不能用未写入的 info),下一步一并改。 --- VKernel/Kernel/drivers/devfs/devfs.vp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/VKernel/Kernel/drivers/devfs/devfs.vp b/VKernel/Kernel/drivers/devfs/devfs.vp index ee2675f..6bc1413 100644 --- a/VKernel/Kernel/drivers/devfs/devfs.vp +++ b/VKernel/Kernel/drivers/devfs/devfs.vp @@ -499,6 +499,12 @@ virtual class framebuffer_device(devfs_file): return -1 def ioctl(self, fd: int, request: int, arg: rawptr) -> int: + # 【诊断·临时】确认 request/arg 是否真的到达内核、以及写入的目标 VA。 + # 若这里打印的 request 不是 0x4600,说明 syscall 派发把请求号传错了(app 会读到未写入的残留)。 + _io_b: [128]char + viperlib.snprintf(&_io_b, 128, "[fb0] ioctl fd=%d req=0x%lx arg=0x%lx w=%lu h=%lu\n", + fd, uint64(request), uint64(arg), uint64(self.fb_w), uint64(self.fb_h)) + serial.puts(&_io_b) if request != FB_GET_INFO or not arg: return -1 info: FbInfo* = FbInfo*(uint64(arg)) @@ -508,6 +514,12 @@ virtual class framebuffer_device(devfs_file): info.format = self.fb_format info.size = self.fb_size info.phys = self.fb_phys + # 【诊断·临时】回读刚写的 6 个字段:能读到新值说明写入确实落到了 arg 指向的内存。 + _io_b2: [128]char + viperlib.snprintf(&_io_b2, 128, "[fb0] ioctl wrote w=%lu h=%lu pitch=%lu fmt=%lu\n", + uint64(info.width), uint64(info.height), + uint64(info.pitch), uint64(info.format)) + serial.puts(&_io_b2) return 0 def mmap_info(self, fd: int, out_phys: uint64*, out_size: uint64*) -> int: