TermiNexus
|
30f47ca4f4
|
fix(vkernel/desktop): 时钟改为按时间每秒刷新 RTC,不再绑到渲染速率
现象:任务栏时间区域不会自己走,必须鼠标移过去才刷新。
根因:_draw_taskbar 里 RTC 缓存按“渲染次数”节流重读 ——
if _render_count % 30 == 0: rtc.rtc_read_time()
而渲染频率完全取决于活动量:空闲约 1 帧/秒 → 要 30 秒才重读一次 RTC;鼠标一移动渲染
变快,_render_count 迅速累加,很快命中 %30==0 → 时钟立刻跟上。这正是“必须鼠标移动
才刷新”的成因。
修改:
- desktop_thread 的“每秒”分支(cur_sec != _last_clock_sec)里先 rtc.rtc_read_time()
再标脏任务栏行 —— 时钟严格按秒刷新,与渲染速率解耦。
- _draw_taskbar 移除 _render_count % 30 的 RTC 重读,只取缓存值绘制。
|
2026-10-14 15:46:29 +08:00 |
|
TermiNexus
|
cc061b2ad3
|
fix(vkernel): 修复 PS/2 鼠标位移符号误判(|位移|≥128 时方向翻转、光标向左飞没)
根因(静态定位,非速度问题):PS/2 协议里第 2/3 字节是位移“幅值”,符号在第 1 字节的
bit4(X)/bit5(Y)。而驱动把位移按 int8 存储/解释,于是 |位移| ≥ 128 时字节最高位被当成
符号位:
- 向右快移(幅值 0x80~0xFF)被读成负数 → _cursor_x 一路减小 → 撞上 if _cursor_x<0
被夹成 0 → 表现为“光标往左飞没了”;
- int8 装不下 9 位有符号位移(符号位在 flags 里),结构上必然丢符号。
修改:
- drivers/input/mouse/mouse.vp:mouse_packet.dx/dy 与 byte2/byte3 改为 uint8,保存原始
幅值字节,消除 int8 截断;flags(含符号位)照旧保留。
- services/desktop.vp::_update_mouse:按协议用“幅值 + 符号位”重建带符号位移
(命中 flags.bit4/bit5 时幅值 -256),再做屏幕 Y 轴反向。
- USB HID 分支不动:USB 报告的 X/Y 本身即 int8 有符号,原解释正确。
|
2026-10-14 15:12:19 +08:00 |
|
TermiNexus
|
a44f55574c
|
fix(vkernel): 鼠标“飞”与刷屏性能 —— 帧缓冲改回写映射 + 鼠标驱动丢弃溢出包/细化分辨率
方案 A(帧缓冲映射):
- 去掉帧缓冲的 PTE_PCD,改为回写映射。原先非缓存映射下每次写屏直通设备,大块刷新极慢;
QEMU 下回写显示正确(TCG 不模拟缓存不一致),真机严格正确应改 write-combining(PAT),
已在代码注释里写明。
- 说明:“只刷脏行”本已是现状(_mark_rows_dirty 按区域标脏,全屏刷仅启动那一次)。
方案 C(鼠标驱动加固,drivers/input/mouse/mouse.vp):
- irq_handler 丢弃带 X/Y overflow 位(bit6/bit7)的包:此时设备给的是饱和值,直接采用
会产生 ±127 级跳变,表现为光标“飞”。
- init 中在 0xF6(Set Defaults) 之后用 0xE8/0x03 把分辨率设为 8 counts/mm,避免默认最粗的
4 counts/mm 造成每计数位移偏大。
|
2026-10-14 15:05:02 +08:00 |
|
TermiNexus
|
73a499b0c1
|
feat(vkernel): 桌面线程每秒校验 .bss 帧参数不变量(fail-fast 抓 .bss 侧写坏)
与 main.vp 的帧参数影子校验互补:那边抓的是 __init__ 栈局部量在启动阶段被写坏,
这边抓的是 .bss 全局在被写坏后、使用前被拦下。
- _SetFrameInvariants():在 start() 完成全部 .bss 赋值后记录影子
(_fb/_screen_w/_screen_h/_fb_pitch/_back_fb/_row_buf/_bg_row_buf/_dirty_rows)
- _CheckFrameInvariants():桌面线程每秒比对一次,不一致即打印 [FATAL]
(左右并列显示 实际值/期望值)并停机
这样两类写坏都能在使用前变成可定位现场,而不是继续静默破坏(如把后备缓冲刷到物理 0 起)。
|
2026-10-14 14:57:59 +08:00 |
|
TermiNexus
|
c0c83cdc83
|
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](含期望值与实际值)并停机 —— 把“偶发写坏”变成可定位的现场,
并明确是哪一个阶段之间被写坏。
|
2026-10-14 14:56:26 +08:00 |
|
TermiNexus
|
9cf33ab374
|
fix(vkernel): _render 脏行行界由“夹取兜底”改为 fail-fast(越界即报错停机)
按“禁止兜底、改 fail-fast”的要求:_dirty_y_min/_dirty_y_max 是 .bss 全局,
被写坏时(曾观测 fb/pitch/w/h 被随机清零)原夹取会静默掩盖上游写坏源。
现改为越界立即打印 FATAL 并停机,直接暴露写坏。
合法的空脏行集合状态(_dirty_count==0、_dirty_y_max==-1、_dirty_y_min==h)已放行。
|
2026-10-14 14:55:40 +08:00 |
|
TermiNexus
|
b6cc64a5c9
|
chore(vkernel): 移除本轮排查加的全部临时诊断探针,并把 fb 为空改为 fail-fast
现象已定位清楚:fb=0 时刷新会把后备缓冲写到物理 0 起,覆盖 IVT/BDA + 低端内存 +
内核镜像自身(边跑边改坏自己正在执行的代码 → 卡死;宿主 QEMU abort 0x40000015)。
本轮实测 fb/pitch 正确时桌面渲染正常、[perf] 数值单调(.bss/中断那条线的修复生效)。
清理内容:
- main.vp:删除 _WhProbe 探针函数与 7 处调用、2 处 mm.DumpBuddy() 调用
- desktop.vp:删除 [rc] 阶段面包屑 7 处、[rc] preflush 转储、[dt] 每秒心跳、[dst] 入口探针
- mm.vp:删除已无调用点的 DumpBuddy()(保留 3 条 malloc 失败诊断——它们是错误信息,非调试噪音)
新增(fail-fast,替代静默兜底):
- desktop.start:fb_ptr == 0 时打印 FATAL 并停机,杜绝“刷新把内核自己写掉”这类灾难
- _render:脏行行界夹取保留(越界会静默写穿帧缓冲),但这是防破坏下限,非修复
|
2026-10-14 14:52:56 +08:00 |
|
TermiNexus
|
d58833d3b5
|
diag(vkernel): 增加 post_vga / pre_start 探针,夹出 fb/pitch 被清零的位置
[rc] preflush 显示 fb=0x0(帧缓冲指针为 NULL),[dst] entry 显示 pitch=0:
刷新循环把 8MB 后备缓冲写到物理 0x0 起 —— 覆盖 IVT/BDA + 低端内存 + 内核镜像自身
(0x100000 起),边跑边覆盖正在执行的代码 → 卡死;QEMU 因客户机跑飞
abort(0x40000015 = STATUS_FATAL_APP_EXIT)。
VGA 文本(315-317 行)用同一组 fb/pitch 画出来是正常的,说明清零发生在
317 行之后、323 行 desktop.start 之前。故加两条探针把元凶夹死:
_WhProbe("post_vga", uint32(fb), pitch) # 317 行后
_WhProbe("pre_start", uint32(fb), pitch) # 323 行前
若 post_vga 正常而 pre_start 为 0,元凶即这三条之一:
serial.puts("你好") / serial.puts("[main] starting desktop") / _WhProbe("pre_desktop")。
|
2026-10-14 14:47:53 +08:00 |
|
TermiNexus
|
0cee9612ae
|
diag(vkernel): 刷新循环前打印全部参与量(定向内存转储),定位跑飞来源
已给刷新/背景循环夹取行界,但现象不变(仍卡在 “[rc] vblank done” 之后、
没有 “[rc] flush done”)——说明跑飞的不是循环边界(_dirty_y_max),
而是循环体内的量:row_bytes/run_bytes 或指针,或 _dirty_rows 本身。
故在 _wait_vblank() 之后、刷新循环之前,一次性打印所有参与量:
dc dmin dmax w h pitch row_bytes
fb back dirty_rows row_buf bg_row_buf
任一异常即为被写坏的对象,且直接给出被写坏后的数值(量级)。
(这就是你说的“内存转储”的定向版:只打这块状态,编译快、迭代方便。)
|
2026-10-14 14:26:26 +08:00 |
|
TermiNexus
|
c9c507c67d
|
fix(vkernel): _render 的刷新/背景循环按屏幕高度夹取行界,避免脏行值被写坏时死循环越界写
面包屑定位:卡在 “[rc] vblank done” 与 “[rc] flush done” 之间 —— 即帧缓冲刷新循环。
_dirty_y_max 是 .bss 全局,一旦被写坏成很大的正数:
- 循环退化成死循环 → 卡死(故 [dt] 心跳一行都不打印);
- run_start*pitch 越写越远,写出 0x80000000 帧缓冲之外 → 落进 MMIO →
宿主 QEMU 被写崩(unknown software exception 0x40000015 = STATUS_FATAL_APP_EXIT),
且屏幕只留下顶部已写的那一小块。
两个循环(背景铺底 + 帧缓冲刷新)的行界现夹到 [0, h-1]。这不是根因修复
(.bss 仍被写坏),但:
- 止血:不再死循环、不再把宿主 QEMU 写崩;
- 兼作探针:[dt] 心跳里的 dymin/dymax 若明显越界,即可确认 .bss 被写坏的量级。
|
2026-10-14 14:18:21 +08:00 |
|
TermiNexus
|
cfbb0c1286
|
diag(vkernel): _render() 各阶段埋 [rc] 面包屑,定位卡死步骤
日志证据:本轮 [dt] 心跳一行都没打印 → 桌面线程没走到“每秒”分支,即卡在第一轮循环里;
而屏幕顶部出现一小块蓝色 → 很可能执行到第一次 _render() 中途卡住(写了一半)。
宿主 QEMU 随后 abort(0x40000015 = STATUS_FATAL_APP_EXIT)。
在 _render() 埋 6 个面包屑:
[rc] entry / bg done / taskbar done / windows done / cursor done / vblank done / flush done
最后打印的那条 = 卡住的那一步。若连 [rc] entry 都没有,则卡点在其之前
(_update_mouse / _update_keyboard / _heartbeat_check),再补那边。
定位后连同所有 [DIAG] 一并移除。
|
2026-10-14 14:13:10 +08:00 |
|
TermiNexus
|
164228e15a
|
diag(vkernel): 桌面线程每秒心跳,打印脏行/渲染/窗口/光标状态
现象:日志停在 “[desktop] thread started”,QEMU 卡死;屏幕只有上方一小块变蓝、
UEFI 文本未被覆盖 —— 指向渲染/刷新阶段的 _dirty_* 状态不正确(而非整屏写入卡住)。
在 desktop_thread 主循环的“每秒”分支打印:
[dt] sec=… dc=… dymin=… dymax=… rc=… win=… cx=… cy=…
作用:
- 若完全没有 [dt] 输出 → 线程在首轮之前就卡住(_mark_all_dirty 或循环顶部);
- 若有输出且 sec 递增 → 线程在跑,问题在渲染/刷新(dc/dymax 数值即可解释
“只刷顶部一小块”)。
定位后连同其它 [DIAG] 一并移除。
|
2026-10-14 14:08:56 +08:00 |
|
TermiNexus
|
3bb6a9a102
|
diag(vkernel): desktop.start 入口加形参探针(w/h/pitch 是否原样到达)
已排除/确认:
- main 的 __init__ 局部量正确(5 个 [wh] 探针全对,pre_desktop 仍为 1360/768);
- 调用点机器码正确(0x100A86: mov 0x10(%rsp),%esi = 1360);
- mm 模块 34 个函数全部合规(无“用到 callee-saved 却未 push”的函数)。
故在 desktop.start 入口打印收到的 w/h/pitch:
- 若此处已为 0 → 实参在调用/ABI 传递环节丢失;
- 若此处正常 → 丢失发生在函数内部(malloc/memset 之后,w 存于 ebx)。
据此继续定点,定位后连同所有 [DIAG] 一并移除。
|
2026-10-14 13:58:02 +08:00 |
|
TermiNexus
|
38ccc9cdf6
|
diag(vkernel): main __init__ 插 width/height 探针,定位局部槽被清零的阶段
“[desktop] dirty_rows/back_fb malloc FAILED”的实质是 width/height 被随机清零:
malloc(0) 直接返回 NULL;伙伴系统经 DumpBuddy 实测健康(free≈160MB,order 3/5..12/15 有块)。
ISR 不保存 rax/rcx/r8-r11 的问题已修(0c63969),但现象仍在 → 主线程栈另有写坏源。
在 __init__ 的 5 个阶段打印 w/h(decl → pre_pg → post_mm → pre_usb → pre_desktop),
二分出被写坏的区间;定位到具体调用后,连探针一起移除。
|
2026-10-14 13:50:48 +08:00 |
|
TermiNexus
|
66eb70b131
|
feat(vkernel): #GP 分支补 rbp 链回溯(与 #PF 分支同款)
#GP 此前只打印 rip/err/rsp/cr4/cr0,看不到调用链;#PF 与“其他异常”分支早已有
[STK] rbp 回溯。现给 #GP 补上同样的 5 级回溯(rbp + 4 个返回地址),
内核态 rbp 低地址直接回溯,用户态(>=0x80000000)跳过以免读用户栈嵌套 #PF。
用于定位当前 “paging.init 的 MakePTWritable 页表遍历读到坏表项 → #GP
rip=0x11a7be” 的调用来源。
|
2026-10-14 13:46:57 +08:00 |
|
TermiNexus
|
449f2dbc37
|
fix(mm): 加分配失败分步诊断;build.py 改用 --phase2command 产出 kernel.elf
- mm.vp: 在 malloc(slab 路径)、_create_page、allocate_block 三处失败分支各加一条
[mm] 诊断打印,用于定位“[desktop] dirty_rows malloc FAILED”
(768B → ≤SLAB_THRESHOLD → slab size class 5(1024B) → _create_page 需 order≥1 伙伴块;
DumpBuddy 显示伙伴空闲链健康,故需进一步区分是哪一步返回 NULL)
- build.py: kernel.elf 改为调用 viperc --phase2command 拿到“精确链接命令”再改写产出。
自行 glob .obj 去链会因对象顺序不同得到与 kernel.bin 不一致的段布局
(实测前 247KB 里 230KB 不同),无法把日志 rip 映射回函数。
|
2026-10-14 13:36:01 +08:00 |
|
TermiNexus
|
54e88ce957
|
feat(build): 额外链接带符号 kernel.elf;mm 增加 DumpBuddy 诊断
- build.py: 用同一批 .obj + 同一 linker.ld 再链一份
VKernel/__vpcbuild__/output/kernel.elf(仅去掉 --oformat binary/--strip-all),
段布局与 kernel.bin 一致 → 可把日志里的 rip 用 objdump/nm 映射回函数
- mm.vp: 新增 export DumpBuddy(),打印 arena start/end 与 total/used/free
及各阶空闲链表首块(上限 8 个),定位分配失败是“链表空”还是“块指针坏”
- main.vp: mm.init 之后、desktop.start 之前各调一次 DumpBuddy(),
用于排查“[desktop] dirty_rows malloc FAILED”
(768B → ≤SLAB_THRESHOLD → slab size class 5(1024B) → _create_page 需 order≥1 伙伴块)
|
2026-10-14 13:27:40 +08:00 |
|
TermiNexus
|
0c6396912b
|
fix(vkernel): ISR 保存/恢复 rax/rcx/r8-r11,修中断破坏被中断代码寄存器
根因:isr.s 的 ISR_NOERR/ISR_ERR 宏把 rax/rcx/r8-r11 当临时寄存器用
(读 RIP/CS/RFLAGS、算 is_user),却从未保存/恢复原值,rcx 更是根本不在
保存列表里。于是任意一次中断(定时器 1000Hz)只要落在“这些寄存器里存有
活跃值”的瞬间,就会破坏被中断代码的活跃值:
- r8 被写成被中断处的 RIP;rcx 被清 0(xor ecx,ecx / setnz cl 造 is_user)
实测吻合:DumpMapping 把 tag 放 rcx、va 放 r8,中断落点恰在其中 → 打印
“ [PG] (None) va=0x11ab82 ”,其中 0x11ab82 正是 DumpMapping 内部的 RIP;
同一机制把 main.vp 的 width 槽写成 0 → “ [desktop] back_fb malloc FAILED ”。
最初日志里的 [0D][GP] rip=0x130d45(vsnprintf 读 %d 变参)亦由此而来。
旧 TPC 编译的寄存器分配没踩到该窗口故“正常”,新版编译器踩到 → 概率性破坏
(对应 VKERNELERR.md 记录的“新版概率性崩溃”)。
- isr.s: 新增 ISR_SAVE_CLOBBERED / ISR_RESTORE_CLOBBERED 与 _isr_scratch;
入口第一件事保存 rax/rcx/r8-r11,各返回路径在 push 完 iretq 帧之后恢复
(iretq 从栈取帧,恢复寄存器不影响返回)
- mm.vp: arena 起点抬高后做 4KB 对齐(KernelEnd 未必页对齐),避免伙伴系统块错位
|
2026-10-14 13:06:26 +08:00 |
|
TermiNexus
|
0919a058a8
|
fix(vkernel): 预留内核 .bss 与栈区,修堆 arena 覆盖未预留内核内存
根因:bootloader 只按 kernel 文件大小 AllocatePages(.bss 不占文件),于是 .bss
尾部(ticks/_perf_* 等全局量)与主线程栈区(0x60000~0x80000)在 memmap 里仍是
EfiConventionalMemory,被内核 mm 的堆 arena 当作空闲内存占用 → 内核全局量被写坏、
堆元数据被反向破坏,最终桌面线程栈上的 va_list 被改坏,vsnprintf 读 %d 变参时
#GP(rip=0x130d45, err=0x0)。
- linker.ld: .bss 末尾加 LONG(0) 强制 PROGBITS,使 kernel.bin 的 FileSize 涵盖
.bss,bootloader 的 PagesNeeded 得以预留整块内核镜像(含 .bss)
- mm.init: 新增 KernelAddr/KernelEnd,挑 arena 时把与内核镜像 [kernel_PhysAddr,
__bss_end) 重叠的 region 起点抬到镜像末端(不整段丢弃)
- main.vp: 取 __bss_end 并传入 mm.init
- boot.c: ExitBootServices 前用 AllocatePages(AllocateAddress, EfiLoaderData)
占位内核栈区 0x60000~0x80000,使其在 memmap 中标记已用
另含在途整理:多处补显式收窄转换(uint8()/uint16() 等)、kbd_svc 构造改为
kbd_svc.__init__() 等。
|
2026-10-14 12:54:43 +08:00 |
|
TermiNexus
|
52728bc8da
|
refactor(gdt): setTSS64 改用 gdt_entry64 整体写入 TSS 描述符
以 gdt_entry64*(&gdt[num]) 复用同一地址写入 16 字节,替代原先手写拆分
gdt[num]/gdt[num+1] 的方式;语义与字节布局均不变。
|
2026-10-13 15:45:59 +08:00 |
|
TermiNexus
|
1c8d2e2c1d
|
fix(gdt): TSS64 描述符 granularity 编码 limit 高 4 位
原写法硬编码 0x00,丢弃 limit[19:16],当前 limit=103 侥幸正确,
改为 (limit >> 16) & 0x0F 以消除隐患。
|
2026-10-13 15:44:41 +08:00 |
|
TermiNexus
|
d093d3fc8b
|
chore: 改名同步 TransPyV -> ViperC(源码/配置内的纯替换)
|
2026-10-12 15:06:50 +08:00 |
|
TermiNexus
|
5b4bab59cc
|
chore(ViperOS): 合并落库内核侧在途改动并移除 vpsdk wiki 拷贝
VKernel / vpsdk / Apps / Libs 共 30 个源文件:内核与 SDK 侧的新语法适配及编译修正(含 bootinfo.vp / main.vp 位宽改 uint64、gfx.vp 前向引用改指针、devfs.vp 指针解引用赋值、elf.vp 跨模块函数取值等)。删除 vpsdk/wiki/*.md(14 文件,约 -8100 行):与仓库根 wiki 重复的拷贝,统一以根 wiki 为唯一来源。
|
2026-10-07 19:04:33 +08:00 |
|
TermiNexus
|
753512ecf7
|
refactor(elf): 因 match 改为硬关键字,重命名同名局部变量
- execrunner/elf.vp:局部变量 match 改名 Matched
|
2026-10-02 23:15:14 +08:00 |
|
TermiNexus
|
dcb7c5c2c0
|
chore(ViperOS): 落库内核侧进行中的改动(26 文件,+1573/-1805)
内容由用户产出,本次仅代为提交、未做任何语义修改;含 static 修饰符前置迁移等(新增 static 前缀 16 行)。提交消息为中性描述——如需更精确的说明请 amend。
|
2026-09-28 15:24:52 +08:00 |
|
TermiNexus
|
1c3fcd6e1e
|
fix(vkernel): 推进中断 IN 传输的 DATA0/DATA1 翻转位
ep_in_toggle 此前全仓无任何回写,TD token 的 toggle 位恒为 DATA0,DATA toggle 永不交替。在两个中断完成回调重新排程前回写翻转,使下一次中断 IN 使用另一 PID;init 首排保持 DATA0(SET_CONFIGURATION 后端点默认值)。
|
2026-09-27 15:10:39 +08:00 |
|
TermiNexus
|
5f5a119f06
|
fix(vkernel): schedule_int_transfer 的 toggle 形参改为值传递
schedule_int_transfer 第 6 形参原为 toggle_ptr: uint8*,却直接转发给 _td_set_token 的值形参 toggle: uint8,命中指针隐式转整数禁令(uhci.vp:160 CastError)。改为 toggle: uint8 值传递,四个调用点去掉取地址,buf 仍以 & 传。同时纳入工作区既有的指针语法迁移:t.CPtr 改 X*、c.Addr 改 &、c.Set(c.Deref(...)) 改 *p = v。
|
2026-09-27 15:05:37 +08:00 |
|
TermiNexus
|
2a54e2bafb
|
清理了 t.CVoid
|
2026-09-16 16:07:04 +08:00 |
|
TermiNexus
|
6a54373c26
|
fix(vkernel): 补 ISR/调度 call 的 rsi/rdi clobber、rep stosb 内存 clobber,修 mm 别名笔误
N8 paging.vp:AllocPage 的 rep stosb 写 4096B 补 CLOBBER_MEMORY,避免优化器
重排/消除其前后的内存读写
N9 coroutine.vp / sched.vp:_coro_entry/_thread_entry 的 call rax 补
CLOBBER_RSI/CLOBBER_RDI(RSP 由 sub rsp,8 / add rsp,8 配对抵消,无需声明)
N15 process.vp:mm_mm.malloc/free → mm.malloc/free(该文件只有 import mm.mm as mm)
N16 elf.vp:读 RAX 的 c.Asm 补 CLOBBER_RAX([DIAG] 探针)
N20 elf.vp / idt.vp(12 处):外部 ELF 入口 / ISR handler 的 call 补
CLOBBER_RSI/CLOBBER_RDI(被调方破坏全部 caller-saved 寄存器)
|
2026-09-11 17:40:21 +08:00 |
|
TermiNexus
|
c1dd55d606
|
fix(vkernel): 修 _tss.reserved0 位宽与 AP trampoline LME 指令编码
- N6 cpu.vp: _tss.reserved0 uint64→uint32, TSS 108B→104B, RSP0 归位偏移 4, 对齐 gdt.tss_buf
- N7 apic.vp: 置 LME 由 0x83 C8(imm8) 改 0x81 C8(imm32), 否则后 4 字节被当指令执行
|
2026-09-11 15:50:14 +08:00 |
|
TermiNexus
|
a518f75b24
|
chore(vkernel): 重置基线 — 纳入 TPV codegen 修复配合的内核侧调整与既有工作区内容
- devfs.vp: string.split 传 PATH_BUFFER_SIZE(配合 split 新增容量参数)
- fat32_types.vp: lfn_extract 越界钳制(base+i > MAX_LFN 返回 -1)
- sheet.vp: gfx.Renderer 实参修正为 (fb, zb, w, h)(原单参导致 w/h=0 渲染空操作)
- 同批包含 VKernel 其余既有移植改动与 vpsdk/Apps/Libs 工作区内容
|
2026-09-11 14:27:01 +08:00 |
|
TermiNexus
|
cd1cc915c5
|
修正了build.py,重置基线
|
2026-09-11 10:34:34 +08:00 |
|
TermiNexus
|
c6a4063015
|
revert: devfs find 恢复 for i in result(编译器已实现 NULL 终止遍历语义)
|
2026-08-30 08:37:39 +08:00 |
|
TermiNexus
|
3b522927bb
|
fix(kernel): devfs find 改 range(token) 遍历,修复全量遍历未初始化栈数组致 strcmp NULL 崩溃
|
2026-08-30 08:30:30 +08:00 |
|
TermiNexus
|
463a20017f
|
fix(kernel): save_pt_range 的 c.Set 改 c.Set(c.Deref(save_count)) 写所指地址而非指针变量
|
2026-08-30 07:44:40 +08:00 |
|
TermiNexus
|
333adb090f
|
fix(kernel): devfs last_slash/file_name 改用裸 str,修复 i8* 赋给 i8** 导致设备注册空名
|
2026-08-30 07:43:55 +08:00 |
|
TermiNexus
|
2a03330a9d
|
fix(kernel): 分裂 2MB 大页使 .rodata 真正只读,加页表与格式串校验诊断并禁用 App 自动启动
|
2026-08-30 07:27:45 +08:00 |
|
TermiNexus
|
efa99a8c4b
|
fix(kernel): [STK] 用户态 rbp 跳过链回溯(防嵌套 #PF 死循环)
用户进程异常时 rbp=0x7fffff...(用户栈),链回溯读 [rbp+8] 触发嵌套 #PF 无限循环(rsp 递减耗尽)。fr0>=0x80000000 时跳过链回溯。
|
2026-08-29 18:14:48 +08:00 |
|
TermiNexus
|
3a3d026f95
|
fix(debug): _fault_rax 改为 ISR 入口最早保存(避免被读 CS 覆盖)
ISR_ERR/NOERR 入口 mov rax,[rsp+16] 读 CS 已覆盖崩溃 rax,且内核路径 xor rax 后再 push——_fault_rax 恒 0。改为入口第一条 mov [_fault_rax],rax,删除 push 后冗余覆盖。
|
2026-08-29 18:06:03 +08:00 |
|
TermiNexus
|
25af08ecf4
|
debug(kernel): 保存并打印崩溃时 RAX(验证 cr2=rax-偏移 关系)
[STK] 显示崩溃帧 rbp=0x7d640 正常,但 cr2=0x0 需 rax=0x6f0——矛盾待解。isr.s 新增 _fault_rax,异常打印 [RAX] 行确认崩溃时 rax 真实值。
|
2026-08-29 18:00:13 +08:00 |
|
TermiNexus
|
084061f97e
|
debug(kernel): [STK] rbp 链回溯扩展到所有异常(含 #UD int 6)
本次崩溃为 int=6 rip=0x7bada(执行流跳栈地址),走 [EX] 分支未打印链。统一 [PF]/[EX] 均输出 [STK] rbp 链。
|
2026-08-29 17:53:40 +08:00 |
|
TermiNexus
|
a85f826adf
|
debug(kernel): #PF 打印 rbp 链回溯(崩溃帧 + 4 级返回地址)
devfs_directory.find 崩溃(cr2=0x0 写 NULL,rax=rsp=0x6f0 异常)说明调用链栈已被破坏。isr.s 新增 _fault_rbp 保存异常现场 rbp,idt.vp [PF] 分支打印 [STK] 链定位栈损坏源。
|
2026-08-29 17:50:32 +08:00 |
|
TermiNexus
|
b1956ea722
|
fix(kernel): paging.init 先清 WP 再 MakePTWritable 再置 WP(bootloader 已设 WP=1)
UEFI/bootloader 的 CR0.WP 已是 1(原代码清 WP 正因此),MakePTWritable 在 WP=1 下写只读页表页即 #PF(cr2=0xf8033e0)。改为:清 WP → 放开页表页 → 置 WP=1。
|
2026-08-29 17:42:34 +08:00 |
|
TermiNexus
|
56e38c43ea
|
fix(kernel): MakePTWritable 移到 WP=0 阶段执行,破除页表页递归只读死锁
在 WP=1 后改页表页自身会写只读页 → #PF(ProtectKernelRO 阶段 cr2=0xf8033e0)。改为 paging.init 里先 MakePTWritable(WP=0 允许写只读页)再置 WP,ProtectKernelRO 只保护 .rodata 内容页。
|
2026-08-29 17:41:03 +08:00 |
|
TermiNexus
|
4f729b20a3
|
fix(kernel): _set_page_writable 支持 2MB 大页(PD 条目直接置 W)
pml4 页(0xf801000)若经 2MB 大页映射,原实现遇 PS=1 直接 return 导致页表页仍只读,写 pml4.entries 持续 #PF。大页的 W 位在 PD 条目自身,直接置位即可。
|
2026-08-29 17:39:25 +08:00 |
|
TermiNexus
|
a92073851e
|
fix(kernel): 保护 .rodata 前先放开页表页可写(WP=1 暴露写页表 #PF)
CR0.WP=1 后暴露 bootloader 页表页(0xf8xxxx)只读的隐藏问题:MapPage 写 pml4.entries 触发 #PF(slog.so 映射 0x600000 新建页表项时 cr2=0xf801000 err=0x3)。MakePTWritable 遍历页表层次把 pml4/pdp/pd/pt 页表页自身设可写,.rodata 内容页仍只读保护。
|
2026-08-29 17:37:29 +08:00 |
|
TermiNexus
|
04ca2d4c5b
|
fix(kernel): .rodata 映射只读 + CR0.WP=1,越界写立即 #PF 暴露写源
此前清 WP + 页表全可写,越界写 .rodata 字符串常量静默破坏(格式串 %lu 变 %lc、路径/符号名损坏连锁 → work=+/eyboard/terminal.elf 加载失败)。ProtectKernelRO 经 c.Asm 引用 __rodata_start/__rodata_end 清 PTE_WRITABLE,配合 CR0.WP 置位,越界写触发 #PF 打印 cr2/rip。
|
2026-08-29 17:34:41 +08:00 |
|
TermiNexus
|
b887d3d9c2
|
更新,部分功能可用
|
2026-08-27 09:47:47 +08:00 |
|
TermiNexus
|
4296d2a19e
|
fix(asm-inline): cmos_read 裸 in/out al 补 CLOBBER_RAX + 显式 mov;rdmsr out 绑定与 clobber 冲突(lo/hi 读不到 EAX/EDX)改显式 mov——同类 EAX 破坏根因,残留间歇性数据损坏源
|
2026-08-27 01:33:19 +08:00 |
|
TermiNexus
|
f963fb16ad
|
debug(fat32): sfn_from_lfn 打印 dot_pos/i/ext_i 与生成的 sfn——Hello 生成 HELLO 空格(缺扩展名),定位 for-in 遍历/扩展名写入间歇性失败
|
2026-08-27 01:30:02 +08:00 |
|