Commit Graph
63 Commits
Author SHA1 Message Date
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
TermiNexus e49c74fb12 debug(fat32): handle_alloc 表满诊断加 handle_table 地址——定位 BSS 相邻越界写源 2026-08-27 01:27:38 +08:00
TermiNexus 8f15455784 debug(fat32): handle_alloc 表满时打印 handles_initialized 与前 4 个 handle 的 is_open——spawn scan open failed err=18(FR_TOO_MANY_OPEN_FILES) 2026-08-27 01:26:12 +08:00
TermiNexus 2b0d68d3fe debug(elf): read_len 后加 RAX 快照——fat32.read 打印 br=64 但 load_elf 收到 rl=0,区分 call 返回错 vs store 后被覆盖 2026-08-27 01:24:26 +08:00
TermiNexus f6154bfed3 debug(fat32): dir_find 打印 sfn_from_lfn 生成的 11 字节 hex——hello.elf 的 sfn 显示为 H(sfn[1]=0x00),定位 sfn 生成被破坏 2026-08-27 01:21:15 +08:00
TermiNexus f8ad5b7176 debug(paging): init_pool 打印 pt_pool_raw/pt_pool_start——clone 时 raw=0x0,区分 init 收到 0 还是 init 后被覆盖 2026-08-27 01:19:04 +08:00
TermiNexus 364daa111b debug(fat32,elf): win_read 打印 abs_sector/hidden_sectors/win 前4字节(win[0..1] 被清零);not x86_64 分支 dump ehdr 前20字节(read_len=64 但内容错) 2026-08-27 01:11:05 +08:00
TermiNexus d0b512f159 debug(elf,main): 打印 read_len 与 spawn_elf 返回 pid 实际值——fat32.read 内部 br=64 但 load_elf 收到 <64、spawn ret pid=1 但 main 收到 0,定位跨模块返回值间歇性丢失 2026-08-27 01:08:37 +08:00
TermiNexus a621b0d264 debug(paging,process,fat32): 定位 BSS 全局内存破坏——clone AllocPage 失败打印 pt_pool_raw/pt_pool_used,create_process malloc 返回实际值(mm 成功但调用方收 None),dir_find 失败 dump win 缓冲内容 2026-08-27 01:02:39 +08:00
TermiNexus 42312a39b1 fix(desktop): mm.malloc 显式 CUInt64T 参数规避裸名回退 i32 参数(bg_row_buf 收到 0x0);fat32 dir_get_entry_info 加 win 缓冲内容诊断(根目录显示 (None) size=523360、dir_find offset=0 失败疑似 win 污染) 2026-08-27 00:55:54 +08:00
TermiNexus 038b0a428e fix(ide,elf): 移除每次读扇区前的 0x3F6 SRST 软复位写(Gargantua 大数据段读取中途 waitDataReady 失败根因);spawn_elf 用指针算术替代 path[name_start:] 切片传参并加 entry/pid 运行时诊断 2026-08-27 00:45:23 +08:00
TermiNexus 25d2628cd4 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 诊断 2026-08-27 00:32:54 +08:00
TermiNexus 3418bc6a59 fix(fat32): c.Set 写指针误用值赋值,改为 c.Set(c.Deref(ptr),val)——read/write 的 br/bw、dir_sector_out、ioctl 扇区参数从未写入导致 ehdr 读取返回0 2026-08-27 00:20:27 +08:00
TermiNexus c0685fe6bd debug(fat32): read 包装打印 br 实际值,确认 c.Set 是否写入(types 内 total_read=64 但 read_len<64) 2026-08-27 00:12:46 +08:00
TermiNexus 51c7475031 debug(fat32): read 打印文件状态(size/first_cluster/pos)与实际读取字节数,定位 ehdr 读取失败根因 2026-08-27 00:08:52 +08:00
TermiNexus a8f7c0b0b3 debug(sched): create_thread 打印 tid/func/stack 实际值,定位线程首次调度跳栈 #UD(rip 在栈区域)根因 2026-08-26 23:30:28 +08:00
TermiNexus 4c25e0e35c debug(desktop,uhci): malloc 判空失败处打印实际返回值,定位 mm.malloc 返回值与调用方接收不一致 2026-08-26 23:25:15 +08:00
TermiNexus cdee5e0e87 debug(idt): 非 #GP/#PF 异常打印 rip/rsp,定位 tid=1 #UD 执行位置 2026-08-26 22:22:56 +08:00
TermiNexus 61208676c6 fix(main): _start 加 stackrealign,修复变参函数 movaps #GP
根因链:_start 由 bootloader jmp 进入(rsp≡0 mod 16),编译器/llc 按 call
约定对齐函数帧(假设入口 rsp≡8 mod 16)→ 帧整体偏 8 → _start 内所有调用
rsp≡8 mod 16 → __init__ 的 float 变参调用(snprintf %.2f 保存 xmm)movaps
#GP(cr4.OSFXSR 已启用、地址 16 对齐仍 #GP 正是此因)。

