diff --git a/VKernel/Kernel/main.vp b/VKernel/Kernel/main.vp index fa1d02b..08b389c 100644 --- a/VKernel/Kernel/main.vp +++ b/VKernel/Kernel/main.vp @@ -34,6 +34,31 @@ import asm kbd_tid: int = -1 mse_tid: int = -1 +# 影子副本 + 校验:__init__ 的 fb/width/height/pitch 局部量曾被偶发写坏(被清零, +# 导致 desktop.start 拿到 fb=0 → 刷新把后备缓冲写到物理 0 起,覆盖内核自身)。 +# 这里保存模块级影子并在关键节点比对,命中即 fail-fast 暴露写坏源,不再让损坏值被静默使用。 +_ShadowFb: uint64 = 0 +_ShadowW: int = 0 +_ShadowH: int = 0 +_ShadowPitch: int = 0 + +def _SetFrameShadow(fb: rawptr, w: int, h: int, pitch: int): + global _ShadowFb, _ShadowW, _ShadowH, _ShadowPitch + _ShadowFb = uint64(fb) + _ShadowW = w + _ShadowH = h + _ShadowPitch = pitch + +def _CheckFrameLocals(tag: const str, fb: rawptr, w: int, h: int, pitch: int): + if uint64(fb) != _ShadowFb or w != _ShadowW or h != _ShadowH or pitch != _ShadowPitch: + b: [176]char + viperlib.snprintf(&b, 176, + "[FATAL] %s: frame locals corrupted fb=0x%lx w=%d h=%d pitch=%d (expect 0x%lx %d %d %d)\n", + tag, uint64(fb), w, h, pitch, _ShadowFb, _ShadowW, _ShadowH, _ShadowPitch) + serial.puts(&b) + while True: + sched.Scheduler._yield() + BootInfo: bootinfo.bootinfo* class ViperKernel: @@ -128,6 +153,7 @@ class ViperKernel: pitch: int = int(BootInfo.framebuffer_pitch) fb_format: int = int(BootInfo.framebuffer_format) fb_size: uint64 = BootInfo.framebuffer_size + _SetFrameShadow(fb, width, height, pitch) # [DBG] 打印 BootInfo 指针与 memmap 原始字段,定位全 0 根因(用后移除) _dbbuf: [140]char viperlib.snprintf(&_dbbuf, 140, "[main] BootInfo=0x%lx mmap=0x%lx mmsz=%lu mmd=%lu fb=0x%lx\n", @@ -292,6 +318,7 @@ class ViperKernel: # paging and mm already initialized before FAT32 usb.init() + _CheckFrameLocals("after_usb", fb, width, height, pitch) serial.puts("[main] starting keyboard service\n") kbd_svc.start() @@ -302,9 +329,11 @@ class ViperKernel: VGA_drv = vga._VGAScreenDriver(fb, width, height, pitch, fb_format) self.VGA = &VGA_drv self.VGA.Print(100, 100, "ViperOS VKernel Test") + _CheckFrameLocals("after_vga", fb, width, height, pitch) serial.puts("你好\n") serial.puts("[main] starting desktop\n") + _CheckFrameLocals("pre_desktop", fb, width, height, pitch) desktop.start(fb, width, height, pitch) serial.puts("[main] desktop started\n")