From cd1cc915c59d66afbbdd36ef13ea1cafc0248553 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Fri, 11 Sep 2026 10:34:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=BA=86build.py=EF=BC=8C?= =?UTF-8?q?=E9=87=8D=E7=BD=AE=E5=9F=BA=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Apps/Gargantua/project.vpj | 2 +- Apps/HelloWorld/project.vpj | 2 +- Apps/Scene3D/project.vpj | 2 +- Apps/Terminal/project.vpj | 2 +- Libs/SerialLogger/project.vpj | 2 +- Libs/VPUI64/project.vpj | 2 +- VKernel/Kernel/drivers/core/cpu/apic.vp | 14 +++++------ VKernel/Kernel/drivers/devfs/devfs.vp | 12 +++++++++ .../Kernel/drivers/input/keyboard/keyboard.vp | 4 ++- VKernel/Kernel/drivers/input/mouse/mouse.vp | 4 ++- VKernel/Kernel/drivers/serial/uart/serial.vp | 6 +++++ VKernel/Kernel/drivers/usb/hid/usb_kbd.vp | 4 +-- VKernel/Kernel/drivers/usb/hid/usb_mouse.vp | 4 +-- VKernel/Kernel/drivers/usb/uhci.vp | 6 ++--- VKernel/Kernel/intr/idt.vp | 25 +++++++++++++++++-- VKernel/Kernel/intr/syscall.vp | 2 +- VKernel/Kernel/main.vp | 18 ++++++------- VKernel/Kernel/mm/mm.vp | 16 ++++++------ VKernel/Kernel/paging/paging.vp | 8 +++++- VKernel/Kernel/sched/sched.vp | 6 ++++- VKernel/Kernel/services/desktop.vp | 10 ++++---- VKernel/project.vpj | 2 +- build.py | 14 +++++------ vpsdk/stdio.vp | 9 +++++++ 24 files changed, 119 insertions(+), 57 deletions(-) diff --git a/Apps/Gargantua/project.vpj b/Apps/Gargantua/project.vpj index 547f8db..767d2c5 100644 --- a/Apps/Gargantua/project.vpj +++ b/Apps/Gargantua/project.vpj @@ -17,7 +17,7 @@ ], "output": "gargantua.elf" }, - "includes": ["../..", "../../../includes"], + "includes": ["../..", "../../../../includes"], "target": { "triple": "x86_64-none-elf", "datalayout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" diff --git a/Apps/HelloWorld/project.vpj b/Apps/HelloWorld/project.vpj index 8d46676..4514794 100644 --- a/Apps/HelloWorld/project.vpj +++ b/Apps/HelloWorld/project.vpj @@ -17,7 +17,7 @@ ], "output": "helloworld.elf" }, - "includes": ["../..", "../../../includes"], + "includes": ["../..", "../../../../includes"], "target": { "triple": "x86_64-none-elf", "datalayout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" diff --git a/Apps/Scene3D/project.vpj b/Apps/Scene3D/project.vpj index d2b30b7..be315b6 100644 --- a/Apps/Scene3D/project.vpj +++ b/Apps/Scene3D/project.vpj @@ -17,7 +17,7 @@ ], "output": "scene3d.elf" }, - "includes": ["../..", "../../../includes"], + "includes": ["../..", "../../../../includes"], "target": { "triple": "x86_64-none-elf", "datalayout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" diff --git a/Apps/Terminal/project.vpj b/Apps/Terminal/project.vpj index 711cdc5..113bf2d 100644 --- a/Apps/Terminal/project.vpj +++ b/Apps/Terminal/project.vpj @@ -17,7 +17,7 @@ ], "output": "terminal.elf" }, - "includes": ["../..", "../../../includes"], + "includes": ["../..", "../../../../includes"], "target": { "triple": "x86_64-none-elf", "datalayout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" diff --git a/Libs/SerialLogger/project.vpj b/Libs/SerialLogger/project.vpj index 4ac3e7c..e5cd696 100644 --- a/Libs/SerialLogger/project.vpj +++ b/Libs/SerialLogger/project.vpj @@ -20,7 +20,7 @@ ], "output": "slog.so" }, - "includes": ["../..", "../../../includes"], + "includes": ["../..", "../../../../includes"], "target": { "triple": "x86_64-none-elf", "datalayout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" diff --git a/Libs/VPUI64/project.vpj b/Libs/VPUI64/project.vpj index 9027b84..37a6b5c 100644 --- a/Libs/VPUI64/project.vpj +++ b/Libs/VPUI64/project.vpj @@ -20,7 +20,7 @@ ], "output": "vpui64.so" }, - "includes": ["../..", "../../../includes"], + "includes": ["../..", "../../../../includes"], "target": { "triple": "x86_64-none-elf", "datalayout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" diff --git a/VKernel/Kernel/drivers/core/cpu/apic.vp b/VKernel/Kernel/drivers/core/cpu/apic.vp index 3e872b5..d4ce7bd 100644 --- a/VKernel/Kernel/drivers/core/cpu/apic.vp +++ b/VKernel/Kernel/drivers/core/cpu/apic.vp @@ -9,9 +9,9 @@ import viperlib import t, c -IA32_APIC_BASE: t.CDefine = 0x1B +IA32_APIC_BASE: t.CDefine = 0x1B APIC_BASE_MSR_ENABLE: t.CDefine = 0x800 -APIC_BASE_ADDR_MASK: t.CDefine = 0xFFFFF000 +APIC_BASE_ADDR_MASK: t.CDefine = 0xFFFFF000 LAPIC_ID: t.CDefine = 0x020 LAPIC_VERSION: t.CDefine = 0x030 @@ -45,10 +45,10 @@ LAPIC_ICR_LEVEL: t.CDefine = 0x8000 MAX_CPUS: t.CDefine = 8 AP_TRAMPOLINE_ADDR: t.CDefine = 0x7000 -_lapic_base: t.CStatic | t.CUInt64T = 0 -_cpu_count: t.CStatic | t.CUInt32T = 1 -_bsp_lapic_id: t.CStatic | t.CUInt32T = 0 -_ap_ready: t.CStatic | t.CUInt32T = 0 +_lapic_base: t.CUInt64T = 0 +_cpu_count: t.CUInt32T = 1 +_bsp_lapic_id: t.CUInt32T = 0 +_ap_ready: t.CUInt32T = 0 def read(offset: t.CUInt32T) -> t.CUInt32T: addr: t.CUInt64T = _lapic_base + t.CUInt64T(offset) @@ -125,7 +125,7 @@ def ap_entry(): asm.sti() asm.hlt() -_trampoline_bin: t.CStatic | t.CArray[t.CUInt8T, 128] = [ +_trampoline_bin: t.CArray[t.CUInt8T, 128] = [ 0xFA, # cli 0x31, 0xC0, # xor ax, ax 0x8E, 0xD8, # mov ds, ax diff --git a/VKernel/Kernel/drivers/devfs/devfs.vp b/VKernel/Kernel/drivers/devfs/devfs.vp index 922ebd6..8797f33 100644 --- a/VKernel/Kernel/drivers/devfs/devfs.vp +++ b/VKernel/Kernel/drivers/devfs/devfs.vp @@ -1,5 +1,6 @@ import drivers.serial.uart.serial as serial import viperstring as string +import viperlib import t, c @@ -234,6 +235,10 @@ class _DevFSObject: if file_count >= MAX_DEVICE_FILES: return -1 if file_ptr: + # [DIAG] 定位 register 阶段 strcpy 目标:打印 file_ptr(用后移除) + _dbg3: t.CArray[t.CChar, 80] + viperlib.snprintf(c.Addr(_dbg3), 80, "[cf] fp=%lx\n", t.CUInt64T(file_ptr)) + serial.puts(c.Addr(_dbg3)) string.strcpy(file_ptr.name, file_name) file_ptr.private_data = private_data file_ptr.parent_dir = dir_ptr @@ -266,6 +271,13 @@ class _DevFSObject: file_ptr: devfs_file | t.CPtr = devfs_file.find_in_dir(file_name, dir_ptr) if not file_ptr: return -1 + # [DIAG] 定位 vtable 悬垂:打印 file_ptr 与对象首字段(vtable 指针)(用后移除) + _dbg_buf: t.CArray[t.CChar, 96] + _dbg_vt: t.CUInt64T = t.CUInt64T(file_ptr, t.CPtr)[0] + viperlib.snprintf(c.Addr(_dbg_buf), 96, "[open] fp=%lx vt=%lx\n", + t.CUInt64T(file_ptr), _dbg_vt) + serial.puts(c.Addr(_dbg_buf)) + fd: t.CInt = -1 for i in range(MAX_FILE_DESCRIPTORS): if not fd_table[i].file: diff --git a/VKernel/Kernel/drivers/input/keyboard/keyboard.vp b/VKernel/Kernel/drivers/input/keyboard/keyboard.vp index fce1039..d44823d 100644 --- a/VKernel/Kernel/drivers/input/keyboard/keyboard.vp +++ b/VKernel/Kernel/drivers/input/keyboard/keyboard.vp @@ -17,6 +17,7 @@ buffer: t.CArray[t.CUInt8T, KBD_BUF_SIZE] buf_head: t.CStatic | t.CUInt32T = 0 buf_tail: t.CStatic | t.CUInt32T = 0 buf_count: t.CStatic | t.CUInt32T = 0 +kbd_irq_cnt: t.CStatic | t.CUInt64T = 0 shift_l: t.CStatic | t.CUInt8T = 0 shift_r: t.CStatic | t.CUInt8T = 0 @@ -61,7 +62,8 @@ def _wait_write(): timeout -= 1 def irq_handler() -> t.CInt: - global buf_head, buf_tail, buf_count + global buf_head, buf_tail, buf_count, kbd_irq_cnt + kbd_irq_cnt += 1 scancode: t.CUInt8T = asm.inb(KBD_DATA) if buf_count < KBD_BUF_SIZE: buffer[buf_tail] = scancode diff --git a/VKernel/Kernel/drivers/input/mouse/mouse.vp b/VKernel/Kernel/drivers/input/mouse/mouse.vp index aee483f..7adf140 100644 --- a/VKernel/Kernel/drivers/input/mouse/mouse.vp +++ b/VKernel/Kernel/drivers/input/mouse/mouse.vp @@ -25,6 +25,7 @@ packets: t.CArray[mouse_packet, MOUSE_BUF_SIZE] pack_head: t.CStatic | t.CUInt32T = 0 pack_tail: t.CStatic | t.CUInt32T = 0 pack_count: t.CStatic | t.CUInt32T = 0 +mse_irq_cnt: t.CStatic | t.CUInt64T = 0 cycle: t.CStatic | t.CUInt8T = 0 byte1: t.CStatic | t.CUInt8T = 0 @@ -56,7 +57,8 @@ def _write_cmd(cmd: t.CUInt8T): asm.inb(MOUSE_DATA) def irq_handler() -> t.CInt: - global cycle, byte1, byte2, byte3, pack_tail, pack_count + global cycle, byte1, byte2, byte3, pack_tail, pack_count, mse_irq_cnt + mse_irq_cnt += 1 status: t.CUInt8T = asm.inb(MOUSE_STATUS) if (status & 0x20) == 0: return 0 data: t.CUInt8T = asm.inb(MOUSE_DATA) diff --git a/VKernel/Kernel/drivers/serial/uart/serial.vp b/VKernel/Kernel/drivers/serial/uart/serial.vp index e000fd3..c553e0b 100644 --- a/VKernel/Kernel/drivers/serial/uart/serial.vp +++ b/VKernel/Kernel/drivers/serial/uart/serial.vp @@ -60,6 +60,12 @@ def printf(fmt: t.CConst | str, *args) -> t.CInt | t.CExport: return n +# 刷新输出流:串口是无缓冲直写(putchar 直接写 UART 端口),flush 即空操作。 +# 覆盖 libc fflush 的裸机缺失(memhub 的诊断/终止路径 call @fflush)。 +def fflush(stream: t.CConst | t.CVoid | t.CPtr) -> t.CInt | t.CExport: + return 0 + + # 系统退出:触发硬件关机(QEMU ACPI/Bochs 关机端口),失败则停机兜底。 # 覆盖 libc exit 的裸机缺失(memhub 等致命错误路径 call @exit)。 def exit(status: int) -> t.CInt | t.CExport: diff --git a/VKernel/Kernel/drivers/usb/hid/usb_kbd.vp b/VKernel/Kernel/drivers/usb/hid/usb_kbd.vp index 0c953fc..10daad7 100644 --- a/VKernel/Kernel/drivers/usb/hid/usb_kbd.vp +++ b/VKernel/Kernel/drivers/usb/hid/usb_kbd.vp @@ -40,7 +40,7 @@ def init() -> t.CInt: serial.puts("[usb_kbd] register callback failed\n") kbd_initialized = 0 return -3 - uhci.schedule_int_transfer(kbd_slot_id, dev.addr, dev.ep_in, dev.ls, t.CUInt8T(dev.ep_in_max), dev.ep_in_toggle, c.Addr(kbd_report)) + uhci.schedule_int_transfer(kbd_slot_id, dev.addr, dev.ep_in, dev.ls, t.CUInt8T(dev.ep_in_max), c.Addr(dev.ep_in_toggle), c.Addr(kbd_report)) return 0 def _on_int_complete() -> t.CInt: @@ -86,7 +86,7 @@ def _on_int_complete() -> t.CInt: kbd_prev_keycodes[i] = kbd_report.keycode[i] dev: usb.usb_device | t.CPtr = kbd_dev if dev is not None and kbd_slot_id >= 0: - uhci.schedule_int_transfer(kbd_slot_id, dev.addr, dev.ep_in, dev.ls, t.CUInt8T(dev.ep_in_max), dev.ep_in_toggle, c.Addr(kbd_report)) + uhci.schedule_int_transfer(kbd_slot_id, dev.addr, dev.ep_in, dev.ls, t.CUInt8T(dev.ep_in_max), c.Addr(dev.ep_in_toggle), c.Addr(kbd_report)) return 0 def has_data() -> t.CInt: diff --git a/VKernel/Kernel/drivers/usb/hid/usb_mouse.vp b/VKernel/Kernel/drivers/usb/hid/usb_mouse.vp index 96fdd49..500dfda 100644 --- a/VKernel/Kernel/drivers/usb/hid/usb_mouse.vp +++ b/VKernel/Kernel/drivers/usb/hid/usb_mouse.vp @@ -38,7 +38,7 @@ def init() -> t.CInt: serial.puts("[usb_mse] register callback failed\n") mse_initialized = 0 return -3 - uhci.schedule_int_transfer(mse_slot_id, dev.addr, dev.ep_in, dev.ls, t.CUInt8T(dev.ep_in_max), dev.ep_in_toggle, c.Addr(mse_report)) + uhci.schedule_int_transfer(mse_slot_id, dev.addr, dev.ep_in, dev.ls, t.CUInt8T(dev.ep_in_max), c.Addr(dev.ep_in_toggle), c.Addr(mse_report)) return 0 def _on_int_complete() -> t.CInt: @@ -56,7 +56,7 @@ def _on_int_complete() -> t.CInt: mse_buf_count += 1 dev: usb.usb_device | t.CPtr = mse_dev if dev is not None and mse_slot_id >= 0: - uhci.schedule_int_transfer(mse_slot_id, dev.addr, dev.ep_in, dev.ls, t.CUInt8T(dev.ep_in_max), dev.ep_in_toggle, c.Addr(mse_report)) + uhci.schedule_int_transfer(mse_slot_id, dev.addr, dev.ep_in, dev.ls, t.CUInt8T(dev.ep_in_max), c.Addr(dev.ep_in_toggle), c.Addr(mse_report)) return 0 def has_data() -> t.CInt: diff --git a/VKernel/Kernel/drivers/usb/uhci.vp b/VKernel/Kernel/drivers/usb/uhci.vp index 298d2bc..d518c3d 100644 --- a/VKernel/Kernel/drivers/usb/uhci.vp +++ b/VKernel/Kernel/drivers/usb/uhci.vp @@ -386,7 +386,7 @@ def control_transfer(dev_addr: t.CUInt8T, endpoint: t.CUInt8T, ls: t.CInt, max_p setup_td.buffer = t.CUInt32T(t.CUInt64T(setup_buf)) if data_len > 0: - data_td: uhci_td | t.CPtr = t.CUInt64T(tds) + uhci_td.__sizeof__() + data_td: uhci_td | t.CPtr = t.CPtr(t.CUInt64T(tds) + uhci_td.__sizeof__()) _td_set_link(data_td, t.CUInt32T(t.CUInt64T(data_td) + uhci_td.__sizeof__()), 0, 0) _td_set_ctrl(data_td, ls, max_pkt) if data_in: @@ -395,7 +395,7 @@ def control_transfer(dev_addr: t.CUInt8T, endpoint: t.CUInt8T, ls: t.CInt, max_p _td_set_token(data_td, TD_TOKEN_OUT, dev_addr, endpoint, TD_TOKEN_DATA1, data_len) data_td.buffer = t.CUInt32T(t.CUInt64T(data_buf)) - status_td: uhci_td | t.CPtr = t.CUInt64T(data_td) + uhci_td.__sizeof__() + status_td: uhci_td | t.CPtr = t.CPtr(t.CUInt64T(data_td) + uhci_td.__sizeof__()) _td_set_link(status_td, 0, 0, 1) _td_set_ctrl(status_td, ls, max_pkt) if data_in: @@ -404,7 +404,7 @@ def control_transfer(dev_addr: t.CUInt8T, endpoint: t.CUInt8T, ls: t.CInt, max_p _td_set_token(status_td, TD_TOKEN_IN, dev_addr, endpoint, TD_TOKEN_DATA1, 0) status_td.buffer = 0 else: - status_td: uhci_td | t.CPtr = t.CUInt64T(tds) + uhci_td.__sizeof__() + status_td: uhci_td | t.CPtr = t.CPtr(t.CUInt64T(tds) + uhci_td.__sizeof__()) _td_set_link(status_td, 0, 0, 1) _td_set_ctrl(status_td, ls, max_pkt) _td_set_token(status_td, TD_TOKEN_IN, dev_addr, endpoint, TD_TOKEN_DATA1, 0) diff --git a/VKernel/Kernel/intr/idt.vp b/VKernel/Kernel/intr/idt.vp index a1cda19..4e0023a 100644 --- a/VKernel/Kernel/intr/idt.vp +++ b/VKernel/Kernel/intr/idt.vp @@ -2,6 +2,7 @@ import platform.pch.pic as pic import platform.pch.timer as timer import sched.sched as sched import drivers.serial.uart.serial as serial +import drivers.core.cpu.apic as apic import viperlib import asm import t, c @@ -244,12 +245,14 @@ def isrCommonhandler(interrupt: t.CInt): while True: asm.sti() asm.hlt() + pass tid: t.CInt = s.current_tid if tid == 0: serial.puts(" KERNEL PANIC\n") while True: asm.sti() asm.hlt() + pass buf2: t.CArray[t.CChar, 64] viperlib.snprintf(c.Addr(buf2), 64, " exc in tid=%d, terminating\n", tid) serial.puts(buf2) @@ -318,6 +321,7 @@ def isr33_handler() -> t.CExport | t.CVoid: t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(1) + apic.eoi() def isr34_handler() -> t.CExport | t.CVoid: handler2: irq_handler_t = irqGetHandler(2) @@ -328,6 +332,7 @@ def isr34_handler() -> t.CExport | t.CVoid: t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(2) + apic.eoi() def isr35_handler() -> t.CExport | t.CVoid: handler3: irq_handler_t = irqGetHandler(3) @@ -338,6 +343,7 @@ def isr35_handler() -> t.CExport | t.CVoid: t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(3) + apic.eoi() def isr36_handler() -> t.CExport | t.CVoid: handler4: irq_handler_t = irqGetHandler(4) @@ -348,6 +354,7 @@ def isr36_handler() -> t.CExport | t.CVoid: t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(4) + apic.eoi() def isr37_handler() -> t.CExport | t.CVoid: handler5: irq_handler_t = irqGetHandler(5) @@ -358,6 +365,7 @@ def isr37_handler() -> t.CExport | t.CVoid: t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(5) + apic.eoi() def isr38_handler() -> t.CExport | t.CVoid: handler6: irq_handler_t = irqGetHandler(6) @@ -368,6 +376,7 @@ def isr38_handler() -> t.CExport | t.CVoid: t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(6) + apic.eoi() def isr39_handler() -> t.CExport | t.CVoid: if pic.isSpurious(7): @@ -380,6 +389,7 @@ def isr39_handler() -> t.CExport | t.CVoid: t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(7) + apic.eoi() def isr40_handler() -> t.CExport | t.CVoid: handler8: irq_handler_t = irqGetHandler(8) @@ -390,6 +400,7 @@ def isr40_handler() -> t.CExport | t.CVoid: t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(8) + apic.eoi() def isr41_handler() -> t.CExport | t.CVoid: handler9: irq_handler_t = irqGetHandler(9) @@ -400,6 +411,7 @@ def isr41_handler() -> t.CExport | t.CVoid: t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(9) + apic.eoi() def isr42_handler() -> t.CExport | t.CVoid: handler10: irq_handler_t = irqGetHandler(10) @@ -410,6 +422,7 @@ def isr42_handler() -> t.CExport | t.CVoid: t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(10) + apic.eoi() def isr43_handler() -> t.CExport | t.CVoid: handler11: irq_handler_t = irqGetHandler(11) @@ -420,6 +433,7 @@ def isr43_handler() -> t.CExport | t.CVoid: t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(11) + apic.eoi() def isr44_handler() -> t.CExport | t.CVoid: handler: irq_handler_t = irqGetHandler(12) if handler: @@ -429,14 +443,21 @@ def isr44_handler() -> t.CExport | t.CVoid: t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9, t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11]) pic.eoi(12) + apic.eoi() -def isr45_handler() -> t.CExport | t.CVoid: pic.eoi(13) -def isr46_handler() -> t.CExport | t.CVoid: pic.eoi(14) +def isr45_handler() -> t.CExport | t.CVoid: + pic.eoi(13) + apic.eoi() + +def isr46_handler() -> t.CExport | t.CVoid: + pic.eoi(14) + apic.eoi() def isr47_handler() -> t.CExport | t.CVoid: if pic.isSpurious(15): return pic.eoi(15) + apic.eoi() def init_exceptions(): setGate(0, t.CUInt64T(isr0), CODE_SEG, 0x8E) diff --git a/VKernel/Kernel/intr/syscall.vp b/VKernel/Kernel/intr/syscall.vp index 860ed3d..5c5fdd0 100644 --- a/VKernel/Kernel/intr/syscall.vp +++ b/VKernel/Kernel/intr/syscall.vp @@ -420,7 +420,7 @@ def syscall_handler(num: t.CUInt64T, arg1: t.CUInt64T, arg2: t.CUInt64T, arg3: t return LOAD_SO(path_ptr_so) elif n == SO_CALL1: sym_ptr: t.CVoid | t.CPtr = t.CVoid(arg1, t.CPtr) - return t.CUInt64T(SO_CALL1(sym_ptr, arg2)) + return t.CUInt64T(SO_CALL1(sym_ptr, t.CPtr(arg2))) elif n == GET_WINBUF: return GET_WINBUF(t.CInt(arg1)) elif n == WIN_FLUSH: diff --git a/VKernel/Kernel/main.vp b/VKernel/Kernel/main.vp index 4b0fb69..4fb2d09 100644 --- a/VKernel/Kernel/main.vp +++ b/VKernel/Kernel/main.vp @@ -135,7 +135,7 @@ class ViperKernel: apic.start_aps() serial.puts("[main] kernel init done\n") - fb: t.CVoid | t.CPtr = BootInfo.framebuffer_addr + fb: t.CVoid | t.CPtr = t.CPtr(BootInfo.framebuffer_addr) width: t.CUInt64T = BootInfo.framebuffer_width height: t.CUInt64T = BootInfo.framebuffer_height pitch: t.CUInt64T = BootInfo.framebuffer_pitch @@ -176,13 +176,13 @@ class ViperKernel: mm.init(0, 0, 0, 0, 0) pt_pool_buf2: t.CVoid | t.CPtr = mm.malloc(t.CUInt64T(513) * t.CUInt64T(4096)) paging.init_pool(pt_pool_buf2, t.CUInt64T(513) * t.CUInt64T(4096)) - serial.puts("[main] paging and mm init done\n") - # 把 .rodata(字符串常量/vtable)映射只读 + CR0.WP=1: - # 越界写立即 #PF 暴露 cr2/rip(此前静默破坏格式串/路径/符号名 → P2/P3/P4/P5 连锁) - paging.ProtectKernelRO() - # [PG] 页表诊断:确认 .rodata 是否真正只读(2MB 大页会令 MakeRangeRO 失效) - paging.DumpMapping(0x100000, "kern") - paging.DumpMapping(0x60000, "bstk") + serial.puts("[main] paging and mm init done\n") + # 把 .rodata(字符串常量/vtable)映射只读 + CR0.WP=1: + # 越界写立即 #PF 暴露 cr2/rip(此前静默破坏格式串/路径/符号名 → P2/P3/P4/P5 连锁) + paging.ProtectKernelRO() + # [PG] 页表诊断:确认 .rodata 是否真正只读(2MB 大页会令 MakeRangeRO 失效) + paging.DumpMapping(0x100000, "kern") + paging.DumpMapping(0x60000, "bstk") paging.DumpMapping(0x80000000, "fb") proc.ProcessManager() @@ -366,7 +366,7 @@ def _start() -> t.CInt: c.Asm(f"mov {c.AsmOut(saved_rdi, t.ASM_DESCR.OUTPUT_REG)}, rdi", op = [t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RDI]) asm.BSSClean() - BootInfo = saved_rdi # 隐式转为 bootinfo* + BootInfo = t.CPtr(saved_rdi) # 转为 bootinfo* VKP = c.Addr(ViperKernel()) while True: asm.sti() diff --git a/VKernel/Kernel/mm/mm.vp b/VKernel/Kernel/mm/mm.vp index 633dbff..0c63819 100644 --- a/VKernel/Kernel/mm/mm.vp +++ b/VKernel/Kernel/mm/mm.vp @@ -126,7 +126,7 @@ class _BuddySystemObject: viperlib.snprintf(c.Addr(_dbp), 80, "[mm] it=%d order=%d bs=0x%lx addr=0x%lx rem=%lu\n", _itc, order, block_size, cur_addr, remaining) _sdbg.puts(c.Addr(_dbp)) - block: memory_block | t.CPtr = cur_addr + block: memory_block | t.CPtr = t.CPtr(cur_addr) block.size = block_size block.state = BLOCK_FREE block.order = order @@ -160,7 +160,7 @@ class _BuddySystemObject: current_order -= 1 new_block_size: t.CUInt64T = get_block_size(current_order) # 创建新块 - new_block: memory_block | t.CPtr = t.CUInt64T(block) + new_block_size + new_block: memory_block | t.CPtr = t.CPtr(t.CUInt64T(block) + new_block_size) new_block.size = new_block_size new_block.state = BLOCK_FREE new_block.order = current_order @@ -185,7 +185,7 @@ class _BuddySystemObject: block_addr: t.CUInt64T = t.CUInt64T(block) - t.CUInt64T(self.buddy.start_addr) buddy_addr: t.CUInt64T = block_addr ^ block_size # 计算伙伴块地址 - buddy: memory_block | t.CPtr = t.CUInt64T(self.buddy.start_addr) + buddy_addr + buddy: memory_block | t.CPtr = t.CPtr(t.CUInt64T(self.buddy.start_addr) + buddy_addr) # 检查伙伴块是否存在且空闲 if buddy >= t.CType(self.buddy.end_addr, memory_block, t.CPtr): break # 伙伴块超出内存范围 @@ -306,13 +306,13 @@ def _slab_find_page(ptr: t.CVoid | t.CPtr) -> slab_page | t.CPtr: if ptr is None: return None hdr_off: t.CUInt64T = memory_block.__sizeof__() page_addr: t.CUInt64T = t.CUInt64T(ptr) & ~t.CUInt64T(0xFFF) - page: slab_page | t.CPtr = page_addr + hdr_off + page: slab_page | t.CPtr = t.CPtr(page_addr + hdr_off) if page.magic == SLAB_MAGIC: os: t.CUInt16T = page.obj_size if os == 32 or os == 64 or os == 128 or os == 256 or os == 512 or os == 1024: return page page_addr2: t.CUInt64T = page_addr - 4096 - page2: slab_page | t.CPtr = page_addr2 + hdr_off + page2: slab_page | t.CPtr = t.CPtr(page_addr2 + hdr_off) if page2.magic == SLAB_MAGIC: os2: t.CUInt16T = page2.obj_size if os2 == 32 or os2 == 64 or os2 == 128 or os2 == 256 or os2 == 512 or os2 == 1024: @@ -333,7 +333,7 @@ class _SlabAllocator: block: memory_block | t.CPtr = BuddySystemObject.allocate_block(4096 + memory_block.__sizeof__()) if not block: return None hdr_off: t.CUInt64T = memory_block.__sizeof__() - page: slab_page | t.CPtr = t.CUInt64T(block) + hdr_off + page: slab_page | t.CPtr = t.CPtr(t.CUInt64T(block) + hdr_off) page.magic = SLAB_MAGIC page.obj_size = aligned_size d_off: t.CUInt16T = t.CUInt16T((hdr_off + slab_page.__sizeof__() + 15) & ~15) @@ -453,7 +453,7 @@ def free(ptr: t.CVoid | t.CPtr) -> t.CExport: op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX]) BuddySystemObject.free_block(block) return - block2: memory_block | t.CPtr = t.CUInt64T(ptr) - memory_block.__sizeof__() + block2: memory_block | t.CPtr = t.CPtr(t.CUInt64T(ptr) - memory_block.__sizeof__()) BuddySystemObject.free_block(block2) def calloc(nmemb: t.CUInt64T, size: t.CUInt64T) -> t.CVoid | t.CPtr | t.CExport: @@ -481,7 +481,7 @@ def realloc(ptr: t.CVoid | t.CPtr, size: t.CUInt64T) -> t.CVoid | t.CPtr | t.CEx op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX]) old_size = block_r.size - 4096 else: - block2: memory_block | t.CPtr = t.CUInt64T(ptr) - memory_block.__sizeof__() + block2: memory_block | t.CPtr = t.CPtr(t.CUInt64T(ptr) - memory_block.__sizeof__()) old_size = block2.size - memory_block.__sizeof__() copy_size: t.CUInt64T = old_size if old_size < size else size string.memcpy(new_ptr, ptr, copy_size) diff --git a/VKernel/Kernel/paging/paging.vp b/VKernel/Kernel/paging/paging.vp index ad3f682..9c4cbd5 100644 --- a/VKernel/Kernel/paging/paging.vp +++ b/VKernel/Kernel/paging/paging.vp @@ -257,7 +257,13 @@ def MakeRangeRO(vaddr_start: t.CUInt64T, vaddr_end: t.CUInt64T): global pml4 if not pml4: return va: t.CUInt64T = vaddr_start & ~t.CUInt64T(0xFFF) - while va < vaddr_end: + # ro_end 下取整到页:不保护含 ro_end 的未对齐尾页。链接脚本输出段未页对齐, + # .data 紧跟 .rodata(__rodata_end 未对齐时 .data 起始落在 rodata 尾页内), + # 整页置只读会把 .data 全局(如 devfs @DevFSObject=0x141630)误保护 → + # devfs_init 写全局 #PF(cr2=0x141630 rip=0x101aaa mov [r15],rax 根因)。 + # 尾页含少量 rodata 尾部(对齐填充),保持可写可容忍。 + ro_end_align: t.CUInt64T = vaddr_end & ~t.CUInt64T(0xFFF) + while va < ro_end_align: pml4_idx: t.CUInt64T = (va >> 39) & 0x1FF if not (pml4.entries[pml4_idx] & PTE_PRESENT): va += 0x1000; continue pdp_r: _p | t.CPtr = t.CType(pml4.entries[pml4_idx] & ~t.CUInt64T(0xFFF), _p, t.CPtr) diff --git a/VKernel/Kernel/sched/sched.vp b/VKernel/Kernel/sched/sched.vp index 5f217d4..7821307 100644 --- a/VKernel/Kernel/sched/sched.vp +++ b/VKernel/Kernel/sched/sched.vp @@ -205,7 +205,11 @@ class Scheduler: viperlib.snprintf(c.Addr(_dbg_ct), 96, "[sched] ct t%d func=0x%lx stack=0x%lx\n", tid, t.CUInt64T(th.func), t.CUInt64T(stack_ptr)) serial.puts(c.Addr(_dbg_ct)) - if not stack_ptr: return None + if not stack_ptr: + # B4:栈分配失败回退槽位计数(对齐 process.vp create_process 失败路径), + # 否则 thread_count 漂移 → 调度器扫描未初始化槽位。 + s.thread_count -= 1 + return None th.stack = stack_ptr th.stack_size = stack_size stack_top: t.CUInt64T = t.CUInt64T(stack_ptr) + stack_size - 16 diff --git a/VKernel/Kernel/services/desktop.vp b/VKernel/Kernel/services/desktop.vp index 0e1ab8e..66a1df0 100644 --- a/VKernel/Kernel/services/desktop.vp +++ b/VKernel/Kernel/services/desktop.vp @@ -345,7 +345,7 @@ def _push_event(evt: InputEvent): string.memcpy(c.Addr(_event_queue[_event_tail]), c.Addr(evt), INPUT_EVENT_SIZE) _event_tail = next_tail -def poll_event(buf_ptr: t.CVoid | t.CPtr, caller_pid: t.CInt) -> t.CInt: +def poll_event(buf_ptr: t.CPtr, caller_pid: t.CInt) -> t.CInt: global _event_head, _event_tail while _event_head != _event_tail: if _event_queue[_event_head].type == EVENT_TYPE_NONE: @@ -1669,7 +1669,7 @@ def _erase_cursor(back: UINT32PTR): if _cursor_saved == 0: return _cursor_restore_bg(back, _prev_cursor_x, _prev_cursor_y, _screen_w, _screen_h) -def desktop_thread(arg: t.CVoid | t.CPtr) -> t.CInt: +def desktop_thread(arg: t.CPtr) -> t.CInt: global _last_clock_sec, _mouse_moved global _prev_cursor_x, _prev_cursor_y global _perf_t_mouse, _perf_t_kbd, _perf_t_render, _perf_t_flush, _perf_t_total, _perf_frames, _perf_start_ticks @@ -1819,7 +1819,7 @@ def desktop_thread(arg: t.CVoid | t.CPtr) -> t.CInt: # [DIAG] .rodata 格式串校验:win=%lu/work=%lu 曾出现 ' / , 字节破坏(越界写)。 # 校验和变化 → 确认为真实内存破坏(配合 .rodata 只读后 #PF 定位写源); # 校验和不变 → 疑似 printf/串口输出伪影,走另一条排查线。 - _perf_fmt_str: str = "[perf] fps=%u wall=%lu work=%lu mouse=%lu kbd=%lu render=%lu(bg=%lu win=%lu cur=%lu fb=%lu) dirty=%d vsync=%d\n" + _perf_fmt_str: str = "[perf] fps=%u wall=%lu work=%lu mouse=%lu kbd=%lu render=%lu(bg=%lu win=%lu cur=%lu fb=%lu) dirty=%d vsync=%d sh=%d dc=%d ki=%lu mi=%lu\n" _fmt_sum: t.CUInt32T = 0 _fi: t.CInt = 0 while _fi < 110: @@ -1828,7 +1828,7 @@ def desktop_thread(arg: t.CVoid | t.CPtr) -> t.CInt: _chk_buf: t.CArray[t.CChar, 48] viperlib.snprintf(c.Addr(_chk_buf), 48, "[chk] sum=%u\n", _fmt_sum) serial.puts(c.Addr(_chk_buf)) - viperlib.snprintf(c.Addr(_perf_buf), 256, _perf_fmt_str, _fps_val, t.CUInt64T(_elapsed_ms), t.CUInt64T(_perf_t_total), t.CUInt64T(_perf_t_mouse), t.CUInt64T(_perf_t_kbd), t.CUInt64T(_perf_t_render), t.CUInt64T(_perf_t_bg), t.CUInt64T(_perf_t_win), t.CUInt64T(_perf_t_cur), t.CUInt64T(_perf_t_fb), _dirty_count, _vblank_ok) + viperlib.snprintf(c.Addr(_perf_buf), 256, _perf_fmt_str, _fps_val, t.CUInt64T(_elapsed_ms), t.CUInt64T(_perf_t_total), t.CUInt64T(_perf_t_mouse), t.CUInt64T(_perf_t_kbd), t.CUInt64T(_perf_t_render), t.CUInt64T(_perf_t_bg), t.CUInt64T(_perf_t_win), t.CUInt64T(_perf_t_cur), t.CUInt64T(_perf_t_fb), _dirty_count, _vblank_ok, _screen_h, _dirty_count, keyboard.kbd_irq_cnt, mouse.mse_irq_cnt) serial.puts(_perf_buf) _perf_t_mouse = 0 _perf_t_kbd = 0 @@ -1844,7 +1844,7 @@ def desktop_thread(arg: t.CVoid | t.CPtr) -> t.CInt: sched.Scheduler.try_reschedule() return 0 -def start(fb_ptr: t.CVoid | t.CPtr, w: t.CInt, h: t.CInt, pitch: t.CInt = 0) -> sched.Thread | t.CPtr: +def start(fb_ptr: t.CPtr, w: t.CInt, h: t.CInt, pitch: t.CInt = 0) -> sched.Thread | t.CPtr: global _fb, _screen_w, _screen_h, _fb_pitch, _cursor_x, _cursor_y global _bg_row_buf, _back_fb, _row_buf global _dirty_rows, _prev_cursor_x, _prev_cursor_y diff --git a/VKernel/project.vpj b/VKernel/project.vpj index bc9d3b6..e74db62 100644 --- a/VKernel/project.vpj +++ b/VKernel/project.vpj @@ -26,7 +26,7 @@ "output": "kernel.bin" }, "includes": [ - "../../includes" + "../../../includes" ], "target": { "triple": "x86_64-none-elf", diff --git a/build.py b/build.py index 939d901..e2bfd46 100644 --- a/build.py +++ b/build.py @@ -12,7 +12,7 @@ noapp = '--noapp' in sys.argv # 编译内核 -cmd = r'..\TransPyV\output\TransPyV.exe --project ./VKernel/project.vpj --clear-cache' +cmd = r'..\..\TransPyV\output\TransPyV.exe --project ./VKernel/project.vpj --clear-cache --rebuild-includes' if clean: cmd += ' --clean' os.system(cmd) @@ -49,17 +49,17 @@ elif kernel_only: print("[build] 警告: hello.elf 不存在,请先不带 --kernel-only 完整构建一次") else: # 完整编译所有库+应用 - so_cmd = r'..\TransPyV\output\TransPyV.exe --project Libs/SerialLogger/project.vpj --clear-cache' + so_cmd = r'..\..\TransPyV\output\TransPyV.exe --project Libs/SerialLogger/project.vpj --clear-cache' if clean: so_cmd += ' --clean' os.system(so_cmd) - vpui_cmd = r'..\TransPyV\output\TransPyV.exe --project Libs/VPUI64/project.vpj --clear-cache' + vpui_cmd = r'..\..\TransPyV\output\TransPyV.exe --project Libs/VPUI64/project.vpj --clear-cache' if clean: vpui_cmd += ' --clean' os.system(vpui_cmd) - app_cmd = r'..\TransPyV\output\TransPyV.exe --project Apps/HelloWorld/project.vpj --clear-cache' + app_cmd = r'..\..\TransPyV\output\TransPyV.exe --project Apps/HelloWorld/project.vpj --clear-cache' if clean: app_cmd += ' --clean' os.system(app_cmd) @@ -67,21 +67,21 @@ else: os.makedirs("./disk/apps", exist_ok=True) shutil.copy("Apps/HelloWorld/.tpv_build/output/helloworld.elf", "./disk/apps/hello.elf") - term_cmd = r'..\TransPyV\output\TransPyV.exe --project Apps/Terminal/project.vpj --clear-cache' + term_cmd = r'..\..\TransPyV\output\TransPyV.exe --project Apps/Terminal/project.vpj --clear-cache' if clean: term_cmd += ' --clean' os.system(term_cmd) shutil.copy("Apps/Terminal/.tpv_build/output/terminal.elf", "./disk/apps/terminal.elf") - garg_cmd = r'..\TransPyV\output\TransPyV.exe --project Apps/Gargantua/project.vpj --clear-cache' + garg_cmd = r'..\..\TransPyV\output\TransPyV.exe --project Apps/Gargantua/project.vpj --clear-cache' if clean: garg_cmd += ' --clean' os.system(garg_cmd) shutil.copy("Apps/Gargantua/.tpv_build/output/gargantua.elf", "./disk/apps/gargantua.elf") - scene3d_cmd = r'..\TransPyV\output\TransPyV.exe --project Apps/Scene3D/project.vpj --clear-cache' + scene3d_cmd = r'..\..\TransPyV\output\TransPyV.exe --project Apps/Scene3D/project.vpj --clear-cache' if clean: scene3d_cmd += ' --clean' os.system(scene3d_cmd) diff --git a/vpsdk/stdio.vp b/vpsdk/stdio.vp index 76e666c..15adfed 100644 --- a/vpsdk/stdio.vp +++ b/vpsdk/stdio.vp @@ -22,3 +22,12 @@ def printf(fmt: t.CConst | str, *args) -> t.CInt | t.CExport: def exit(status: t.CInt) -> t.CVoid | t.CExport: """终止当前进程(EXIT syscall:销毁本进程窗口)""" _syscall._syscall1(t.CUInt64T(_syscall.EXIT), t.CUInt64T(status)) + + +def fflush(stream: t.CConst | t.CVoid | t.CPtr) -> t.CInt | t.CExport: + """刷新输出流:串口/控制台输出都是直写,无缓冲可刷,空操作返回 0 + + 覆盖 libc fflush 的裸机缺失(includes/memhub.vp 的诊断/终止路径 call @fflush); + 与 printf/exit 同为 CExport 裸名,供内核侧 includes 跨模块引用解析。 + """ + return 0