加 t.attr.stackrealign 使 _start 序言动态重对齐栈,与入口约定无关。
2026-08-26 20:18:09 +08:00
TermiNexus ff802c2eed debug(intr): #GP 打印 CR0/CR4
movaps 地址 0x7d780 16 对齐仍 #GP——需确认 SSE 是否真启用(CR4.OSFXSR bit9)
与 CR0.EM(bit2)。若 OSFXSR=0 则 enable_sse 未生效(可能是 stub 解析问题)。
2026-08-26 19:40:13 +08:00
TermiNexus 7b084803f5 fix(cpu): 启动早期启用 SSE/FPU,修复 movaps #GP
faulting RSP=0x7d760 16 对齐证明非栈对齐问题,movaps #GP(err=0) 真因是 CR4.OSFXSR 未置位(SSE 未启用)。OVMF 启动后 SSE 默认关闭,变参函数传 float/double 保存 xmm 寄存器时触发。新增 cpu.enable_sse(CR0 清 EM 置 MP + CR4 OSFXSR|OSXMMEXCPT + fninit),main.vp __init__ 开头调用。
2026-08-26 19:36:50 +08:00
TermiNexus 4ff48efde9 debug(intr): #GP/#PF 打印 faulting RSP
memmap 修复后栈写 #PF 消失,但 sched started 后出现 [GP] rip=0x134e1b
err=0x0——0x134e1b 是 serial.printf(变参)序言的 movaps(SSE 对齐存储),
说明调用方 RSP 未对齐。isr.s 新增 _fault_rsp 捕获(ISR_ERR 宏保存 faulting
RSP),idt.vp #GP/#PF 打印 rsp=0x%lx,定位 RSP 偏差来源。
2026-08-26 19:34:01 +08:00
TermiNexus 530c85d6a4 fix(main): 移除 BootInfo 局部重声明,修复 memmap 全 0
根因:BootInfo: t.CPtr = self.BootInfo(函数内注解重声明全局名)触发编译器
bug——局部 alloca 创建但从不写入(赋值落全局 @BootInfo),后续 BootInfo.X 读
未初始化局部 → 全 0 → mm.init 收 addr=0/size=0/desc=0 → 走 CMOS fallback →
读到 0xFF → size≈4GB → buddy 分配假内存 → 线程栈 4GB → #PF PANIC。

BootInfo 原始字节转储证实 bootloader 传参正确(mmap=0xde20d60 size=4800
desc=48 fb=0x80000000),纯内核读错。直接使用 global BootInfo 修复。

