这是一个在 HarmonyOS NEXT 设备上运行 QEMU 虚拟机的应用工程 的配套的增强工具(虚拟机App名字叫做Aether Engine 目标是“鸿蒙版 UTM”):让 MatePad/鸿蒙电脑在本地离线运行 Windows / Linux 来宾系统,并逐步做到“像系统功能一样好用”的集成体验(文件互通、碰一碰、相机/周边能力等)。
- 在鸿蒙设备上把 QEMU 跑起来:QEMU 核心(第三方)+ Host 应用(ArkTS)+ Native 桥(C++/NAPI)三层配合。
- 性能与兼容性:优先检测宿主是否能访问
/dev/kvm(硬件虚拟化)→ 不可用则自动降级 TCG(软件翻译)保证能跑。 - 日常使用体验:安装期用 VNC,日常用 RDP;网络用 hostfwd 映射;共享目录用于 Host↔Guest 互通。(这个你不用管 你做增强工具)
- [] “一体化”集成(AET):做我们自己的 Guest Additions(Aether Enhanced Tools),让 Guest 能调用 Host 的“鸿蒙能力”(附近设备/分布式相机/文件选择等),并把结果回传给 Guest。
- 增强工具的UI层
- 上层
ArkTS页面负责 VM 管理、诊断工具、分享/碰一碰交互、VNC等。 - QEMU里面的这个Windows和Linux虚拟机就用Avalonia这UI框架 然后呢配合点Net 8的底层的这个
AetherEnhancedTools.UI去提供这个增强工具的显示UI
- 上层
- 控制/观测通道
- QMP:Host ↔ QEMU 的控制面(QEMU和ArkTS层已存在
qmp.sock,用于 query-status、screendump 等),我们也需要把他(QEMU Guest Bridge)集成到Aether Enhanced Tools的安装程序里面 - 共享目录(Linux:virtio-9p;Windows:virtio-fs/viofs):Host↔Guest 的文件通道(tag=
hostshare)。Windows 上 upstream virtio-win 没有vio9p.inf,推荐走viofs(virtio-fs)+ WinFsp。 - Aether Bridge(文件型 RPC):Guest(AET) ↔ Host(App) 的能力调用协议(
.aether_bridge/)。
- QMP:Host ↔ QEMU 的控制面(QEMU和ArkTS层已存在
- QMP(已做)
- 我们已经在 QEMU 启动参数里启用了
-qmp unix:.../qmp.sock,server,nowait - Host 侧已有接口去连这个 socket 做状态查询/截图等
- 我们已经在 QEMU 启动参数里启用了
- QGA(规划要补)
- QGA 是“标准 QEMU Guest Agent”(guest 内服务),一般通过 virtio-serial 暴露
org.qemu.guest_agent.0 - 当前仓库:有 QMP,但还没把 QGA 通道(virtio-serial + guest-agent port)接进启动参数,也还没实现
guest-*命令调用 - 结论:QGA 可以做,但需要补 QEMU args + Host 调用层(这正好对应你后面要做的安装器里“装 QGA”那一步)
- QGA 是“标准 QEMU Guest Agent”(guest 内服务),一般通过 virtio-serial 暴露
- AET(我们自己的 Guest Tools,这是你需要负责的部分)
- AET 不等于 virtio-win,不等于 QGA:它是“产品集成层”的 Guest Additions
- 我们 Phase1 选用 共享目录上的文件型 RPC,原因:
- 不依赖长连接/端口,不容易被系统策略/网络隔离搞死
- Host 侧可以明确控制权限(例如“不把 QMP 暴露给 Guest”)
AetherEnhancedTools.Agent:它是 Guest 里的“常驻 Agent(守护进程/服务),运行在 Windows/Linux 来宾系统里,负责维持在线、监听/处理来自 Host 的事件、管理 Guest 侧能力:文件同步、驱动状态、QGA 状态、虚拟相机/剪贴板啊、以及给 UI 提供本地 API(例如本机 IPC / named pipe / localhost HTTP / gRPC)AetherEnhancedTools.Core:放“跨平台通用的核心逻辑”,给 Agent 和 UI 共用,比如说.aether_bridge的协议客户端啊、数据模型:Hello/Heartbeat/Status、错误码 路径/挂载检测(hostshare mount 点探测)啊,以及日志、配置(JSON config)、版本信息AetherEnhancedTools.UI:Avalonia界面 给用户看的AetherEnhancedTools.sln:整个解决方案
协议版本:aether.bridge.v1
位置:每个 VM 的共享目录内:<vmSharedDir>/.aether_bridge/
补充约定(Host↔Guest 对齐):
- 共享根目录同时包含:
.aether_bridge/:内部协议目录(RPC +host_input状态流),不建议作为用户文件入口nearby-huaweis/:用户可见目录(“附近的华为”入口,适合做快捷方式/盘符映射)
- 详见:
docs/shared-folder-layout.md
目录结构(Guest 与 Host 约定):
req/:Guest → Host 请求(*.json)res/:Host → Guest 响应(<requestId>.json)evt/:预留(事件流)blob/:预留(大文件/帧数据等)host_input/:Host → Guest 高频输入状态流(多指/笔压),不走req/res(详见:docs/host-input-bridge.md)
请求文件规则(很关键):
- Guest 写
*.json.tmp→ rename 成*.json(保证原子性,Host 不读半截)
最小握手(必须):
aet.hello:AET 启动后先发一次,上报版本/OS/实例 IDaet.heartbeat:建议每 4 秒一次;Host TTL 默认 ~12 秒(超时视为离线)aet.getStatus:调试用,查询 Host 记录的在线状态
Host 侧实现位置:
entry/src/main/ets/utils/GuestAgentBridge.ets- 轮询
req/,按method分发处理,写回res/ - 安全原则:Host 不把 QMP 暴露给 Guest
- 轮询
这个目录就是“给 Guest 侧开发/联调用”的最小样例合集:
用途:
- 演示 Windows Guest 如何通过
.aether_bridge发请求并等响应 - 发送:
aet.helloaet.heartbeat(默认 4s)
- 依赖:
- Windows Guest 已能访问共享目录(推荐 virtio-fs/viofs 挂载出来的盘符/路径)
.aether_bridge\req与.aether_bridge\res已存在
运行方式(Guest 内):
- 先确保共享目录挂载可用
- 再运行(名字和指令示例):
aet_minimal_windows.exe --mount <MOUNT>用途:
- 同样实现
aet.hello+aet.heartbeat - 额外演示一个“重能力”调用:
camera.stream.start- Host 会把帧落到共享目录的
blob/(PPM + meta.json) - 脚本会读取帧并可选推送到 Linux 的 v4l2loopback 虚拟摄像头(用 ffmpeg)
- Host 会把帧落到共享目录的
依赖(Guest 内):
- 已挂载共享目录,且
.aether_bridge/req/res/blob存在 - 如要虚拟摄像头:需要
v4l2loopback+ffmpeg
运行示例:
sudo modprobe v4l2loopback devices=1 video_nr=10 card_label="AetherCam" exclusive_caps=1
python3 aet_minimal_linux.py --mount <MOUNT> --video /dev/video10 --source testPattern可选 --source distributedCamera,并传 --device-id/--camera-id。
用途:
- 在 Guest(Windows/Linux 都行)里,自动扫描局域网 HDC 端口,减少手动输入
ip:port - 常用场景:
- 你在 Guest 里写脚本/工具,要辅助连上宿主(或另一台设备)做部署/调试
用法示例:
python3 aet_hdc_connect.py --scan --port 8710 --connect
# 或指定
python3 aet_hdc_connect.py --target 192.168.1.23:8710 --connect如 hdc 不在 PATH,可用 --hdc "C:\path\to\hdc.exe"。
用途:
- 这是你说的那个 “AetherEnhancedToolsSetup.exe 一把梭” 模式的 源码骨架
- 目标流程(已按你描述写死顺序):
- 提权(管理员)
- 解压/复制 payload 到
%TEMP% - 用
pnputil装 VirtIO 关键驱动(vioser.inf+(vio9p.inf或viofs.inf)) - 静默安装 AET(优先 MSI)
- 静默安装 QGA(MSI)
- payload 约定目录(运行时与 exe 同级):
payload/virtio/:解压后的 virtio-win 驱动树(里面要能找到vioser.inf,以及共享目录驱动:viofs.inf或你们自有的vio9p.inf)payload/winfsp/:WinFsp 安装包(winfsp-*.msi,Windows 走 virtio-fs/viofs 时必须)payload/aet/:你的 AET 安装包(MSI 优先)payload/qga/:QGA 安装包(MSI)
注意:
- 这是 skeleton:第三方包版本不同,细节可能需要你后续补强(校验/回滚/组件选择等)
- 不要把大二进制提交进 git:payload 应该被
.gitignore忽略(建议在windows_setup/下放一个.gitignore专门忽略payload/)