拓冰建站拓冰建站
首页 / 资讯中心 / 正文

UTM 深度解析:基于 QEMU 的 iOS/macOS 全功能系统模拟器与虚拟机主机

UTM 深度解析基于 QEMU 的 iOS/macOS 全功能系统模拟器与虚拟机主机【免费下载链接】UTMVirtual machines for iOS and macOS项目地址: https://gitcode.com/gh_mirrors/ut/UTMUTM 是一款面向 iOS 与 macOS 的全功能系统模拟器System Emulator和虚拟机主机VM Host其模拟与虚拟化引擎基于 QEMU允许用户在 Mac、iPhone 和 iPad 上运行 Windows、Linux、macOS 等多种客户机系统。本文以仓库根目录的 README.zh-Hans.md 为主线结合仓库源码与官方开发文档系统讲解 UTM 的核心特色、UTM SE 的实现原理、整体架构分层、安装渠道以及从源码构建与打包的完整流程帮助读者既理解它能做什么也掌握它如何实现、如何构建。一、项目定位与核心能力UTM 的全称来自通用图灵机Universal Turing MachineREADME 开篇引用了艾伦·图灵 1936 年的论述发明一台可用于计算任何可计算序列的机器是可行的。It is possible to invent a single machine which can be used to compute any computable sequence.以此点明项目的本质——用一台设备模拟出可运行任意操作系统的通用计算环境。从技术形态看UTM 是系统级模拟器 虚拟机主机的复合体它不只模拟 CPU 指令集还模拟 MMU、各类设备等完整硬件即 README 中所说的使用 QEMU 的全系统模拟MMU、设备等因此客户机中的操作系统无需任何修改即可运行。在 UTMQemuSystem.m 中可以看到 UTM 直接以动态库方式嵌入 QEMU通过_qemu_init、_qemu_main_loop、_qemu_cleanup三个函数指针驱动 QEMU 的完整生命周期对应startQemu流程见 UTMQemuSystem.m这与QEMU 是 UTM 的骨干引擎的定位完全一致。核心特色清单README 原文使用 QEMU 的全系统模拟模拟 MMU、设备等完整硬件客户机操作系统无需修改即可运行支持 30 处理器架构包括 x86_64、ARM64 和 RISC-V 等VGA 图形模式基于 SPICE 与 QXL 显示设备文本终端模式适用于无需图形界面的场景USB 设备支持可将宿主机 USB 设备直通/转发给客户机基于 QEMU TCG 的 JIT 加速通过动态代码生成提升模拟性能现代化前端采用最新 API为 macOS 11 和 iOS 11 从头设计设备端全流程管理可直接在设备上创建、管理、运行虚拟机。上述30 处理器能力可在 Configuration 目录下的QEMUConstantGenerated.swift等文件中得到印证——UTM 将大量 QEMU 常量架构、机型、网卡、声卡等以枚举形式集中定义其中架构、机型等枚举即对应 QEMU 支持的处理器类型。这些常量由 scripts/const-gen.py 生成且 QEMUConstant.swift 中明确了QEMUConstant协议可以由外部生成A QEMU constant is a enum that can be generated externally体现了 UTM 通过脚本化方式与上游 QEMU 保持同步的设计思路。macOS 上的额外能力在 macOS 平台UTM 相比 iOS 多出两类关键能力硬件加速虚拟化使用 macOS 自带的Hypervisor.framework配合 QEMU实现同架构虚拟化x86 虚拟机运行于 Intel MacARM64 虚拟机运行于 Apple Silicon Mac。由于该框架在 iOS 上不可用这是 macOS 的独占特性详见 Architecture.mdmacOS 客户机支持在 macOS 12 上使用 Apple 的Virtualization.framework直接启动 macOS 客户机。此时后端不再是 QEMU而是苹果原生的虚拟化框架对应仓库中的 UTMAppleVirtualMachine.swift 与 UTMAppleConfiguration.swift。二、UTM SE无 JIT 的较慢版实现原理UTM SESE 即 Slower Edition / 较慢版是项目的一个重要分支其存在源于 iOS 平台的 JIT 限制。为什么需要 UTM SEUTM/QEMU 需要动态代码生成JIT才能获得最佳性能。但在 iOS 上启用 JIT 需要越狱设备或者利用针对特定 iOS 版本的各种变通方法如下文介绍的 Tethered Launch 调试器启动方案。对于无法越狱、也没有变通条件的普通用户JIT 是一个硬门槛。线程解释器TCI方案UTM SE 使用**线程解释器Threaded Code InterpreterTCI**来替代 JIT。TCI 的性能优于传统解释器但仍然比 JIT 慢因此被命名为较慢版。这种技术与 iSHREADME相关项目中列出的 iOS 用户态 Linux 终端模拟器用于动态执行的技术相似。UTM SE 不需要越狱也不需要任何 JIT 变通方法可以作为常规应用程序直接侧载sideload。TCI 后端由上游 QEMU 社区成员 ktemkin 的 ARM64 TCTI 分支演进而来见 Architecture.md 中关于 QEMU fork 特性的描述ARM64 TCTI from ktemkin (JIT-less iOS support)。仓库中 patches/sources 列出的依赖清单也表明UTM 使用自维护的utmapp/qemufork版本为qemu-10.0.2-utm并在 patches/data/qemu-10.0.2-utm/qemu-10.0.2-utm.patch 中携带了对该 fork 的定制补丁。UTM SE 的架构裁剪为了优化体积和构建时间UTM SE 仅包含以下架构ARM、PPC、RISC-V 和 x86各有 32 位与 64 位变体。这与完整版支持的 30 架构形成对比属于明显的功能取舍。在构建层面UTM SE 对应独立的 Xcode Scheme从 build_utm.sh 的用法说明可见可用 Scheme 为[iOS|iOS-TCI|iOS-Remote|macOS]其中iOS-TCITCI Threaded Code Interpreter即 UTM SE的构建目标配合 iOSDevelopment.md 中将iOS替换为iOS-SE即可构建 UTM SE的说明可以确认 SE 版在依赖 Sysrootios-tci-arm64与编译目标上均与完整版相互独立。三、整体架构从后端引擎到 SwiftUI 前端Architecture.md 给出了 UTM 的分层架构图从上到下依次为┌────────────────────┬──────────────────────┐ │ iOS VM Display │ macOS VM Display │ ├────────────────────┴──────────────────────┤ │ SwiftUI │ ├───────────────────────────────────────────┤ │ UTMVirtualMachine │ ├────────────────┬──────────────────────────┤ │ CocoaSpice │ │ ├────────────────┤ Virtualization.framework │ │ QEMU (TCG/HVF) │ │ └────────────────┴──────────────────────────┘3.1 QEMU引擎层QEMU 是 UTM 的骨干。UTM 运行的是自维护的 fork针对 Darwin 平台做了多项优化见 Architecture.md 与 patches/sources将 QEMU 构建为共享库而非独立可执行文件为越狱 iOS 提供 APRR 支持集成 ktemkin 的ARM64 TCTI实现无 JIT 的 iOS 支持即 UTM SE 的基础提供SPICE ANGLE 后端实现硬件 GL 加速。其中hvf加速器Hypervisor.framework提供 macOS 上的同架构虚拟化x86→x86 或 ARM64→ARM64且仅限 macOS。3.2 UTMQemu进程模型与沙盒引导由于 iOS 不允许fork、直接使用 XPC 或启动新进程UTM 在 iOS 上把 QEMU 主循环放进一个 pthread 中运行代价是无法同时启动多个 QEMU 实例、且 QEMU 退出后不能重新拉起而在 macOS 上则通过 XPC 将 QEMU 放入独立进程。这一层由UTMQemu统一管理其 Objective-C 实现即 UTMQemuSystem.m——可以看到它通过函数指针qemu_init/qemu_main_loop/qemu_cleanup在 pthread 内执行 QEMU 主循环。macOS 受 App Sandbox 限制需要额外的引导代码QEMUHelper见 QEMUHelper.m是拥有独立沙盒的 XPC 辅助进程负责在沙盒内孵化QEMULauncher见 QEMULauncher/main.c再由 Launcher 真正运行 QEMU。这种UTM 主程序 → XPC Helper → Launcher的三层结构既满足了 App Sandbox 的单 Bundle ID 要求也通过进程隔离提升了安全性。跨沙盒传递文件权限时UTM 采用主程序用NSOpenPanel获取标准 bookmark → 传给 XPC 进程 → XPC 进程转成 security scoped bookmark 回传主程序存储的三步方案详见 Architecture.md而 SPICE 通信所用的 Unix socket 则存放在共享 App Group 目录中。3.3 配置体系UTMConfigurationVM 配置以PLIST 格式存储反序列化后映射为两种结构之一UTMQemuConfigurationQEMU 后端以Codable接口承载配置数据。从 UTMQemuConfiguration.swift 可见其内部划分为 Information基本信息与图标、System系统、QEMU附加 QEMU 参数、Input输入、Sharing共享、Display显示、Drive磁盘、Network网络、Serial串口、Sound声音等子结构并通过CodingKeys与 PLIST 键一一对应该文件还包含backend .qemu的校验与isLegacy标记支持从旧版Legacy配置自动迁移Configuration/Legacy目录即存放迁移代码UTMAppleConfigurationVirtualization.framework 后端见 UTMAppleConfiguration.swift纯 Swift 实现同样基于Codable但比NSDictionary支撑的 QEMU 配置更易扩展复杂数据结构。UTMQemuSystemServices/UTMQemuSystem.m负责把UTMQemuConfiguration翻译成启动 QEMU 所需的命令行参数与环境变量UTMQemuManager则在 VM 启动后通过QMP 协议JSON over socket提供运行时服务包括停止/暂停/恢复、快照、鼠标与平板模式切换、挂载可移动磁盘镜像等。QMP 协议由 QEMU 的 QAPI schema 定义UTM 基于 QEMU 的qapi-gen.py改造出参数生成器与面向NSDictionary的 QAPI C 访问器从而透明地复用 QEMU 的全部命令、结构与事件。3.4 图形栈CocoaSpice 与 MetalUTM 选择 SPICE 作为 QEMU 的前端协议因为它相比 VNC 在 USB 转发、多显示器、客户机剪贴板共享SPICE agent与动态分辨率调整上能力更强。CocoaSpice由UTMQemuVirtualMachine调用以控制 SPICE 客户端并响应客户端事件。3.5 前端SwiftUI UIKit/AppKit前端绝大部分使用 SwiftUI 2.0 构建这决定了最低支持系统为 iOS 14 / macOS 11也是项目无意回移植到更早系统的原因Architecture.md 明确说明。Platform/UTMData.swift 作为ObservableObject是主页面的单一数据源保存 VM 列表并提供创建、修改、移动等操作。VM 显示层因 SwiftUI 尚不足以承载全部交互需求而使用 UIKitiOS/AppKitmacOS实现——例如 iOS 上用于模拟标准键盘缺失按键的自定义键盘附件视图NIB 实现见 Platform/iOS/Display 目录。四、安装方式iOS 版 UTM / UTM SE官方安装指引位于 getutm.app 的 install 页面README 中提供了该入口macOS 版 UTM官方站点 mac.getutm.app 提供下载。需要说明的是完整版 UTM 在 iOS 上依赖 JIT普通侧载无法直接获得最佳性能UTM SE 则无此限制可直接作为常规 App 侧载详见上文UTM SE一节。五、从源码构建开发环境与构建脚本README 将开发文档链接至 Documentation/MacDevelopment.md 与 Documentation/iOSDevelopment.md本节提炼两篇文档的关键步骤并结合仓库脚本给出可直接执行的命令。5.1 获取源码需递归克隆以拉取全部子模块git clone --recursive UTM 仓库地址若已普通克隆可事后补齐子模块git submodule update --init --recursive5.2 依赖获取预编译 Sysroot推荐依赖分为预编译与自编译两条路径。预编译路径从 GitHub Actions 产物中下载对应平台的Sysroot-*归档并解压到仓库根目录需要登录 GitHub 才能下载 artifacts。macOS 只需下载本机架构的 Sysroot 即可本地运行iOS 侧可按目标平台选择例如ios-arm64完整版、ios-tci-arm64UTM SE、ios_simulator-x86_64/ios_simulator-arm64模拟器、visionos-arm64visionOS等完整对应表见 iOSDevelopment.md。5.3 自编译依赖高级自编译强烈建议在全新的 macOS 虚拟机中进行——部分依赖会无视架构地写入/usr/local/lib宿主机上已装的libusb、gawk、cmake等包会破坏构建。步骤概览安装 Xcode Command Line Tools 与 Homebrew安装构建前置依赖brew install bison pkg-config gettext glib-utils libgpg-error nasm meson pip3 install six pyparsing并确保bison在$PATH中export PATH/usr/local/opt/bison/bin:/opt/homebrew/opt/bison/bin:$PATH运行依赖构建脚本macOS 用-p macosiOS 用-p PLATFORM如ios_simulator-tci./scripts/build_dependencies.sh -p macos -a arm64其中-a可为arm64或x86_64要构建通用二进制需分别跑两个架构后再执行./scripts/pack_dependencies.sh . macos arm64 x86_64合并。若正在开发 QEMU 并希望传入自定义 QEMU 源码路径可使用-q PATH_TO_QEMU_SOURCE选项注意必须使用 UTM 兼容的 QEMU fork。依赖清单可参考 patches/sources除 QEMUqemu-10.0.2-utm外还包含 SPICE 服务端spice-0.14.3与客户端spice-gtk-0.42、GLib、Pixman、OpenSSL、libtpms/swtpm可信平台模块、libusb、libslirp用户态网络栈、GStreamer 插件以及 GPU 加速相关的 ANGLE、libepoxy、MoltenVK、Mesa、virglrenderer、Vulkan-Loader 等每个组件均带对应补丁文件patches 目录。5.4 构建 UTM命令行构建统一使用 scripts/build_utm.sh其参数为./scripts/build_utm.sh -t TEAMID -k SDK -s SCHEME -a ARCH -o /path/to/output-tTeam IDiOS 可选、macOS 必需用于 App Group-k目标 SDK如iphoneos、iphonesimulator、xros、macosx-sScheme可选iOS、iOS-TCIUTM SE、iOS-Remote、macOS-a架构arm64或x86_64macOS 通用二进制可传arm64 x86_64需加引号-o输出目录。例如 macOS 版./scripts/build_utm.sh -t TEAMID -k macosx -s macOS -a arm64 -o /path/to/output/directoryiOS 完整版./scripts/build_utm.sh -k iphoneos -s iOS -a arm64 -o /path/to/output/directory产物为未签名的.xcarchive。脚本内部调用xcodebuild archive并对 iOS 的 Frameworks 执行lipo -thin瘦身以规避 iOS 15 以下崩溃并节省磁盘对 macOS 产物则直接注入macOS.entitlements、QEMUHelper.entitlements、QEMULauncher.entitlements与utmctl.entitlements做临时签名详见 build_utm.sh 末尾的 codesign 段。5.5 Xcode 图形化开发将CodeSigning.xcconfig.sample复制为CodeSigning.xcconfig并填写相应值macOS若拥有带 Hypervisor entitlements 的开发者账号设置DEVELOPER_ACCOUNT_VM_ACCESS YES默认 Xcode 会构建缺少 USB 与网络桥接特性的未签名版本iOS用DEVELOPMENT_TEAM替换你的 Team ID用已注册的 Bundle ID 前缀替换PRODUCT_BUNDLE_PREFIX付费账号可设DEVELOPER_ACCOUNT_PAID YES以自动申请更大的内存限制 entitlement。另外注意 macOS 上有个已知问题带调试器附加启动 VM 可能崩溃变通方法是先不附加调试器启动 UTM启动 VM 后再通过 Debug → Attach to Process 附加。5.6 打包与签名由build_utm.sh产出的.xcarchive含 GitHub Actions 产物必须重新签名后方可使用。macOSscripts/package_mac.sh未签名包缺少 USB 与网络桥接等特性./scripts/package_mac.sh unsigned /path/to/UTM.xcarchive /path/to/output生成可安装到/Applications的UTM.dmg签名包Developer ID./scripts/package_mac.sh developer-id /path/to/UTM.xcarchive /path/to/output TEAM_ID PROFILE_UUID HELPER_PROFILE_UUID LAUNCHER_PROFILE_UUID需要注册开发者账号、Developer ID Application 证书以及 UTM、QEMUHelper、QEMULauncher 三个带 Hypervisor entitlements需向 Apple 单独申请并获批的 provisioning profile签名后可再向 Apple 申请公证notarizationMac App Store 包./scripts/package_mac.sh app-store ...生成提交用UTM.pkg需要 Apple Distribution 与 Mac App Distribution 两类证书。iOSscripts/package.sh签名 IPA需 Development 签名证书而非 Distribution因为 UTM 需要get-task-allowentitlementApple 仅在 Development 签名下授予./scripts/package.sh signedipa /path/to/UTM.xcarchive /path/to/output TEAM_ID PROFILE_UUID未签名 IPA可用 AltStore 或越狱设备 AppSync Unified 安装./scripts/package.sh ipa /path/to/UTM.xcarchive /path/to/outputDEB 包供 Cydia/Sileo AppSync Unified 安装内部包裹未签名 IPA./scripts/package.sh deb /path/to/UTM.xcarchive /path/to/output免费 Apple 账号签名的 IPA 有7 天有效期需每 7 天重新签名越狱设备则可生成 fake-signed 的 DEB。5.7 Tethered LaunchiOS 上启用 JIT 的调试器启动方案iOS 14 起Apple 封堵了此前获取 JIT 的漏洞非越狱设备上最佳变通方案是通过调试器启动Tethered Launch完整步骤见 Documentation/TetheredLaunch.mdREADME 未直接链接但该文档与 iOS 开发、UTM SE 背景强相关。核心流程准备 Xcode、最新 IPA Release、iOS App Signer、Homebrew 与ios-deploybrew install ios-deploy用 iOS App Signer 对 IPA 重签名并导出将UTM-signed.ipa改名.zip解压出Payload/部署ios-deploy --bundle /path/to/Payload/UTM.app之后每次启动不能从主屏幕启动ios-deploy --justlaunch --noinstall --bundle /path/to/Payload/UTM.app常见问题若报invalid code signature / inadequate entitlements / profile has not been explicitly trusted需在 设置 → 通用 → 设备管理 中信任开发者描述文件若报Failed to register bundle identifier需更换 Bundle Identifier 重试。也可在 Xcode 的 Window → Devices and Simulators 中勾选Connect via network实现无 USB 线缆的部署与启动。六、相关项目与许可相关生态项目README相关项目一节列出了两个生态关联项目iSH——在 iOS 上模拟用户态 Linux 终端、运行 x86 Linux 应用其动态执行技术与 UTM SE 的 TCI 方案同源a-shell——为 iOS 原生构建的通用 Unix 命令与工具集通过终端接口访问。许可说明UTM 本身在宽容的 Apache 2.0 许可证下分发但使用了若干 (L)GPL 组件其中大多数为动态链接但gstreamer 插件为静态链接且部分代码取自 QEMUGPL因此若要重新分发此应用需特别注意许可证合规问题详见 LICENSE。前端还依赖以下 MIT/BSD 许可的组件IQKeyboardManager键盘管理、SwiftTerm终端模拟、ZIP FoundationZIP 读写、InAppSettingsKit应用内设置界面。部分图标由 Freepik 从 flaticon.com 制作持续集成CI由 MacStadium 开源计划托管。七、结语UTM 的价值在于把 QEMU 的强大模拟能力完整地搬进了 iOS 与 macOS 的沙盒生态通过自维护的 QEMU fork共享库化、APRR、TCTI、SPICE ANGLE、pthread/XPC 双进程模型、PLIST Codable 配置体系、SPICE/Metal 图形链路以及 SwiftUI 前端实现了设备上创建、管理、运行虚拟机的完整体验UTM SE 则以线程解释器换取了无越狱、无 JIT 变通的可侧载方案。对于开发者而言MacDevelopment.md、iOSDevelopment.md、TetheredLaunch.md 与 scripts 下的构建/打包脚本构成了一条完整的依赖 → 构建 → 签名 → 分发链路可据此自行编译、签名与部署 UTM 及其 SE 变体。【免费下载链接】UTMVirtual machines for iOS and macOS项目地址: https://gitcode.com/gh_mirrors/ut/UTM创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门