编译器 bug(注解局部重声明全局名赋值落全局)待 TransPyV 单独修复。
2026-08-26 19:26:50 +08:00
TermiNexus 87d4e359d8 debug(main): 转储 BootInfo 地址处原始 88 字节
BootInfo=0xde20d00 非 NULL 但字段全 0。转储该地址原始字节,区分内存确实全 0
(bootloader 写入未生效/重定位缺失)还是内核读错偏移(布局不匹配)。
2026-08-26 19:23:30 +08:00
TermiNexus 963e0ed53f debug(main): 打印 BootInfo 指针与 memmap 原始字段
mm.init 收到 addr=0 size=0 desc=0(全部为 0),可能是全局 BootInfo 为 NULL
(读物理 0-24 全 0)或 bootloader 传参异常。mm.init 前打印 BootInfo 指针
本身与 MemmapAddr/MemmapSize/MemmapDescSize/framebuffer_addr 原始值。
2026-08-26 19:17:58 +08:00
TermiNexus d4200f1129 debug(mm): 无条件打印 memmap 三参数 + fallback CMOS 原始值
serial.log 显示 memmap 分支(d[..] 转储 / mm: best=)从未打印 → 分支未执行,
size≈4GB 来自 fallback 的 detect_memory_size()(CMOS 读到垃圾)。加两处诊断:
1) init 开头无条件打印 MemmapAddr/MemmapSize/MemmapDescSize;
2) fallback 打印 CMOS 0x15-0x18 与 detect_memory_size 结果。
2026-08-26 19:11:22 +08:00
TermiNexus 1043343b9d fix(mm): get_block_size 移位改 64 位,修复伙伴初始化无限循环
4096<<20 在 i32 下溢出为 0x0 → bs=0x0 → cur_addr/remaining 不变 → 无限循环
([mm] it=1..6 order=20 bs=0x0 addr 不变)。改 t.CUInt64T 移位。另增关键数值
打印(memmap addr/size/desc/entries),配合描述符转储定位 4GB 伪可用区。
2026-08-26 19:04:55 +08:00
TermiNexus f9ec205816 debug(mm): 转储 memmap 描述符 + buddy 初始化循环进度
mm.init 报 start=0x400000 size=4292411392(≈4GB)后挂起——256MB 内存不该有
4GB 可用区,怀疑 memmap 描述符读到垃圾。新增:1) init 内转储全部描述符
(type/start/pages);2) buddy __init__ 循环打印前 6 次迭代与 loop done 标记,
定位挂起点。
2026-08-26 19:02:40 +08:00
TermiNexus 3995cb9545 debug(timer): 门32读回+软int0x20+PIC ISR,一次性区分中断分发路径
LAPIC 配置已确认正常(base/ver/svr/lint0 全部读回正确)但硬件中断仍不达。
新增三段诊断:1) 读回 IDT 门 32 的 base/sel/type;2) 软件 int 0x20 验证
分发路径(门有效→H+返回,门无效→[GP] err=0x20);3) 读 PIC1 ISR 确认
PIT IRQ0 是否真正到达 PIC 并被响应。
2026-08-26 18:42:58 +08:00
TermiNexus ee329c313f fix(apic): early_init 改用 IA32_APIC_BASE EN 位判断,避免 cpuid 误判跳过 init
lint0 读回 0x0(QEMU 复位默认 0x10000)说明此前读的是 RAM,_lapic_base 为 0,
init() 很可能未执行。msr_read 已在前置流程验证可用,改按 MSR bit11 判断更可靠。
main.vp 增补综合诊断:打印 base/version/svr/lint0 重写读回/特性位,一次性区分
init 未执行、MMIO 映射失效、写不粘三种假设。
2026-08-26 18:39:07 +08:00
TermiNexus 9ff53aa1fa debug(apic): 读回 LINT0 与 APIC BASE MSR,验证 EXTINT 配置是否生效
PIT 正常(cnt=1109)但中断不送达。读回验证:
- lint0=0x700 → EXTINT 未屏蔽(正确);0x10700 → 被屏蔽;其它 → 写入失败
- apic_base_msr bit11 → APIC 使能状态
用后移除。
2026-08-26 18:32:21 +08:00
TermiNexus 471cfa16bf debug(timer): timer_init 读 PIT 计数器,验证 PIT 是否在走
中断仍不送达 timer_handler(无 H)。读 PIT 计数器(latch+读 0x40)打印:
- 计数在 1~1193 之间变化 → PIT 正常,问题在中断送达(PIC/APIC/IDT)
- 计数为 0/不变 → PIT 本身没跑(outb 未生效/环境问题)
用后移除。
2026-08-26 18:29:20 +08:00
TermiNexus 57c4092d19 debug(timer): timer_handler 一次性 H + msleep 自旋 s,判定 ISR 是否被调用
apic.eoi 修复后仍挂在 sti done(无 msleep done)。加两处确定性诊断:
- timer_handler 首次进入打印 'H':ISR 被调用则出现
- msleep 每 1M 次迭代打印 's':hlt 唤醒(中断触发)但 ticks 不推进则出现
判定:
- 无 H → 定时中断未到达 timer_handler(IDT/PIC/APIC 路由)
- 有 H → ISR 已调用,问题在 handler/ticks 推进
用后移除。
2026-08-26 18:26:34 +08:00
TermiNexus 9082056fe0 fix(timer): timer_handler 补 LAPIC EOI,修复 APIC 启用后定时中断被屏蔽
APIC 启用后(LINT0=EXTINT 送达),每次中断会置 LAPIC ISR,必须写
LAPIC_EOI(0x0B0) 清除。此前只发 PIC EOI(0x20/0xA0),LAPIC ISR 卡住 →
首个定时中断后后续中断全被屏蔽 → ticks 不推进 → timer_msleep 永久挂起
(清理诊断后稳定复现,serial.log 停在 "sti done" 无 "msleep done")。
两个分支(timer_running 早退 + 正常路径)都补 apic.eoi()。
2026-08-26 18:23:16 +08:00
TermiNexus f675540c64 chore(boot): 移除全部中断排查诊断(int20 测试 + T/[T]/D 打印)
定时中断已确认恢复(APIC LINT0=EXTINT)。移除 int 0x20 软件触发测试与
isr32_handler 'T'、timer_handler '[T]'、isr_default 'D' 打印,回归干净
内核,定位 sti 后新出现的 #GP(疑似 int 0x20 测试触发)。
2026-08-26 18:19:41 +08:00
TermiNexus 3c163a5936 debug(boot): sti 后软件触发 int 0x20,二分定位中断不送达
APIC LINT0=EXTINT 已配置但仍无定时中断。加 int 0x20(向量 32)软件触发:
- 有 T → IDT gate 32 正常,问题在 PIT/PIC 硬件送达
- 无 T → IDT/lidt 问题
用后移除。
2026-08-26 18:16:09 +08:00
TermiNexus 9ec3627a5a fix(boot): 启用 apic.early_init,配置 LINT0=EXTINT 恢复 PIC 定时中断
QEMU/OVMF(UEFI)下本地 APIC 已启用,PIC 外部中断须经 LAPIC LINT0 送达
CPU。apic.init() 将 LINT0 配为 EXTINT(取消屏蔽);此前 early_init 被注释,
LINT0 保持未配置/屏蔽 → 定时器中断被 APIC 吞掉 → sti 后 timer_msleep 等
不到 ticks 永远挂死(serial.log 停在 "sti done",T/D 诊断均无输出)。
2026-08-26 18:14:29 +08:00
TermiNexus 10857e58ed debug(intr): isr32_handler 入口打印 T + isr_default 打印 D,定位定时中断丢失
前一轮 timer_handler [T] 未打印 → timer_handler 未被调用。本轮加两处
确定性诊断:isr32_handler 入口 'T'(IRQ0 是否到达 isr32)、isr_default
'D'(是否有中断向量到默认处理)。三种结果:
- 无输出 → 定时中断根本没触发(PIC/PIT/APIC 路由问题)
- D 输出 → 中断触发但向量到默认处理(IDT gate 未设置)
- T 输出 → IRQ0 到达 isr32(问题在 handler 内)
用后移除。
2026-08-26 18:11:47 +08:00
TermiNexus 7336ddff48 debug(timer): timer_handler 每 250 拍打印 [T],验证定时器中断触发
sti 后卡死在 timer_msleep,静态分析 PIT/PIC/IDT/ISR/timer_handler/
msleep/sched_tick 的 IR 全部正确。加串口诊断确认 ISR 是否触发:
若串口无 [T] → 中断未触发(PIC/PIT/IDT 运行期问题);有 [T] 仍挂 →
ticks 未推进/ISR 未返回。用后移除。
2026-08-26 18:07:47 +08:00
TermiNexus 8b40203b63 提交新的建议忽略 2026-08-06 18:08:50 +08:00
TermiNexus be92f671d0 根据静态注解修正了部分的 global 修正(遍历截止fat32 fileio.vp) 2026-07-31 13:36:26 +08:00
TermiNexus 9d786dd5b1 self 传参的相关修复 2026-07-30 17:30:47 +08:00
TermiNexus 49d074e487 通过插件的静态推导修复了一些错误 2026-07-30 17:28:27 +08:00
TermiNexus 065fcbdf43 调整了 VKernel 的版本 2026-07-30 17:26:17 +08:00
TermiNexus 56d127cb88 将 project.json 改为了 project.vpj,初步尝试了使用 Viper 插件高亮 2026-07-30 17:24:35 +08:00
TermiNexus 20e7289c61 将 .py 和 .pyi 后缀名改为了 .vp 和 .vpi 后缀名 2026-07-30 16:34:26 +08:00