内核:删掉 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(动态库加载待下沉用户层)。
79 lines
2.8 KiB
Plaintext
79 lines
2.8 KiB
Plaintext
import vpsdk.devfs as devfs
|
||
import vpsdk.desk as desk
|
||
import vpsdk.process as process
|
||
from stdint import *
|
||
import viperlib
|
||
import desk_server
|
||
|
||
|
||
def _dbg(msg: const str):
|
||
# S4:改走 /dev/serial0(SERIAL_PUTS 私有 syscall 已删除)
|
||
devfs.serial_puts(msg)
|
||
|
||
|
||
@__attribute__(section(".text.startup"), aligned(16))
|
||
export def _start() -> int:
|
||
_dbg("[explorer] start\n")
|
||
|
||
# 1) 打开 framebuffer 设备,问几何,再映射成线性地址
|
||
fb_fd: int = devfs.fb_open()
|
||
if fb_fd < 0:
|
||
_dbg("[explorer] open /dev/fb0 FAILED\n")
|
||
process.exit(1)
|
||
return 0
|
||
|
||
info: devfs.FbInfo = devfs.fb_get_info(fb_fd)
|
||
buf: [160]char
|
||
viperlib.snprintf(&buf, 160,
|
||
"[explorer] fb %ux%u pitch=%u fmt=%u size=%lu phys=0x%lx\n",
|
||
info.width, info.height, info.pitch, info.format, info.size, info.phys)
|
||
_dbg(&buf)
|
||
|
||
fb_va: uint64 = devfs.fb_map(fb_fd, info.size)
|
||
if fb_va == 0:
|
||
_dbg("[explorer] mmap /dev/fb0 FAILED\n")
|
||
process.exit(1)
|
||
return 0
|
||
|
||
buf2: [96]char
|
||
viperlib.snprintf(&buf2, 96, "[explorer] fb mapped at 0x%lx\n", fb_va)
|
||
_dbg(&buf2)
|
||
|
||
# 2) 屏幕几何/映射地址已打印(上面两行),像素通路由此验证;真正的绘制在服务端。
|
||
fb: uint32* = uint32*(fb_va)
|
||
|
||
# 4) 输入设备可达性:能 open 到就说明 /dev/* 通路已打通
|
||
# (真正读事件、接管窗口合成放到 S3 —— 内核桌面此刻还在抢同一个 PS/2 口)。
|
||
kfd: int = devfs.kbd_open()
|
||
mfd: int = devfs.mouse_open()
|
||
buf3: [96]char
|
||
viperlib.snprintf(&buf3, 96, "[explorer] input: kbd=%d mouse=%d\n", kfd, mfd)
|
||
_dbg(&buf3)
|
||
|
||
# 5) 挂上 /dev/desk 共享区并格式化 —— explorer 是图形壳,共享区由它初始化,
|
||
# app 侧只 desk_ready() 校验。这里先把头打出来证明 IPC 底座可用。
|
||
desk_fd: int = desk.desk_open()
|
||
if desk_fd < 0:
|
||
_dbg("[explorer] open /dev/desk FAILED\n")
|
||
process.exit(1)
|
||
return 0
|
||
shm: uint64 = desk.desk_map(desk_fd)
|
||
if shm == 0:
|
||
_dbg("[explorer] mmap /dev/desk FAILED\n")
|
||
process.exit(1)
|
||
return 0
|
||
desk.desk_format(shm, info.width, info.height, info.pitch)
|
||
hdr: desk.DeskHeader* = desk.DeskHeader*(shm + desk.desk_header_off())
|
||
buf4: [144]char
|
||
viperlib.snprintf(&buf4, 144,
|
||
"[explorer] desk shm=0x%lx ready=%d slot=%lu arena=%u\n",
|
||
shm, hdr.ready, uint64(desk.desk_slot_size()), hdr.arena_off)
|
||
_dbg(&buf4)
|
||
|
||
# 6) 进入窗口服务端主循环(永不返回):请求环 + 输入 + 合成。
|
||
srv: desk_server.DeskServer = desk_server.DeskServer()
|
||
srv.init(fb, int(info.width), int(info.height), int(info.pitch), info.format, shm, kfd, mfd)
|
||
_dbg("[explorer] desk server running\n")
|
||
srv.serve()
|
||
return 0
|