From ca72ddbbf72f7c4ea02f4c5a3c3d193cc74236db Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Fri, 16 Oct 2026 18:32:33 +0800 Subject: [PATCH] =?UTF-8?q?refactor(syscall):=20=E8=B0=83=E7=94=A8?= =?UTF-8?q?=E5=8F=B7=E6=94=B9=E7=94=A8=20enum=20=E5=B9=B6=E5=85=A8?= =?UTF-8?q?=E9=9D=A2=E5=AF=B9=E9=BD=90=20Linux=20x86-64=20ABI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 内核 intr/syscall.vp 与 vpsdk/syscall.vp 各一份 1..34 的 define 表改为同名 enum Syscall。编号口径:与 Linux 同名同号;Linux 有而我们未实现的留空不占号(12 brk / 39 getpid / 84 rmdir / 217 getdents64 / 257 openat … 需要时按号补)。 15 个语义重合的调用直接用 Linux 号:READ 0 / WRITE 1 / OPEN 2 / CLOSE 3 / STAT 4 / SEEK 8 / MMAP 9 / MUNMAP 11 / YIELD 24 / THREAD_CREATE 56(≈clone) / SPAWN 59(≈execve) / THREAD_EXIT 60(exit) / MKDIR 83 / REMOVE 87 / EXIT 231(exit_group)。 其余 19 个(UI 11 个 + SERIAL_PUTS/TELL/SIZE/OPENDIR/READDIR/CLOSEDIR/LOAD_SO/SO_CALL1)暂放 0x1000 起的**临时私有段**,每条带迁移标注:私有能力最终不占 syscall 号、改走 devfs 设备文件;UI 11 个待用户态 explorer(图形壳)接管 framebuffer 与输入后删除。 内核派发链改 n == int(Syscall.X)(n 是 int/i64、成员是 i32,显式 int() 规避未证实的混合宽度比较);SDK 全部调用点统一为 syscall.Syscall.X;stdlib 的 SYSCALL_MMAP 别名并入 Syscall.MMAP;Terminal 里硬编码的 uint64(18) 改为常量。 --- Apps/Terminal/main.vp | 2 +- Libs/SerialLogger/serial_logger.vp | 12 +-- Libs/VPUI64/vpui64.vp | 4 +- VKernel/Kernel/intr/syscall.vp | 150 ++++++++++++++++------------- vpsdk/dynlib.vp | 4 +- vpsdk/fs.vp | 26 ++--- vpsdk/process.vp | 10 +- vpsdk/stdio.vp | 4 +- vpsdk/stdlib.vp | 2 +- vpsdk/syscall.vp | 83 ++++++++-------- vpsdk/vpui.vp | 2 +- vpsdk/window.vp | 22 ++--- 12 files changed, 171 insertions(+), 150 deletions(-) diff --git a/Apps/Terminal/main.vp b/Apps/Terminal/main.vp index 21a513a..cecabce 100644 --- a/Apps/Terminal/main.vp +++ b/Apps/Terminal/main.vp @@ -20,7 +20,7 @@ export def _start() -> int: master: vpui.Tk* = &root def _sdbg(msg: str): - _syscall._syscall1(uint64(18), uint64(msg)) + _syscall._syscall1(uint64(_syscall.Syscall.SERIAL_PUTS), uint64(msg)) _sdbg("[term] start\n") diff --git a/Libs/SerialLogger/serial_logger.vp b/Libs/SerialLogger/serial_logger.vp index f19496f..dfadfd3 100644 --- a/Libs/SerialLogger/serial_logger.vp +++ b/Libs/SerialLogger/serial_logger.vp @@ -2,11 +2,11 @@ import vpsdk.syscall as syscall import t, c export def log_info(msg: const str): - syscall._syscall1(uint64(syscall.SERIAL_PUTS), uint64("[SerialLogger] ")) - syscall._syscall1(uint64(syscall.SERIAL_PUTS), uint64(msg)) - syscall._syscall1(uint64(syscall.SERIAL_PUTS), uint64("\n")) + syscall._syscall1(uint64(syscall.Syscall.SERIAL_PUTS), uint64("[SerialLogger] ")) + syscall._syscall1(uint64(syscall.Syscall.SERIAL_PUTS), uint64(msg)) + syscall._syscall1(uint64(syscall.Syscall.SERIAL_PUTS), uint64("\n")) export def log_warn(msg: const str): - syscall._syscall1(uint64(syscall.SERIAL_PUTS), uint64("[SerialLogger:WARN] ")) - syscall._syscall1(uint64(syscall.SERIAL_PUTS), uint64(msg)) - syscall._syscall1(uint64(syscall.SERIAL_PUTS), uint64("\n")) + syscall._syscall1(uint64(syscall.Syscall.SERIAL_PUTS), uint64("[SerialLogger:WARN] ")) + syscall._syscall1(uint64(syscall.Syscall.SERIAL_PUTS), uint64(msg)) + syscall._syscall1(uint64(syscall.Syscall.SERIAL_PUTS), uint64("\n")) diff --git a/Libs/VPUI64/vpui64.vp b/Libs/VPUI64/vpui64.vp index 5e73579..bc79045 100644 --- a/Libs/VPUI64/vpui64.vp +++ b/Libs/VPUI64/vpui64.vp @@ -7,10 +7,10 @@ def color_rgb(r: uint8, g: uint8, b: uint8) -> uint32: return uint32(r) | (uint32(g) << 8) | (uint32(b) << 16) def get_winbuf(win_id: int) -> UINT32PTR: - return syscall._syscall2(uint64(syscall.GET_WINBUF), uint64(win_id), 0) + return syscall._syscall2(uint64(syscall.Syscall.GET_WINBUF), uint64(win_id), 0) def win_flush(win_id: int): - syscall._syscall2(uint64(syscall.WIN_FLUSH), uint64(win_id), 0) + syscall._syscall2(uint64(syscall.Syscall.WIN_FLUSH), uint64(win_id), 0) export def draw_pixel(buf: UINT32PTR, bw: int, x: int, y: int, color: uint32): if x < 0 or y < 0: return diff --git a/VKernel/Kernel/intr/syscall.vp b/VKernel/Kernel/intr/syscall.vp index 212668c..aa29a1f 100644 --- a/VKernel/Kernel/intr/syscall.vp +++ b/VKernel/Kernel/intr/syscall.vp @@ -11,40 +11,54 @@ import paging.paging as paging import execrunner.elf as elf -define CREATE_WINDOW = 1 -define DRAW_TEXT = 2 -define EXIT = 3 -define OPEN = 4 -define CLOSE = 5 -define READ = 6 -define WRITE = 7 -define SEEK = 8 -define TELL = 9 -define SIZE = 10 -define MKDIR = 11 -define REMOVE = 12 -define OPENDIR = 13 -define READDIR = 14 -define CLOSEDIR = 15 -define STAT = 16 -define WAIT_WINDOW = 17 -define SERIAL_PUTS = 18 -define LOAD_SO = 19 -define SO_CALL1 = 20 -define GET_WINBUF = 21 -define WIN_FLUSH = 22 -define POLL_EVENT = 23 -define SET_CURSOR = 24 -define YIELD = 25 -define SET_TITLE = 26 -define SET_GEOMETRY = 27 -define SPAWN = 28 -define MMAP = 29 -define MUNMAP = 30 -define SET_RESIZABLE = 31 -define GET_WIN_SIZE = 32 -define THREAD_CREATE = 33 -define THREAD_EXIT = 34 +# ============================================================================ +# 系统调用号表(唯一权威来源)。与 Linux x86-64 ABI **同名同号**: +# · Linux 有同名调用 → 直接用它的号;Linux 有而我们未实现的**留空不占号** +# (12 brk / 39 getpid / 84 rmdir / 217 getdents64 / 257 openat … 需要时按号补上); +# · 我们独有的能力**不再新增 syscall**,一律走 devfs 设备文件(open/read/write) +# 或下沉到用户层(见下面「临时私有段」的逐条迁移标注)。 +# 注意:vpsdk/syscall.vp 有一份逐字对应的镜像(vpsdk 不允许依赖 VKernel), +# 增删/改号/改名必须两边同步。 +# ============================================================================ +enum Syscall: + # ---- Linux 对齐段(号 = Linux x86-64 的号)---- + READ = 0 # read(fd, buf, count) + WRITE = 1 # write(fd, buf, count) + OPEN = 2 # open(path, flags) + CLOSE = 3 # close(fd) + STAT = 4 # stat(path, info)(结构体仍是本系统的 fileinfo) + SEEK = 8 # lseek(fd, offset, whence)(whence 目前恒 0 = SEEK_SET) + MMAP = 9 # mmap(size) → VA(ABI 待向 Linux 的 addr/len/prot/flags/fd/off 靠拢) + MUNMAP = 11 # munmap(ptr, size)(目前空实现) + YIELD = 24 # sched_yield() + THREAD_CREATE = 56 # clone():建用户线程,返回 tid + SPAWN = 59 # execve():加载并运行新 ELF,返回 pid + THREAD_EXIT = 60 # exit():退役当前线程 + MKDIR = 83 # mkdir(path) + REMOVE = 87 # unlink(path) + EXIT = 231 # exit_group():退役当前线程 + 拆掉本 pid 的窗口 + # ---- 临时私有段(0x1000+):Linux 无对应,且**逐条都会被消掉** ---- + # 目标形态:私有能力不占 syscall 号 → 改 devfs 设备文件;UI 11 个 → 由用户态 + # explorer(图形壳)接管 framebuffer 与输入后删除。当前保留只为让现有 app 还能跑。 + SERIAL_PUTS = 0x1000 # TODO(devfs):改为 write(/dev/serial0) + TELL = 0x1001 # TODO(linux):可由 lseek(fd, 0, SEEK_CUR) 表达 + SIZE = 0x1002 # TODO(linux):可由 fstat 表达 + OPENDIR = 0x1003 # TODO(linux):openat(O_DIRECTORY) + getdents64 + READDIR = 0x1004 # TODO(linux):getdents64 + CLOSEDIR = 0x1005 # TODO(linux):close + LOAD_SO = 0x1006 # TODO(用户层):动态库加载下沉 + SO_CALL1 = 0x1007 # TODO(用户层):同上 + WAIT_WINDOW = 0x1008 # TODO(explorer):UI + CREATE_WINDOW = 0x1009 # TODO(explorer):UI + DRAW_TEXT = 0x100A # TODO(explorer):UI + GET_WINBUF = 0x100B # TODO(explorer):UI + WIN_FLUSH = 0x100C # TODO(explorer):UI + POLL_EVENT = 0x100D # TODO(explorer):UI + SET_CURSOR = 0x100E # TODO(explorer):UI + SET_TITLE = 0x100F # TODO(explorer):UI + SET_GEOMETRY = 0x1010 # TODO(explorer):UI + SET_RESIZABLE = 0x1011 # TODO(explorer):UI + GET_WIN_SIZE = 0x1012 # TODO(explorer):UI define IA32_EFER = 0xC0000080 define IA32_STAR = 0xC0000081 @@ -385,96 +399,96 @@ extern def syscall_entry() export def syscall_handler(num: uint64, arg1: uint64, arg2: uint64, arg3: uint64, arg4: uint64, arg5: uint64, arg6: uint64) -> uint64: n: int = int(num) - if n == CREATE_WINDOW: + if n == int(Syscall.CREATE_WINDOW): title_ptr: str = str(arg5) return uint64(CREATE_WINDOW(int(arg1), int(arg2), int(arg3), int(arg4), title_ptr, int(arg6))) - elif n == DRAW_TEXT: + elif n == int(Syscall.DRAW_TEXT): text_ptr: str = str(arg4) return uint64(DRAW_TEXT(int(arg1), int(arg2), int(arg3), text_ptr, uint32(arg5))) - elif n == EXIT: + elif n == int(Syscall.EXIT): return uint64(EXIT(int(arg1))) - elif n == OPEN: + elif n == int(Syscall.OPEN): path_ptr: str = str(arg1) return uint64(OPEN(path_ptr, uint32(arg2))) - elif n == CLOSE: + elif n == int(Syscall.CLOSE): return uint64(CLOSE(int(arg1))) - elif n == READ: + elif n == int(Syscall.READ): buf_ptr: rawptr = rawptr(arg2) return uint64(READ(int(arg1), buf_ptr, uint32(arg3))) - elif n == WRITE: + elif n == int(Syscall.WRITE): buf_ptr: rawptr = rawptr(arg2) return uint64(WRITE(int(arg1), buf_ptr, uint32(arg3))) - elif n == SEEK: + elif n == int(Syscall.SEEK): return uint64(SEEK(int(arg1), uint32(arg2))) - elif n == TELL: + elif n == int(Syscall.TELL): return uint64(TELL(int(arg1))) - elif n == SIZE: + elif n == int(Syscall.SIZE): return uint64(fsize(int(arg1))) - elif n == MKDIR: + elif n == int(Syscall.MKDIR): path_ptr: str = str(arg1) return uint64(MKDIR(path_ptr)) - elif n == REMOVE: + elif n == int(Syscall.REMOVE): path_ptr: str = str(arg1) return uint64(REMOVE(path_ptr)) - elif n == OPENDIR: + elif n == int(Syscall.OPENDIR): path_ptr: str = str(arg1) return uint64(OPENdir(path_ptr)) - elif n == READDIR: + elif n == int(Syscall.READDIR): info_ptr: rawptr = rawptr(arg2) return uint64(READdir(int(arg1), info_ptr)) - elif n == CLOSEDIR: + elif n == int(Syscall.CLOSEDIR): return uint64(CLOSEdir(int(arg1))) - elif n == STAT: + elif n == int(Syscall.STAT): path_ptr: str = str(arg1) info_ptr: rawptr = rawptr(arg2) return uint64(STAT(path_ptr, info_ptr)) - elif n == WAIT_WINDOW: + elif n == int(Syscall.WAIT_WINDOW): if int(arg2) == 1: return uint64(desktop.is_active(int(arg1))) elif int(arg2) == 2: sched.Scheduler.try_reschedule() return 0 return uint64(WAIT_WINDOW(int(arg1))) - elif n == SERIAL_PUTS: + elif n == int(Syscall.SERIAL_PUTS): str_ptr_sp: str = str(arg1) return uint64(SERIAL_PUTS(str_ptr_sp)) - elif n == LOAD_SO: + elif n == int(Syscall.LOAD_SO): path_ptr_so: rawptr = rawptr(arg1) return LOAD_SO(path_ptr_so) - elif n == SO_CALL1: + elif n == int(Syscall.SO_CALL1): sym_ptr: rawptr = rawptr(arg1) return uint64(SO_CALL1(sym_ptr, rawptr(arg2))) - elif n == GET_WINBUF: + elif n == int(Syscall.GET_WINBUF): return GET_WINBUF(int(arg1)) - elif n == WIN_FLUSH: + elif n == int(Syscall.WIN_FLUSH): return uint64(WIN_FLUSH(int(arg1), rawptr(arg2))) - elif n == POLL_EVENT: + elif n == int(Syscall.POLL_EVENT): buf_ptr_ev: rawptr = rawptr(arg1) caller_pid_ev: int = process.current() return uint64(desktop.poll_event(buf_ptr_ev, caller_pid_ev)) - elif n == SET_CURSOR: + elif n == int(Syscall.SET_CURSOR): desktop.set_cursor_type(int(arg1), int(arg2)) return 0 - elif n == YIELD: + elif n == int(Syscall.YIELD): sched.Scheduler.try_reschedule() return 0 - elif n == SET_TITLE: + elif n == int(Syscall.SET_TITLE): title_ptr_st: rawptr = rawptr(arg2) return uint64(desktop.set_title(int(arg1), title_ptr_st)) - elif n == SET_GEOMETRY: + elif n == int(Syscall.SET_GEOMETRY): return uint64(desktop.set_geometry(int(arg1), int(arg2), int(arg3), int(arg4), int(arg5))) - elif n == SET_RESIZABLE: + elif n == int(Syscall.SET_RESIZABLE): return uint64(desktop.set_resizable(int(arg1), int(arg2), int(arg3))) - elif n == GET_WIN_SIZE: + elif n == int(Syscall.GET_WIN_SIZE): return uint64(desktop.get_size(int(arg1))) - elif n == SPAWN: + elif n == int(Syscall.SPAWN): path_ptr_sp: rawptr = rawptr(arg1) return uint64(SPAWN(path_ptr_sp, int(arg2))) - elif n == MMAP: + elif n == int(Syscall.MMAP): return MMAP(arg1) - elif n == MUNMAP: + elif n == int(Syscall.MUNMAP): return uint64(MUNMAP(arg1, arg2)) - elif n == THREAD_CREATE: + elif n == int(Syscall.THREAD_CREATE): func_ptr: rawptr = rawptr(arg1) arg_ptr: rawptr = rawptr(arg2) cur_pid: int = process.current() @@ -486,7 +500,7 @@ export def syscall_handler(num: uint64, arg1: uint64, arg2: uint64, arg3: uint64 if p: p.addThread(th.tid) return uint64(th.tid) - elif n == THREAD_EXIT: + elif n == int(Syscall.THREAD_EXIT): # 用户线程显式退出(回收用户栈等资源后让出,永不返回)。 sched.Scheduler.exit_current_thread() return 0 diff --git a/vpsdk/dynlib.vp b/vpsdk/dynlib.vp index 7b49803..0b19f1b 100644 --- a/vpsdk/dynlib.vp +++ b/vpsdk/dynlib.vp @@ -2,10 +2,10 @@ from . import syscall as syscall def load_so(path: const str) -> uint64: - return syscall._syscall1(uint64(syscall.LOAD_SO), uint64(path)) + return syscall._syscall1(uint64(syscall.Syscall.LOAD_SO), uint64(path)) def so_call1(sym_name: const str, arg1: rawptr) -> int: # arg1 只是原样交给系统调用的裸地址,故用 rawptr(未定/通配指针)而非 t.CPtr: # 后者是具体类型的一级指针,调用方传字符串字面量(二级指针)会被判成级数不符 # (CastError: pointer level differs, source level 2 -> target level 1)。 - return int(syscall._syscall2(uint64(syscall.SO_CALL1), uint64(sym_name), uint64(arg1))) + return int(syscall._syscall2(uint64(syscall.Syscall.SO_CALL1), uint64(sym_name), uint64(arg1))) diff --git a/vpsdk/fs.vp b/vpsdk/fs.vp index 6555f42..873604d 100644 --- a/vpsdk/fs.vp +++ b/vpsdk/fs.vp @@ -17,43 +17,43 @@ define DT_FILE = 1 define DT_DIR = 2 def open(path: const str, flags: uint32) -> int: - return int(syscall._syscall3(uint64(syscall.OPEN), uint64(path), uint64(flags), 0)) + return int(syscall._syscall3(uint64(syscall.Syscall.OPEN), uint64(path), uint64(flags), 0)) def close(fd: int) -> int: - return int(syscall._syscall1(uint64(syscall.CLOSE), uint64(fd))) + return int(syscall._syscall1(uint64(syscall.Syscall.CLOSE), uint64(fd))) def read(fd: int, buf: rawptr, count: uint32) -> int: - return int(syscall._syscall3(uint64(syscall.READ), uint64(fd), uint64(buf), uint64(count))) + return int(syscall._syscall3(uint64(syscall.Syscall.READ), uint64(fd), uint64(buf), uint64(count))) def write(fd: int, buf: rawptr, count: uint32) -> int: - return int(syscall._syscall3(uint64(syscall.WRITE), uint64(fd), uint64(buf), uint64(count))) + return int(syscall._syscall3(uint64(syscall.Syscall.WRITE), uint64(fd), uint64(buf), uint64(count))) def seek(fd: int, offset: uint32) -> int: - return int(syscall._syscall3(uint64(syscall.SEEK), uint64(fd), uint64(offset), 0)) + return int(syscall._syscall3(uint64(syscall.Syscall.SEEK), uint64(fd), uint64(offset), 0)) def tell(fd: int) -> uint32: - return uint32(syscall._syscall1(uint64(syscall.TELL), uint64(fd))) + return uint32(syscall._syscall1(uint64(syscall.Syscall.TELL), uint64(fd))) def fsize(fd: int) -> uint32: - return uint32(syscall._syscall1(uint64(syscall.SIZE), uint64(fd))) + return uint32(syscall._syscall1(uint64(syscall.Syscall.SIZE), uint64(fd))) def mkdir(path: const str) -> int: - return int(syscall._syscall3(uint64(syscall.MKDIR), uint64(path), 0, 0)) + return int(syscall._syscall3(uint64(syscall.Syscall.MKDIR), uint64(path), 0, 0)) def remove(path: const str) -> int: - return int(syscall._syscall3(uint64(syscall.REMOVE), uint64(path), 0, 0)) + return int(syscall._syscall3(uint64(syscall.Syscall.REMOVE), uint64(path), 0, 0)) def opendir(path: const str) -> int: - return int(syscall._syscall3(uint64(syscall.OPENDIR), uint64(path), 0, 0)) + return int(syscall._syscall3(uint64(syscall.Syscall.OPENDIR), uint64(path), 0, 0)) def readdir(dd: int, info: rawptr) -> int: - return int(syscall._syscall3(uint64(syscall.READDIR), uint64(dd), uint64(info), 0)) + return int(syscall._syscall3(uint64(syscall.Syscall.READDIR), uint64(dd), uint64(info), 0)) def closedir(dd: int) -> int: - return int(syscall._syscall1(uint64(syscall.CLOSEDIR), uint64(dd))) + return int(syscall._syscall1(uint64(syscall.Syscall.CLOSEDIR), uint64(dd))) def stat(path: const str, info: rawptr) -> int: - return int(syscall._syscall3(uint64(syscall.STAT), uint64(path), uint64(info), 0)) + return int(syscall._syscall3(uint64(syscall.Syscall.STAT), uint64(path), uint64(info), 0)) class FileIO: _fd: int diff --git a/vpsdk/process.vp b/vpsdk/process.vp index 83bd3d4..41d1ade 100644 --- a/vpsdk/process.vp +++ b/vpsdk/process.vp @@ -2,20 +2,20 @@ from . import syscall as syscall def exit(code: int): - syscall._syscall1(uint64(syscall.EXIT), uint64(code)) + syscall._syscall1(uint64(syscall.Syscall.EXIT), uint64(code)) def thread_exit(): """当前用户线程显式退出:内核回收其用户栈并标记线程结束(不返回)。""" - syscall._syscall0(uint64(syscall.THREAD_EXIT)) + syscall._syscall0(uint64(syscall.Syscall.THREAD_EXIT)) def yield_cpu(): - syscall._syscall2(uint64(syscall.WAIT_WINDOW), uint64(0), uint64(2)) + syscall._syscall2(uint64(syscall.Syscall.WAIT_WINDOW), uint64(0), uint64(2)) def spawn(path: const str, blocking: int = 0) -> int: - return int(syscall._syscall2(uint64(syscall.SPAWN), uint64(path), uint64(blocking))) + return int(syscall._syscall2(uint64(syscall.Syscall.SPAWN), uint64(path), uint64(blocking))) def thread_create(func: rawptr, arg: rawptr = None) -> int: - return int(syscall._syscall2(uint64(syscall.THREAD_CREATE), uint64(func), uint64(arg))) + return int(syscall._syscall2(uint64(syscall.Syscall.THREAD_CREATE), uint64(func), uint64(arg))) class Thread: diff --git a/vpsdk/stdio.vp b/vpsdk/stdio.vp index 29fd1da..d21913b 100644 --- a/vpsdk/stdio.vp +++ b/vpsdk/stdio.vp @@ -15,12 +15,12 @@ export def printf(fmt: const str, *args) -> int: return 0 buf: [1024]char n: int = viperlib.vsnprintf(&buf, 1024, fmt, args) - _syscall._syscall1(uint64(_syscall.SERIAL_PUTS), uint64(&buf)) + _syscall._syscall1(uint64(_syscall.Syscall.SERIAL_PUTS), uint64(&buf)) return n export def exit(status: int): """终止当前进程(EXIT syscall:销毁本进程窗口)""" - _syscall._syscall1(uint64(_syscall.EXIT), uint64(status)) + _syscall._syscall1(uint64(_syscall.Syscall.EXIT), uint64(status)) export def fflush(stream: const rawptr) -> int: diff --git a/vpsdk/stdlib.vp b/vpsdk/stdlib.vp index b5f3367..d6bc534 100644 --- a/vpsdk/stdlib.vp +++ b/vpsdk/stdlib.vp @@ -20,7 +20,7 @@ export def malloc(size: sizet) -> rawptr: if _heap_inited == 0: _heap_init() hdr_size: sizet = _heap_hdr.__sizeof__() total: sizet = hdr_size + size - ptr: uint64 = _sc._syscall1(uint64(_sc.SYSCALL_MMAP), uint64(total)) + ptr: uint64 = _sc._syscall1(uint64(_sc.Syscall.MMAP), uint64(total)) if ptr == 0: return None # 块头必须落在**映射区内部**(映射起点 ptr 处),不能写 ptr - hdr_size: # 那 8 字节在映射之外 —— 第一次 malloc 时 mmap 返回的正是用户堆起点 0x20000000, diff --git a/vpsdk/syscall.vp b/vpsdk/syscall.vp index bafcbff..0fadc63 100644 --- a/vpsdk/syscall.vp +++ b/vpsdk/syscall.vp @@ -1,41 +1,48 @@ -define CREATE_WINDOW = 1 -define DRAW_TEXT = 2 -define EXIT = 3 -define OPEN = 4 -define CLOSE = 5 -define READ = 6 -define WRITE = 7 -define SEEK = 8 -define TELL = 9 -define SIZE = 10 -define MKDIR = 11 -define REMOVE = 12 -define OPENDIR = 13 -define READDIR = 14 -define CLOSEDIR = 15 -define STAT = 16 -define WAIT_WINDOW = 17 -define SERIAL_PUTS = 18 -define LOAD_SO = 19 -define SO_CALL1 = 20 -define GET_WINBUF = 21 -define WIN_FLUSH = 22 -define POLL_EVENT = 23 -define SET_CURSOR = 24 - -define YIELD = 25 -define SET_TITLE = 26 -define SET_GEOMETRY = 27 -define SPAWN = 28 -define MMAP = 29 -define MUNMAP = 30 -define SET_RESIZABLE = 31 -define GET_WIN_SIZE = 32 -define THREAD_CREATE = 33 -define THREAD_EXIT = 34 - -# SYSCALL_* 别名(vpsdk.stdlib 等模块引用;数值与内核 VKernel/intr/syscall.vp 一致) -define SYSCALL_MMAP = 29 +# ============================================================================ +# 系统调用号表(SDK 侧镜像)。**与 VKernel/Kernel/intr/syscall.vp 的同名 enum 逐条对应**: +# vpsdk 不允许依赖 VKernel,所以这里是一份必须手工同步的副本 —— 增删/改号/改名两边一起改。 +# 编号口径:与 Linux x86-64 ABI 同名同号;Linux 有而我们未实现的留空不占号; +# 我们独有的能力不再新增 syscall,最终走 devfs 设备文件或下沉到用户层(见 0x1000+ 段的标注)。 +# ============================================================================ +enum Syscall: + # ---- Linux 对齐段(号 = Linux x86-64 的号)---- + READ = 0 # read(fd, buf, count) + WRITE = 1 # write(fd, buf, count) + OPEN = 2 # open(path, flags) + CLOSE = 3 # close(fd) + STAT = 4 # stat(path, info)(结构体仍是本系统的 fileinfo) + SEEK = 8 # lseek(fd, offset, whence)(whence 目前恒 0 = SEEK_SET) + MMAP = 9 # mmap(size) → VA(ABI 待向 Linux 的 addr/len/prot/flags/fd/off 靠拢) + MUNMAP = 11 # munmap(ptr, size)(目前空实现) + YIELD = 24 # sched_yield() + THREAD_CREATE = 56 # clone():建用户线程,返回 tid + SPAWN = 59 # execve():加载并运行新 ELF,返回 pid + THREAD_EXIT = 60 # exit():退役当前线程 + MKDIR = 83 # mkdir(path) + REMOVE = 87 # unlink(path) + EXIT = 231 # exit_group():退役当前线程 + 拆掉本 pid 的窗口 + # ---- 临时私有段(0x1000+):Linux 无对应,且**逐条都会被消掉** ---- + # 目标形态:私有能力不占 syscall 号 → 改 devfs 设备文件;UI 11 个 → 由用户态 + # explorer(图形壳)接管 framebuffer 与输入后删除。当前保留只为让现有 app 还能跑。 + SERIAL_PUTS = 0x1000 # TODO(devfs):改为 write(/dev/serial0) + TELL = 0x1001 # TODO(linux):可由 lseek(fd, 0, SEEK_CUR) 表达 + SIZE = 0x1002 # TODO(linux):可由 fstat 表达 + OPENDIR = 0x1003 # TODO(linux):openat(O_DIRECTORY) + getdents64 + READDIR = 0x1004 # TODO(linux):getdents64 + CLOSEDIR = 0x1005 # TODO(linux):close + LOAD_SO = 0x1006 # TODO(用户层):动态库加载下沉 + SO_CALL1 = 0x1007 # TODO(用户层):同上 + WAIT_WINDOW = 0x1008 # TODO(explorer):UI + CREATE_WINDOW = 0x1009 # TODO(explorer):UI + DRAW_TEXT = 0x100A # TODO(explorer):UI + GET_WINBUF = 0x100B # TODO(explorer):UI + WIN_FLUSH = 0x100C # TODO(explorer):UI + POLL_EVENT = 0x100D # TODO(explorer):UI + SET_CURSOR = 0x100E # TODO(explorer):UI + SET_TITLE = 0x100F # TODO(explorer):UI + SET_GEOMETRY = 0x1010 # TODO(explorer):UI + SET_RESIZABLE = 0x1011 # TODO(explorer):UI + GET_WIN_SIZE = 0x1012 # TODO(explorer):UI def _syscall0(num: uint64) -> uint64: ret: uint64 diff --git a/vpsdk/vpui.vp b/vpsdk/vpui.vp index ff567bd..7820e93 100644 --- a/vpsdk/vpui.vp +++ b/vpsdk/vpui.vp @@ -54,7 +54,7 @@ _hex_tbl: [17]char = "0123456789ABCDEF" _hex_buf: [20]char = "0000000000000000000" def _serial_puts(s: const str): - _syscall._syscall1(uint64(_syscall.SERIAL_PUTS), uint64(s)) + _syscall._syscall1(uint64(_syscall.Syscall.SERIAL_PUTS), uint64(s)) def _ptr_to_hex(val: uint64, buf: rawptr): buf[0] = 48 diff --git a/vpsdk/window.vp b/vpsdk/window.vp index a72387e..707a9fc 100644 --- a/vpsdk/window.vp +++ b/vpsdk/window.vp @@ -50,10 +50,10 @@ struct InputEvent: _pad2: uint8 def create_window(x: int, y: int, w: int, h: int, title: const str, style: int) -> int: - return int(syscall._syscall6(uint64(syscall.CREATE_WINDOW), uint64(x), uint64(y), uint64(w), uint64(h), uint64(title), uint64(style))) + return int(syscall._syscall6(uint64(syscall.Syscall.CREATE_WINDOW), uint64(x), uint64(y), uint64(w), uint64(h), uint64(title), uint64(style))) def draw_text(win_id: int, x: int, y: int, text: const str, color: uint32) -> int: - return int(syscall._syscall5(uint64(syscall.DRAW_TEXT), uint64(win_id), uint64(x), uint64(y), uint64(text), uint64(color))) + return int(syscall._syscall5(uint64(syscall.Syscall.DRAW_TEXT), uint64(win_id), uint64(x), uint64(y), uint64(text), uint64(color))) # 每窗口一份**用户态**后备缓冲(stdlib.malloc → MMAP → 0x20000000 用户堆)。 # 旧实现用 GET_WINBUF 把内核窗口缓冲地址直接交给 app,那片页 U=0 → app 一画就 #PF(err=0x7); @@ -73,32 +73,32 @@ def get_winbuf(win_id: int) -> uint32*: return uint32*(_winbufs[win_id]) def get_win_size(win_id: int) -> int: - return int(syscall._syscall2(uint64(syscall.GET_WIN_SIZE), uint64(win_id), 0)) + return int(syscall._syscall2(uint64(syscall.Syscall.GET_WIN_SIZE), uint64(win_id), 0)) def flush(win_id: int): buf: uint32* = get_winbuf(win_id) - syscall._syscall3(uint64(syscall.WIN_FLUSH), uint64(win_id), uint64(buf)) + syscall._syscall3(uint64(syscall.Syscall.WIN_FLUSH), uint64(win_id), uint64(buf)) def mainloop(win_id: int): - syscall._syscall1(uint64(syscall.WAIT_WINDOW), uint64(win_id)) + syscall._syscall1(uint64(syscall.Syscall.WAIT_WINDOW), uint64(win_id)) def poll_event(evt: InputEvent*) -> int: - return int(syscall._syscall1(uint64(syscall.POLL_EVENT), uint64(evt))) + return int(syscall._syscall1(uint64(syscall.Syscall.POLL_EVENT), uint64(evt))) def is_active(win_id: int) -> int: - return int(syscall._syscall2(uint64(syscall.WAIT_WINDOW), uint64(win_id), 1)) + return int(syscall._syscall2(uint64(syscall.Syscall.WAIT_WINDOW), uint64(win_id), 1)) def set_cursor_type(win_id: int, cursor_t: int): - syscall._syscall2(uint64(syscall.SET_CURSOR), uint64(win_id), uint64(cursor_t)) + syscall._syscall2(uint64(syscall.Syscall.SET_CURSOR), uint64(win_id), uint64(cursor_t)) def set_title(win_id: int, title: const str) -> int: - return int(syscall._syscall2(uint64(syscall.SET_TITLE), uint64(win_id), uint64(title))) + return int(syscall._syscall2(uint64(syscall.Syscall.SET_TITLE), uint64(win_id), uint64(title))) def set_geometry(win_id: int, x: int, y: int, w: int, h: int) -> int: - return int(syscall._syscall5(uint64(syscall.SET_GEOMETRY), uint64(win_id), uint64(x), uint64(y), uint64(w), uint64(h))) + return int(syscall._syscall5(uint64(syscall.Syscall.SET_GEOMETRY), uint64(win_id), uint64(x), uint64(y), uint64(w), uint64(h))) def set_resizable(win_id: int, rw: int, rh: int) -> int: - return int(syscall._syscall3(uint64(syscall.SET_RESIZABLE), uint64(win_id), uint64(rw), uint64(rh))) + return int(syscall._syscall3(uint64(syscall.Syscall.SET_RESIZABLE), uint64(win_id), uint64(rw), uint64(rh))) #class Window: # HWND: int