feat(vkernel): __init__ 帧参数加影子副本校验(fail-fast 抓偶发写坏源)
fb/width/height/pitch 局部量曾被偶发清零(→ desktop.start 拿到 fb=0 → 刷新把后备缓冲 写到物理 0 起、覆盖内核自身而卡死/崩宿主 QEMU)。USB/UHCI 路径已排查:TD 块走堆分配、 QH 在 free 前置 terminate、枚举缓冲均为堆分配且长度有钳制,未见明显越界零写。 故加常驻轻量校验(非临时探针,可长期保留): - _SetFrameShadow:BootInfo 读取后保存影子 - _CheckFrameLocals:在 after_usb / after_vga / pre_desktop 三处比对,不一致即打印 [FATAL](含期望值与实际值)并停机 —— 把“偶发写坏”变成可定位的现场, 并明确是哪一个阶段之间被写坏。
This commit is contained in:
1 parent
9cf33ab374
commit
c0c83cdc83
1 file changed
+29
@@ -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")
|
||||
|
||||
|
||||
Reference in new issue
Block a user