内核 MMAP(addr,length,prot,flags,fd,offset):fd=-1 + MAP_ANONYMOUS 走匿名映射(分配物理页、清零后映射到本进程新 VA,对齐 Linux"匿名必为零"语义);fd 是带 mmap_info 的 devfs 设备(当前仅 /dev/fb0)则把 [phys+offset, phys+offset+len) 按页映射进调用者地址空间(PTE_USER|WRITE)。addr/MAP_FIXED 暂未实现,一律由内核挑 VA 并返回真实起始地址。新增 PROT_*/MAP_*/MMAP_FD_ANON 常量。 参数次序与 Linux mmap 完全一致(rdi/rsi/rdx/r10/r8/r9),syscall_entry 的搬运顺序本就是这个约定,SDK 侧 vpsdk/syscall.vp 加 mmap() 助手走 _syscall6。stdlib.malloc 随之改为匿名映射调用(fd=-1、MAP_PRIVATE|MAP_ANONYMOUS、PROT_READ|PROT_WRITE),行为与原 MMAP(size) 一致且多一层清零。
146 lines
7.5 KiB
Plaintext
146 lines
7.5 KiB
Plaintext
# ============================================================================
|
||
# 系统调用号表(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)(目前空实现)
|
||
IOCTL = 16 # ioctl(fd, request, arg):设备控制(当前用于 /dev/fb0 查几何)
|
||
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
|
||
|
||
# ---- mmap 的 prot / flags(与内核 VKernel/intr/syscall.vp 及各 Linux 同名常量一致)----
|
||
define PROT_NONE = 0x0
|
||
define PROT_READ = 0x1
|
||
define PROT_WRITE = 0x2
|
||
define PROT_EXEC = 0x4
|
||
define MAP_SHARED = 0x01
|
||
define MAP_PRIVATE = 0x02
|
||
define MAP_FIXED = 0x10
|
||
define MAP_ANONYMOUS = 0x20
|
||
# fd = -1(Linux 匿名映射约定)
|
||
define MMAP_FD_ANON: uint64 = 0xFFFFFFFFFFFFFFFF
|
||
|
||
def _syscall0(num: uint64) -> uint64:
|
||
ret: uint64
|
||
__asm__(f"""mov rax, {asminp(num, ASM_DESCR.REG_ANY)}
|
||
syscall""",
|
||
out=[asmout(ret, ASM_DESCR.OUTPUT_REG)],
|
||
op=[ASM_DESCR.CLOBBER_MEMORY, ASM_DESCR.CLOBBER_RCX,
|
||
ASM_DESCR.CLOBBER_R11])
|
||
return ret
|
||
|
||
def _syscall1(num: uint64, a1: uint64) -> uint64:
|
||
ret: uint64
|
||
__asm__(f"""mov rdi, {asminp(a1, ASM_DESCR.REG_ANY)}
|
||
mov rax, {asminp(num, ASM_DESCR.REG_ANY)}
|
||
syscall""",
|
||
out=[asmout(ret, ASM_DESCR.OUTPUT_REG)],
|
||
op=[ASM_DESCR.CLOBBER_MEMORY, ASM_DESCR.CLOBBER_RCX,
|
||
ASM_DESCR.CLOBBER_R11, ASM_DESCR.CLOBBER_RDI])
|
||
return ret
|
||
|
||
def _syscall2(num: uint64, a1: uint64, a2: uint64) -> uint64:
|
||
ret: uint64
|
||
__asm__(f"""mov rdi, {asminp(a1, ASM_DESCR.REG_ANY)}
|
||
mov rsi, {asminp(a2, ASM_DESCR.REG_ANY)}
|
||
mov rax, {asminp(num, ASM_DESCR.REG_ANY)}
|
||
syscall""",
|
||
out=[asmout(ret, ASM_DESCR.OUTPUT_REG)],
|
||
op=[ASM_DESCR.CLOBBER_MEMORY, ASM_DESCR.CLOBBER_RCX,
|
||
ASM_DESCR.CLOBBER_R11, ASM_DESCR.CLOBBER_RDI,
|
||
ASM_DESCR.CLOBBER_RSI])
|
||
return ret
|
||
|
||
def _syscall3(num: uint64, a1: uint64, a2: uint64, a3: uint64) -> uint64:
|
||
ret: uint64
|
||
__asm__(f"""mov rdi, {asminp(a1, ASM_DESCR.REG_ANY)}
|
||
mov rsi, {asminp(a2, ASM_DESCR.REG_ANY)}
|
||
mov rdx, {asminp(a3, ASM_DESCR.REG_ANY)}
|
||
mov rax, {asminp(num, ASM_DESCR.REG_ANY)}
|
||
syscall""",
|
||
out=[asmout(ret, ASM_DESCR.OUTPUT_REG)],
|
||
op=[ASM_DESCR.CLOBBER_MEMORY, ASM_DESCR.CLOBBER_RCX,
|
||
ASM_DESCR.CLOBBER_R11, ASM_DESCR.CLOBBER_RDI,
|
||
ASM_DESCR.CLOBBER_RSI, ASM_DESCR.CLOBBER_RDX])
|
||
return ret
|
||
|
||
def _syscall5(num: uint64, a1: uint64, a2: uint64, a3: uint64, a4: uint64, a5: uint64) -> uint64:
|
||
ret: uint64
|
||
__asm__(f"""mov rdi, {asminp(a1, ASM_DESCR.REG_ANY)}
|
||
mov rsi, {asminp(a2, ASM_DESCR.REG_ANY)}
|
||
mov rdx, {asminp(a3, ASM_DESCR.REG_ANY)}
|
||
mov r10, {asminp(a4, ASM_DESCR.REG_ANY)}
|
||
mov r8, {asminp(a5, ASM_DESCR.REG_ANY)}
|
||
mov rax, {asminp(num, ASM_DESCR.REG_ANY)}
|
||
syscall""",
|
||
out=[asmout(ret, ASM_DESCR.OUTPUT_REG)],
|
||
op=[ASM_DESCR.CLOBBER_MEMORY, ASM_DESCR.CLOBBER_RCX,
|
||
ASM_DESCR.CLOBBER_R11, ASM_DESCR.CLOBBER_RDI,
|
||
ASM_DESCR.CLOBBER_RSI, ASM_DESCR.CLOBBER_RDX,
|
||
ASM_DESCR.CLOBBER_R10, ASM_DESCR.CLOBBER_R8])
|
||
return ret
|
||
|
||
def _syscall6(num: uint64, a1: uint64, a2: uint64, a3: uint64, a4: uint64, a5: uint64, a6: uint64) -> uint64:
|
||
ret: uint64
|
||
__asm__(f"""mov rdi, {asminp(a1, ASM_DESCR.REG_ANY)}
|
||
mov rsi, {asminp(a2, ASM_DESCR.REG_ANY)}
|
||
mov rdx, {asminp(a3, ASM_DESCR.REG_ANY)}
|
||
mov r10, {asminp(a4, ASM_DESCR.REG_ANY)}
|
||
mov r8, {asminp(a5, ASM_DESCR.REG_ANY)}
|
||
mov r9, {asminp(a6, ASM_DESCR.REG_ANY)}
|
||
mov rax, {asminp(num, ASM_DESCR.REG_ANY)}
|
||
syscall""",
|
||
out=[asmout(ret, ASM_DESCR.OUTPUT_REG)],
|
||
op=[ASM_DESCR.CLOBBER_MEMORY, ASM_DESCR.CLOBBER_RCX,
|
||
ASM_DESCR.CLOBBER_R11, ASM_DESCR.CLOBBER_RDI,
|
||
ASM_DESCR.CLOBBER_RSI, ASM_DESCR.CLOBBER_RDX,
|
||
ASM_DESCR.CLOBBER_R10, ASM_DESCR.CLOBBER_R8,
|
||
ASM_DESCR.CLOBBER_R9])
|
||
return ret
|
||
|
||
def mmap(addr: uint64, length: uint64, prot: uint64, flags: uint64, fd: uint64, offset: uint64) -> uint64:
|
||
"""mmap(addr, length, prot, flags, fd, offset):返回映射起始 VA,失败返回 0。
|
||
|
||
匿名映射:fd = MMAP_FD_ANON(-1) 且 flags 带 MAP_ANONYMOUS;
|
||
映射设备(如 /dev/fb0):fd 传该设备的 fd。addr / MAP_FIXED 由内核挑地址。
|
||
(定义放在 _syscall6 之后,避免同模块内前向引用。)
|
||
"""
|
||
return _syscall6(uint64(Syscall.MMAP), addr, length, prot, flags, fd, offset)
|