feat(explorer): S2 —— 新增图形壳应用 explorer 骨架,用户态经 devfs+mmap 直接写屏
Apps/Explorer:复制标准 app 骨架(main.vp / linker.ld / project.vpj,链接地址 0x400000)。启动流程:open /dev/fb0 → ioctl(FB_GET_INFO) 打几何 → mmap 拿到线性地址 → 等约 2 秒(等内核桌面首屏全量重绘过去)→ 画一条渐变横条验证像素真上屏 → open /dev/input/keyboard|mouse 验证输入设备可达 → 常驻不退出。 vpsdk/devfs.vp(新增 SDK 设备层):设备路径常量(与内核注册名逐字一致)、FB_GET_INFO 与 FbInfo 镜像(packed,与内核同布局)、fb_open/fb_get_info/fb_map/kbd_open/mouse_open。 build.py:把 Explorer 加进 required_apps 清单与完整构建分支;内核 main.vp 在四个 app 之后 spawn /APPS/explorer.elf。内核 desktop 与 explorer 并存属迁移中间态,S3 会把窗口合成整体交出去。
This commit is contained in:
1 parent
7d5380148b
commit
6bd2390e08
6 files changed
+216
No files matched your search
@@ -0,0 +1,39 @@
|
||||
ENTRY(__entry)
|
||||
|
||||
SECTIONS {
|
||||
. = 0x400000;
|
||||
|
||||
.text : {
|
||||
__entry = .;
|
||||
*(.text.startup)
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
}
|
||||
|
||||
.rodata : {
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
}
|
||||
|
||||
.data : {
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
}
|
||||
|
||||
.bss : {
|
||||
__bss_start = .;
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
__bss_end = .;
|
||||
}
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.comment)
|
||||
*(.note)
|
||||
*(.eh_frame)
|
||||
*(.eh_frame_hdr)
|
||||
*(.reloc)
|
||||
*(.rela)
|
||||
*(.debug*)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
import vpsdk.devfs as devfs
|
||||
import vpsdk.process as process
|
||||
import vpsdk.syscall as syscall
|
||||
from stdint import *
|
||||
import viperlib
|
||||
|
||||
|
||||
def _dbg(msg: const str):
|
||||
syscall._syscall1(uint64(syscall.Syscall.SERIAL_PUTS), uint64(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) 等桌面把首屏全量重绘做完(否则刚写的像素会被 _mark_all_dirty 的首次重绘盖掉)。
|
||||
# 这里没有时钟可用,就空转 yield:yield_cpu 约每 10ms 真让出一次,200 次约 2 秒。
|
||||
for _i in range(200):
|
||||
process.yield_cpu()
|
||||
|
||||
# 3) 画一条横贯屏幕的渐变条 —— 证明"用户态直接写 framebuffer 真的上屏"。
|
||||
w: int = int(info.width)
|
||||
h: int = int(info.height)
|
||||
pitch_px: int = int(info.pitch) / 4
|
||||
pixels: uint32* = uint32*(fb_va)
|
||||
y0: int = h / 3
|
||||
y1: int = y0 + h / 6
|
||||
for y in range(y0, y1):
|
||||
row: int = y * pitch_px
|
||||
for x in range(w):
|
||||
rr: int = (x * 255) / w
|
||||
bb: int = 255 - rr
|
||||
pixels[row + x] = uint32((rr << 16) | (0x78 << 8) | bb)
|
||||
_dbg("[explorer] painted gradient band\n")
|
||||
|
||||
# 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)
|
||||
|
||||
# 图形壳暂时只是占位,常驻不退出(app 的 _start 绝不能再 return:栈顶下一格是 0)。
|
||||
while True:
|
||||
process.yield_cpu()
|
||||
return 0
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "Explorer",
|
||||
"version": "1.0.0",
|
||||
"source_dir": "./",
|
||||
"build_dir": "./__vpcbuild__",
|
||||
"compiler": {
|
||||
"cmd": "llc",
|
||||
"flags": ["-filetype=obj", "-mtriple=x86_64-none-elf", "-relocation-model=static", "-O2"]
|
||||
},
|
||||
"linker": {
|
||||
"cmd": "ld.lld.exe",
|
||||
"flags": [
|
||||
"-m", "elf_x86_64",
|
||||
"-T", "linker.ld",
|
||||
"--oformat", "elf64-x86-64",
|
||||
"--strip-all"
|
||||
],
|
||||
"output": "explorer.elf"
|
||||
},
|
||||
"includes": ["../..", "../../../../includes"],
|
||||
"target": {
|
||||
"triple": "x86_64-none-elf",
|
||||
"datalayout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||
},
|
||||
"options": {
|
||||
"slice_level": 3,
|
||||
"target": "llvm",
|
||||
"strict_mode": true
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user