Gbos-VM:在 Apple Silicon Mac 上以 GPU 加速虚拟机运行 Googlebook OS
Gbos-VM: Run Googlebook OS in a GPU-Accelerated VM on Apple Silicon Macs
Gbos-VM 让 Apple Silicon Mac 通过 QEMU 启动真实 Googlebook OS 镜像(Dell Googlebook 的 ARM64 Android 17 恢复镜像),并将 Vulkan 透传到 Metal 实现 GPU 加速,Chrome 可正常运行。
在 Apple Silicon Mac 上的虚拟机中运行真实的 Googlebook OS 镜像——GPU 加速,Chrome 可正常工作。
这不是模拟器镜像,也不是通用的 Android 构建。安装脚本会下载 Google 为 Dell Googlebook 提供的官方恢复镜像(ARM64,Android 17),把硬件相关的部分替换为虚拟部分,然后在 QEMU 下启动,并将 Vulkan 透传到 Metal。
本项目与 Google 或 Dell 没有关联,也不是经过验证的 Googlebook。在登录任何账号之前,请先阅读 System Structure。
快速开始
git clone https://github.com/skylartaylor/gbos-vm.git
cd gbos-vm
./install.sh然后打开它构建出的应用:
open "work/host/Googlebook VM.app"如果你想把它放到 Dock 里,就把它拖进去。打开它时会启动虚拟机,退出时会正常关闭 Android。
在 M5 MacBook 上首次启动大约需要 45 秒。如果你看到用户选择界面,点击 User——没有密码。
install.sh 会下载约 9 GB 数据,并需要 60 GB 可用空间。在 M5 MacBook 上,构建部分大约需要五分钟;下载时间取决于你的网络连接速度。
你需要什么
- 一台 Apple Silicon Mac。Intel Mac 不行——这是在虚拟机监控程序上运行的 ARM 客户机,不是模拟。
- 实际需要 16 GB 内存。虚拟机分配 4 GB,构建还需要更多。
- Xcode 命令行工具和 Homebrew。
- 带有 NDK、某个 build-tools 版本和一个平台(API 34+)的 Android SDK。Android Studio 的默认配置即可。我们使用 NDK
28.2.13676358构建;如果你没有这个版本,脚本会使用你最新的版本(据报告 30 可用),或者设置ANDROID_NDK来选择。 - 一个 JDK。如果你安装了 Android Studio,会自动使用它自带的 JDK。
- 可选:来自 SDK 的 Android Emulator 包。蓝牙会借用它的虚拟无线电(参见 What doesn't work yet);没有它,虚拟机启动时就没有蓝牙。
install.sh 会在下载任何内容之前检查所有这些,并主动提出安装缺失的部分——Homebrew 包、JDK,以及通过 Google 的 sdkmanager 安装 Android 组件(你不需要 Android Studio)。它从不要求 sudo。单独运行 ./prereqs.sh 可以查看当前状态。
我们在一台机器上构建和测试(M5,16 GB,macOS 27)。也有几个人报告说在 M4 Mac 上也能用——如果你在其他设备上尝试,请告诉我们结果如何。
使用它
| 快捷键 | 作用 |
|---|---|
⌃⌘F |
全屏 |
⌃⌘M |
切换指针模式 |
⌃⌥ |
释放被捕获的鼠标 |
⌃⌘R |
重启虚拟机 |
⌘V |
将 Mac 剪贴板粘贴到客户机 |
⌘, |
设置 |
退出(或关闭窗口)会正常关闭 Android。你的数据存放在 work/image/googlebook.raw 中,并在多次运行之间保留。
Settings(⌘,)中有指针模式、分辨率、内存、CPU 核心数,以及网络、音频和蓝牙的开关。指针模式会立即更改;其他都是虚拟机选项,因此会在下次启动时生效。
分辨率默认使用你显示器的原生像素,比例为 16:10。在带刘海的 MacBook 上,这正好是刘海下方的区域,因此全屏时是逐像素对应的。
更新
在 git pull 之后,重新构建应用并刷新磁盘的系统部分。请先退出虚拟机。
./build-host.sh ./update-image.sh
update-image.sh 会保留你的数据——它只替换系统区域,并把之前的磁盘以 googlebook.raw.before-update 的名字留在新磁盘旁边,以防出现问题。
如果你更想从终端操作,python3 run/launch.py work 做同样的事情,并接受 --display 1920x1200 和 --fullscreen。
指针模式
Captured mouse 是默认模式:点击窗口捕获鼠标,按 ⌃⌥ 释放。这是经典的虚拟机体验——对 Android 来说就是一个普通的 USB 鼠标,所以行为正常。
有两种集成模式,指针可以自由进出窗口。它们被标记为实验性,因为它们仍然有些小问题:
- Android 光标。由客户机绘制指针,因此它会正确改变形状(I 型光标、调整大小箭头)。它会稍微滞后于你的手,而且 Android 将其视为触控笔,这在某些地方会显得奇怪。
- Mac 光标。即时响应,但它始终是箭头。
在“设置”中的指针菜单里切换,或使用 ⌃⌘M。你的选择会被记住,剪贴板同步在三种模式下都有效。
系统结构
该镜像最初是 Google 未经修改的 recovery 下载。我们不碰系统分区——但 Googlebook OS 期望的硬件我们的虚拟机没有(TPM、Trusty、高通 DSP、特定 GPU),因此vendor 分区会被重建,使用来自 Google 自家 Cuttlefish 项目的虚拟设备替代品:
- 软件 KeyMint 和 Gatekeeper,而非硬件支持的版本。你的密钥不受安全元件保护,因为根本没有安全元件。
- vendor 分区上没有验证启动。其他分区保留原有的 verity;我们修改的那个无法保留。
- 三条额外的 SELinux 规则,都严格针对图形缓冲区共享。SELinux 保持强制模式。
- Cuttlefish 的蓝牙服务,而非高通的,通过虚拟串口与 Mac 上的虚拟无线电通信。该无线电在
127.0.0.1上监听且无密码,因此你 Mac 上的另一个程序可以加入它并显示为附近的蓝牙设备。如果这让你困扰,请在设置中关闭蓝牙。 - 一个以 Android shell 用户身份运行的辅助程序,从查看器接收指针和剪贴板输入。它只接受提供每次启动随机令牌的主机,并且它不监听任何内容——它向外连接到你 Mac 上的
127.0.0.1。
所以:把它当作开发虚拟机来对待。它非常适合探索操作系统。我不会把它作为日常主力机,但我相信一些怪人(褒义)会尝试。
尚不支持的功能
- 蓝牙仅为虚拟。如果你安装了 Android 模拟器,虚拟机会获得其模拟无线电(
netsimd):蓝牙可以打开,但没有真实设备可配对。真实设备需要桥接 USB 加密狗,我们尚未实现。没有模拟器时,Android 会被告知它根本没有蓝牙。 - 客户机显示限制为 60 fps。我们使用的 QEMU 构建没有暴露刷新率设置。
- 平面着色可能出错。Chrome 需要 MoltenVK 没有的 Vulkan 扩展,因此我们告诉客户机它存在。这对几乎所有内容都没问题;
flat插值的 WebGL 内容可能会选错顶点。 - 从客户机复制出去、右键点击和长时间会话已实现,但尚未经过适当测试。它们可能没问题。也可能有问题。
- 音频在一次启动时无声,然后又能用了。我们还不知道为什么。
自定义部分
为此必须构建三样东西:
GLES 和 Vulkan 之间的缓冲区共享。Android 将相同的图形缓冲区交给这两个 API。在 Linux 上那是 dma-buf;macOS 没有这种东西。我们用 POSIX 共享内存支持每个共享缓冲区,并将其导入 Metal 和 MoltenVK——补丁在 patches/virglrenderer-android-interop.patch 中。
行间距。Metal 要求纹理行填充到 16 字节;Android 则不需要。修复方案其实很小:那块内存只存在于 Mac 一侧,所以主机可以按 Metal 想要的任意间距来用,而客户机完全不需要知道。
不是鼠标的指针。Android 不接受 QEMU 的绝对定位数位板,而把相对鼠标调整到与真实光标一致会产生漂移。于是客户机内一个极小的辅助程序创建了一个虚拟绘图板——Android 将其视为绝对指针——由查看器向它提供坐标。这效果不如我们希望的那样好,所以捕获光标仍然是最可靠的方式。我们希望能改进它。
其余都是管道工作:fetch.sh 获取镜像,build-host.sh 构建打过补丁的渲染器和查看器,build-guest.sh 为 Android 交叉编译 Mesa,build-image.sh 组装磁盘。
布局
install.sh runs the four steps below in order
fetch.sh downloads + verifies the Googlebook image, Cuttlefish, and UTM
build-host.sh patched virglrenderer, QEMU launcher, viewer
build-guest.sh Mesa (GLES + Vulkan), pointer helper, SELinux policy tool
build-image.sh assembles the bootable disk
update-image.sh refreshes an existing disk after a git pull, keeping your data
run/ VM runner and a command-line launcher (the app bundles these)
image/ the scripts that rebuild the vendor partition
guest/ host/ sources for the bits we wrote
patches/ our changes to virglrenderer, Mesa and CocoaSpice
所有内容都落在 work/ 中(设置 GOOGLEBOOK_WORK 可将其放到别处)。如果你已经有了那些大文件下载,把 GOOGLEBOOK_DOWNLOADS 指向它们,就不会再次下载。构建默认使用四个任务——如果你有足够的内存,可以提高 GBOS_JOBS,但不加限制的 Mesa 构建会轻松把一台 16 GB 的 Mac 推入交换内存(别问我怎么知道的)。
下载了什么,以及从哪里下载
这里不重新分发任何来自 Google 或 UTM 的内容。脚本会在你的机器上获取以下每一项,并用固定的 SHA-256 进行校验:
- Googlebook 恢复镜像 —
dl.google.com(构建16471258) - Cuttlefish 虚拟设备镜像 —
ci.android.com(构建16373615) - UTM 5.0.6 beta — 官方 GitHub 发布版(用于其 QEMU、MoltenVK 和 ANGLE)
- Mesa 26.2.4、libsepol 3.11、bison 3.8.2 — 它们的上游发布 tarball
致谢
这完全依赖于他人的工作:UTM 及其 virglrenderer 和 CocoaSpice 分支、Mesa、MoltenVK、QEMU,以及 Android Cuttlefish 团队,正是他们的虚拟设备组件让镜像得以启动。指针辅助程序使用了与 scrcpy 相同的技巧。
许可证
我们编写的所有内容均采用 MIT 许可证——见 LICENSE。这些补丁适用于 MIT 许可的项目,但 patches/cocoaspice-viewer.patch 除外,它修改的是 Apache-2.0 代码,并继续沿用该许可证。
AI 使用情况
以下 AI 工具被用于协助本项目:
- OpenAI GPT 6 Astra
- DeepSeek 4.1 Flash
- Anthropic Claude Opus 5.5
来源:Hacker News · github.com