在 Parallels 上运行 Rosetta

在 Parallels 上运行 Rosetta

Hanako

你果在今年 6 月发布了 macOS Ventura,其中一个亮点功能是支持在 Linux 虚拟机中运行 Rosetta。

得知这个消息的时候,我心血来潮地升了个 Beta 版来体验。Bug 真 TM 多,不过我是从 Beta 7 开始的,应该没 Beta 1 惨。下次我绝对不升预览版

根据 Running Intel Binaries in Linux VMs with Rosetta 的描述,我使用当时实验性支持 Rosetta 的 UTM 4.0 Beta,在 Apple Virtualization.framework(下文简称 VF)下安装了 Arch Linux ARM,根据 Apple Developer 的文档挂载了 Rosetta VirtioFS,运行了 update-binfmts。

1
2
3
4
5
6
mkdir /tmp/mountpoint
sudo mount -t virtiofs rosetta /tmp/mountpoint
sudo /usr/sbin/update-binfmts --install rosetta /tmp/mountpoint/rosetta \
--magic "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00" \
--mask "\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff" \
--credentials yes --preserve no --fix-binary yes

update-binfmts 的参数意思不用多说。

不过 aarch64 环境下大量缺少 x86-64 的 .so 动态链接库,pacman 的多架构软件包管理又非常感人,在随便测试了一个在某 x86 服务器上静态编译的 Hello World 后,不得已换成了 Debian 11(Ubuntu 爬),dpkg 可以方便地管理多个处理器架构的软件包:

1
2
dpkg --add-architecture amd64
dpkg --add-architecture i386

之后 update 一遍,随便装个 amd64 的包:

1
apt-get install libx11-dev:amd64

ld.so.conf 会被自动配置并运行 ldconfig。

1
2
3
4
5
6
7
8
9
10
> ls /etc/ld.so.conf.d
aarch64-linux-gnu.conf libc.conf
arm-linux-gnueabihf.conf x86_64-linux-gnu.conf
fakeroot-aarch64-linux-gnu.conf

> cat /etc/ld.so.conf.d/x86_64-linux-gnu.conf
# Multiarch support
/usr/local/lib/x86_64-linux-gnu
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu

Google 没有提供 ARM 版的 Chrome。Chromium 在 Rosetta 下闪退。Firefox 运行良好,虽然肯定比 ARM64 原生版慢。

能够支持 GUI 应用程序,这是我没有想到的。

切换到 Parallels Desktop

截至本文撰写时,UTM 最新版是 v4.0.9。

虽然我不知道现在 UTM 对 VF 的支持怎么样,但是当时 VF 下不能自动变换分辨率(屏幕分辨率在设定中是写死的,似乎是 VF 的缺陷)、不能使用剪贴板互通、不能使用触控板滚屏(后面两个应该是能用了),这些功能虽然在基于 Hypervisor.framework(下文简称 HVF)的 QEMU 上能够使用,但使用体验也是比较感人的。

lima 使用的是基于 HVF 的 QEMU,不能魔改代码启用 Rosetta。

买了正版 Parallels Desktop 当然是要物尽其用了对吧(而且我当时也有退回 macOS 12 的打算)

RosettaLinux 在 macOS 下的位置是 /Library/Apple/usr/libexec/oah/RosettaLinux

把 RosettaLinux 执行文件 copy 出来,挂载到 Parallels Desktop 的 Debian 11 上,毫无意外地报错了。

1
2
rosetta error: Rosetta is only intended to run on Apple Silicon with a macOS host using Virtualization.framework with Rosetta mode enabled
追踪与中断点陷阱

都是硬件虚拟化,虚拟处理器都是一样的,魔改一番或许有戏。

魔改工程

1
2
> file rosetta
rosetta: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, BuildID[xxHash]=be14a432992ecdeb, stripped

把 rosetta elf 丢进 IDA 溜达溜达。请无视这个 Windows,都怪某 Hackergame

ELF 类型选 ARM64 小端序。

字符串全文搜索上述的 Rosetta is only ,可见有两种情况会跳转到该错误。

情况 1

这应该是 Apple 在故意整活。

情况 2

在进行某种计算。

顺便学习了一下 ARM 指令集。

部分涉及跳转的 ARM 指令如下:

TBZ: test branch zero. 测试位为0,则跳转。 TBNZ: test branch no zero. 测试位不为0,则跳转。 CBNZ: 当Xt寄存器的值(64位)非零,那么执行跳转,地址是当前PC+label的偏移地址。 CBZ: 当Xt寄存器的值(64位)是零,那么执行跳转,地址是当前PC+label的偏移地址。

将 TBNZ 和 CBNZ 分别变更为 TBZ 和 CBZ,导出到文件。

IDA 不自带除 x86 外的平台的汇编器,尝试直接编辑汇编时会报告以下错误:

可以安装 Keypatch 后使用 Keypatch——Patcher 命令,也可以在 Hex View 中直接变更十六进制文本。

直接变更十六进制文本时,记得是小端序。

直接运行,看起来不报错了。

尝试运行上述的静态链接程序,没有异常。

这不就成了吗

复制到 /bin 目录,安装:

1
2
3
4
5
sudo apt install update-binfmts
sudo /usr/sbin/update-binfmts --install rosetta /bin/rosetta \
--magic "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00" \
--mask "\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff" \
--credentials yes --preserve no --fix-binary yes

直接运行,正常:

安装 amd64 相关链接库:

1
2
3
sudo dpkg --add-architecture amd64
sudo apt install libc6:amd64
sudo apt install libx11-6:amd64

安装 Firefox:

1
2
3
sudo apt remove firefox-esr
sudo apt autoremove
sudo apt install firefox-esr:amd64

甚至能播放视频,音频正常播放,看来非常稳

总结

Apple 这墙跟纸糊的一样。

不过我在试图运行于 Asahi Linux 时碰壁了,似乎是 Asahi Linux 默认的 16K Kernel 没法用,4K IOMMU 补丁无效。

反正 Asahi Linux 的 GPU 驱动还没公布,短时间内不会用上了就不管了。

其它 ARM 设备要用的话估计有点困难,Apple Silicon 的内存一致性模型有为 Rosetta 专门设计,就算能跑那也会比 Apple Silicon 效率要低。

经群友提醒,非 VF 虚拟机下无法调整控制 TSO 序的寄存器。需要一种在 macOS 下调整 TSO 序的方法。

改天装个 Vivado 看看会不会比 Windows 版的快。

  • 标题: 在 Parallels 上运行 Rosetta
  • 作者: Hanako
  • 创建于 : 2022-11-02 08:00:00
  • 更新于 : 2023-10-22 22:48:04
  • 链接: https://hanako.me/parallels_rosetta.html
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
此页目录
在 Parallels 上运行 Rosetta