86Box 虚拟机操作
每当任务要求启动、配置、等待、重启、调试或检查 86Box 虚拟机时,请使用本技能。
不可协商的安全规则
- 在启动前确定精确的虚拟机目录。
- 使用
--vmpath <虚拟机目录> --vmname <显示名称>启动。 - 记录启动后返回的 PID 以及稳定的工具进程名。
- 在发送任何信号前,使用可执行文件和精确的
--vmpath验证 PID 身份。 - 禁止使用
killall、宽泛的pkill、宽泛的pgrep或未经验证的 PID。 - 假设其他人正在运行独立的 86Box 进程。
- 当 NVRAM 或配置更改较为重要时,优先使用干净的 UI 关闭。
- 切勿为了单虚拟机实验而覆盖共享的 ROM;应克隆完整的 ROM 集,并使用
--rompath选择克隆后的路径。
前置检查
-
在平台虚拟机根目录下解析一个名称。在 macOS 上:
~/Library/Application Support/86Box/Virtual Machines/<名称>直接指定虚拟机路径也是有效的。
-
读取
<虚拟机>/86box.cfg。记录:machine;cpu_use_dynarec;- 可选的
gdbstub_port; - 配置的介质和适配器设备。
-
选择二进制文件:
- 正常交互:
/Applications/86Box.app/Contents/MacOS/86Box; - 客户机调试:本地编译的
-DGDBSTUB=ON版本。
- 正常交互:
-
审计命令(在 86Box-tool 项目根目录运行,或安装后运行):
cd ~/src/86Box-tool && uv run ./86boxctl.sh <虚拟机> command -
如果调试多个虚拟机,要求在每份配置中设置不同的
gdbstub_port,并设置cpu_use_dynarec = 0。
启动
独立控制器:
./86boxctl.sh <虚拟机> start
./86boxctl.sh <虚拟机> start --gdb-stub
打过补丁的 IBM PS/2 Model 80 Type 2 BIOS:
./86boxctl.sh <虚拟机> command \
--model-80-type-2-rom /path/to/sequential-128k.bin
./86boxctl.sh <虚拟机> start \
--model-80-type-2-rom /path/to/sequential-128k.bin
虚拟机必须使用 machine = ibmps2_m80。控制器会探测平台默认的 ROM 根目录,将完整的 ROM 树克隆到 <虚拟机>/romsets/ 下,将镜像拆分为活跃的偶数/奇数通道文件,进行验证,然后通过 --rompath 使用生成的根目录启动。当探测有歧义时,请使用 --rom-source。使用 prepare-roms 可在不启动的前提下构建 ROM 集。
对于通过工具进行长时间 GUI 会话的情况,请通过工具进程管理器启动可执行文件,格式如下:
name = 唯一的稳定名称,例如 86box-automatic-configuration
application = 选择的 86Box 二进制文件
args = [--vmpath, <绝对虚拟机目录>, --vmname, <显示名称>]
pty = false
persist = true (当交互跨越多个回合时)
记录返回的 PID。后续的 describe、logs、restart 和 stop 操作只能使用该稳定的进程名。重启会产生新的 PID,请重新记录。
不要将 86box.cfg 作为唯一的定位参数传递。那样只能选择配置,但不会设置 86Box 的虚拟机用户文件路径,因此相对路径的介质、NVRAM 和本地 ROM 可能解析到错误的目录。
确认就绪
仅创建进程并不代表客户机已就绪。
- 正常版本:要求该精确进程在启动后存活,然后检查可见的虚拟机或具体的虚拟机工件。
- GDB 版本:要求该虚拟机配置的 RSP 端口处于监听状态。
- 切勿将其他 86Box 进程或端口作为该虚拟机的就绪证据。
使用:
./86boxctl.sh <虚拟机> status
./86boxctl.sh <虚拟机> logs --lines 100
等待用户
当用户要求等待到工具中断时,请完全照做。除非用户明确要求做退出触发的工作,否则不要在虚拟机退出时继续执行。工具的任务等待器不会将托管的 GUI 进程视为后台任务,因此请创建一个长时间运行的有限异步等待哨兵,以无限的工具超时等待该任务,并在用户中断后取消它。
请使用稳定的进程名和 PID 分别跟踪虚拟机进程。
观察
宿主机生命周期
./86boxctl.sh <虚拟机> status
./86boxctl.sh <虚拟机> wait
./86boxctl.sh <虚拟机> logs --lines 100
客户机屏幕、控制台和内存
两个独立的路径:
-
RSP 存根(需要 GDB-stub 版本;连接后会暂停客户机):
RSP_PORT=<端口> ./rsp.py probe RSP_PORT=<端口> ./rsp.py video-mode RSP_PORT=<端口> ./rsp.py screen RSP_PORT=<端口> ./rsp.py wait-screen "期望文本" --wait-timeout 600 RSP_PORT=<端口> ./rsp.py dump b8000 fa0在文本模式
0、1、2、3和7下,screen选择 40x25 或 80x25,使用B8000h(彩色)或B0000h(单色),并遵循活跃的视频页面。在图形模式11h下,它读取位于A0000h的打包 640x480 1bpp 帧缓冲,恢复客户机运行,并让工具的配置@vision模型解释生成的 PNG 文件。omp必须在PATH中;使用--vision-question自定义提示。快照命令仅在检查时暂停,并在模型推理前分离。 -
Memdump 服务器(无 GDB 存根,不暂停 CPU):在虚拟机配置中设置
memdump_port。使用实时差量视图轮询文本帧缓冲:./screenmon.py --memdump-port 12348 # 交互式 TTY:ANSI 差量 ./screenmon.py --memdump-port 12348 --plain # 管道:完整帧 + 变更行 ./screenmon.py --memdump-port 12348 --count 30 --interval 0.1screenmon.py仅渲染两次轮询之间发生变化的内容;模式由isatty()自动选择,除非使用--full/--plain覆盖。默认间隔为 0.1 秒。
对于持续的双向操作:
# 交互式 ANSI 镜像;Ctrl-] 分离
RSP_PORT=<端口> ./guest_console.py
# 可处理的屏幕和差量事件
RSP_PORT=<端口> ./guest_console.py \
--format jsonl --no-input --duration 10
# 通过 BIOS 键盘环输入 DOS 命令
RSP_PORT=<端口> ./guest_console.py \
--send "DIR" --enter --duration 10
# 早期 POST 需要硬件扫描码注入
RSP_PORT=<端口> ./guest_console.py \
--input-mode hardware --key F1 --duration 5
控制台以 70 Hz 采样,保留完整的字符/属性缓冲区,仅输出合并后的变更运行。TTY 获得 ANSI 光标更新;重定向输出默认为 JSONL。输入在启动后默认为经过验证的 BIOS 键盘环。硬件模式通过模拟的 8042 注入速度化的 Set-1 扫描字节用于 POST。保留 Ctrl-] 用于分离,以便客户机的 Ctrl-C 保持可用。
切勿仅凭注入的按键就推断成功。必须观察所产生的屏幕差量或明确的客户机输出。
持久虚拟机配置
在干净关闭后,仅检查解析后的虚拟机目录:
<虚拟机>/86box.cfg
<虚拟机>/nvr/<machine>.nvr
<虚拟机>/nvr/<machine>_sec.nvr
对于此仓库:
uv run --project . refdisk-view-config --vm <名称> --adf-source rf7080a/disk
在 86Box UI 中添加卡片并不会自动填充客户机 MCA NVRAM。客户机参考盘必须配置 POS 状态,且 86Box 必须干净地保存它。
ROM 验证
machine = ... 决定了所需的 ROM 文件名。检查:
86boxctl status记录的精确--rompath(如果存在);- 生成集中的
.86boxctl-romset.json; - 来自 86Box 机器定义的精确活跃文件名;
- 这些活跃文件的哈希值或字节比较。
对于此工作流,显式的 --rompath 必须包含完整的 86Box ROM 集。尽管 86Box 可以回退到其他搜索根目录,但完整性可以使运行自包含,并防止静默混合。不要将其指向仅包含一台机器的目录。
对于原始的连续 128 KiB Model 80 Type 2 镜像,请使用 --model-80-type-2-rom。控制器会写入:
machines/ibmps2_m80/15f6637.bin = input[0::2] # 低/偶数通道
machines/ibmps2_m80/15f6639.bin = input[1::2] # 高/奇数通道
这两个文件均为 65,536 字节;将它们交错必须能重现输入。start 和 restart 会自动创建或验证隔离的克隆:
./86boxctl.sh <虚拟机> prepare-roms \
--model-80-type-2-rom /path/to/sequential-128k.bin
./86boxctl.sh <虚拟机> status
默认值为标准的 86Box ROM 根目录:macOS 的 Application Support、Unix 上的 XDG_DATA_HOME/XDG_DATA_DIRS、Windows 上的 Local/Program/AppData。使用 --rom-source PATH 或 86BOX_ROM_ROOT 覆盖。--refresh-rom-set 仅重建可识别的生成目录。
诸如 .orig 和 .altered 之类的备份后缀不会自动选择。请保留共享的原始文件。
对于使用真实 GDB-stub 功能的 86Box 进程的端到端验证:
./model80_rom_smoke.py <MODEL80_VM>
要求 machine = ibmps2_m80、cpu_use_dynarec = 0 以及唯一的 gdbstub_port。工具从标准通道文件派生出一个连续的镜像,将 KB OK 改为 OKBMR,修复 64 KiB 校验和,通过隔离的完整 ROM 克隆启动,在客户机文本 VRAM 中观察到 OKBMR,并仅停止其记录的 PID。仅当需要手动检查时使用 --keep-running。
停止或恢复
优先使用干净的 UI 关闭,然后确认跟踪的进程已退出。如果需要控制:
./86boxctl.sh <虚拟机> stop
./86boxctl.sh <虚拟机> restart
stop 仅向经过身份验证的 PID 发送 SIGTERM,并且不会静默强制终止它。仅在接受可能的 NVRAM 或配置丢失后使用 --kill-after-timeout。
发生崩溃时:
- 捕获
status和logs; - 确认记录属于目标虚拟机;
- 仅重启该记录;
- 记录新的 PID;
- 返回到之前的等待或观察步骤。
完成证据
在报告成功之前,请提供与任务相符的证据:
- 精确的虚拟机路径和机器标识符;
- 二进制文件和精确的启动命令;
- 稳定的进程名和当前 PID;
- 就绪证据;
- 干净退出或崩溃状态;
- 相关的配置/NVRAM 路径和大小;
- 客户机屏幕、寄存器、内存或解码后的配置输出。
关于实现细节、GDB 存根问题、ROM 查找和故障诊断,请参阅 README.md。