内核 devfs 新增 shm_device(/dev/desk):同一物理区间映射给所有打开者;main.vp 启动时 mm.malloc 出 DESK_SHM_SIZE(8MB) 并登记,分配失败只打日志跳过(explorer 的 open 会明确失败,不静默兜底)。内核只负责"分配 + 共享映射",区间内布局完全不参与。 vpsdk/desk.vp(新增协议模块):共享区固定布局(DeskHeader / WinSlot / 请求环 / 每窗口事件环 / 像素 arena)、单生产者单消费者环形队列(head/tail,跨进程无锁、全程指针直读写)、explorer 用的 desk_format/desk_arena_alloc 与 app 用的 desk_ready。请求/事件类型常量齐备(CREATE/DESTROY/MOVE/RESIZE/TITLE/FLUSH/ACTIVATE 与 CREATED/CLOSE/KEY/MOUSE/RESIZE)。 vpsdk/devfs.vp 增 DEV_DESK 与 shm_map();Explorer 启动即 open+mmap /dev/desk、desk_format 初始化并打印头信息,验证 IPC 底座可用。
68 lines
2.5 KiB
Plaintext
68 lines
2.5 KiB
Plaintext
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)
|