Files
ViperOS/vpsdk/devfs.vp
T
TermiNexus 5e1cd04478 feat(s4): 删除 SERIAL_PUTS 私有 syscall,用户态改走 /dev/serial0
内核:删掉 SERIAL_PUTS 的枚举项/派发分支/处理函数(内核自身的 serial.puts 是直接驱动调用,不受影响)。SDK:vpsdk/devfs.vp 新增 serial_puts()(惰性 open /dev/serial0 一次 + write),syscall.vp 删掉该成员。

调用点全部切到 devfs.serial_puts:vpsdk/stdio.vp 的 printf、vpsdk/vpui.vp 的 _serial_puts、Apps/Terminal 的 _sdbg、Apps/Explorer 的 _dbg、Libs/SerialLogger 的 log_info/log_warn(.so 同样走设备节点)。顺带清掉因此失效的 import(vpui 的 _syscall、Terminal 的 _syscall、Explorer 的 syscall)。

至此私有段只剩 7 项:TELL/SIZE/OPENDIR/READDIR/CLOSEDIR(可由 lseek/fstat/openat+getdents64 表达)与 LOAD_SO/SO_CALL1(动态库加载待下沉用户层)。
2026-10-16 19:17:39 +08:00

86 lines
3.1 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import vpsdk.fs as fs
import vpsdk.syscall as syscall
import string
from stdint import *
# ============================================================================
# devfs 设备层:设备节点路径 + 各设备的专用读写/控制助手。
#
# 设备节点由内核在启动时注册(见 VKernel/Kernel/main.vp 的 devfs_register_*),
# 用户态用普通 open/read/write/ioctl 访问 —— 不再有"设备专用 syscall"。
# ============================================================================
# 路径必须与内核注册名逐字一致
define DEV_SERIAL0 = "/dev/serial0"
define DEV_SERIAL1 = "/dev/serial1"
define DEV_FB0 = "/dev/fb0"
define DEV_KBD = "/dev/input/keyboard"
define DEV_MOUSE = "/dev/input/mouse"
define DEV_DESK = "/dev/desk"
# ioctl 命令与返回结构:必须与 VKernel/Kernel/drivers/devfs/devfs.vp 的
# FB_GET_INFO / FbInfo 逐字段一致(packed;4×u32 + 2×u64 = 32 字节)。
define FB_GET_INFO = 0x4600
@__attribute__(packed)
class FbInfo:
width: uint32
height: uint32
pitch: uint32
format: uint32
size: uint64
phys: uint64
def fb_open() -> int:
return fs.open(DEV_FB0, uint32(0))
def fb_get_info(fd: int) -> FbInfo:
"""查 framebuffer 几何 / 格式 / 物理区间。失败时返回全 0(size == 0 即可判失败)。"""
info: FbInfo
string.memset(&info, 0, FbInfo.__sizeof__())
fs.ioctl(fd, uint32(FB_GET_INFO), &info)
return info
def fb_map(fd: int, size: uint64) -> uint64:
"""把 framebuffer 映射进本进程,返回线性起始地址(0 = 失败),之后可直接写像素。
走通用 mmap(fd = 该设备 fd):内核按设备的 mmap_info 把物理区间按页映射进来。
"""
return syscall.mmap(0, size, uint64(syscall.PROT_READ | syscall.PROT_WRITE),
uint64(syscall.MAP_SHARED), uint64(fd), 0)
def kbd_open() -> int:
return fs.open(DEV_KBD, uint32(0))
def mouse_open() -> int:
return fs.open(DEV_MOUSE, uint32(0))
def shm_map(fd: int, size: uint64) -> uint64:
"""把共享内存设备映射进本进程,返回线性起始地址(0 = 失败)。
与 fb_map 同一机制(设备 mmap_info 给出的物理区间);不同点在于 /dev/desk
的区间对**所有**打开者都是同一块物理内存,因此天然可跨进程共享。
"""
return syscall.mmap(0, size, uint64(syscall.PROT_READ | syscall.PROT_WRITE),
uint64(syscall.MAP_SHARED), uint64(fd), 0)
# /dev/serial0 的 fd 惰性打开一次(-1 = 还没开;-2 = 开失败过,不再重试)
_serial_fd: int = -1
def serial_puts(msg: const str) -> int:
"""把字符串写到 /dev/serial0 —— 替代已删除的 SERIAL_PUTS syscall。
内核侧 serial0 设备的 write 按 C 字符串输出(内部就是 serial.puts),
所以这里只需把指针与长度递下去。
"""
global _serial_fd
if _serial_fd == -1:
_serial_fd = fs.open(DEV_SERIAL0, uint32(0))
if _serial_fd < 0:
_serial_fd = -2
if _serial_fd < 0: return -1
if msg is None: return -1
return fs.write(_serial_fd, msg, uint32(string.strlen(msg)))