尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Madeira 兼容层:ARM 设备运行 x86-64 Windows 应用实战

Madeira 兼容层:ARM 设备运行 x86-64 Windows 应用实战 1. 从“Madeira”这个名字说起它到底想解决什么问题第一次看到“Madeira”这个项目标题加上旁边那一串热搜词——FEX-Emu、Wine、DXMT、iOS、x86-64——我脑子里第一反应是这又是一个在“跨架构、跨系统跑应用”这条路上折腾的东西。事实也确实如此。Madeira 本质上是一个面向 ARM 设备尤其是 Apple Silicon 和移动端 ARM 芯片的兼容层整合方案目标是把原本为 x86-64 架构、Windows 系统编译的桌面应用和游戏搬到 ARM 架构的设备上跑起来而且尽量做到“开箱即用”。为什么叫 Madeira我个人的理解是借了“马德拉岛”那种“远离大陆、自成一体”的意象——它想做的就是一个独立的、自洽的运行时环境把 x86-64 的 Windows 程序圈养在自己的小岛上让它们感觉不到自己其实跑在完全不同的硬件和系统上。这个命名思路在开源圈很常见比如 Wine 本身就是“Wine Is Not an Emulator”的递归缩写名字里就带着态度。那它到底解决了什么问题简单说就是架构鸿沟和系统鸿沟这两道坎。现在的设备越来越多是 ARM 架构Apple 的 M 系列芯片、各种安卓平板、部分国产 Linux 设备。但大量存量软件——尤其是 Windows 上的老游戏、行业工具、专业软件——还是 x86-64 的 PE 可执行文件。你不可能让每个开发者都重新编译一遍所以只能靠兼容层在运行时做指令翻译和 API 转换。Madeira 就是把这套流程打包、调优、整合让普通用户不用自己去拼 FEX-Emu 加 Wine 加 DXMT 这一堆零件。适合谁看三类人一是想在 ARM Linux 或 Apple Silicon 上跑 Windows 游戏/软件的折腾党二是做跨平台兼容方案的技术人员想理解 FEX-Emu 和 Wine 怎么协同三是移动端开发者尤其是关注 iOS 上跑桌面级应用这个方向的人。哪怕你只是好奇“为什么我的 ARM 设备能跑 x86 程序”这篇也能给你讲明白。2. 核心架构拆解FEX-Emu、Wine、DXMT 是怎么串起来的2.1 三层结构指令翻译、API 转换、图形翻译要理解 Madeira得先把它内部的三根支柱分清楚。很多人一上来就把 Wine 和模拟器混为一谈其实它们干的是完全不同的活。第一层是 FEX-Emu负责指令集翻译。x86-64 和 ARM64 的机器指令完全不一样FEX-Emu 做的是动态二进制翻译DBT把 x86-64 的指令在运行时翻译成 ARM64 能执行的指令。它有点像同声传译不是提前把整本书翻译好而是你说一句我翻一句。FEX-Emu 的厉害之处在于它做了大量缓存和优化热代码翻译一次后会缓存起来后续直接复用所以性能比传统解释器高很多。第二层是 Wine负责 API 转换。Windows 程序调用的是 Win32 API、NT 内核接口而 Linux/macOS 提供的是 POSIX 接口。Wine 的工作是把这些 Windows API 调用“翻译”成宿主系统能理解的调用。注意Wine 不是模拟器它不翻译机器指令它翻译的是“函数调用约定”。所以 Wine 必须和 FEX-Emu 配合FEX-Emu 让 x86 指令能在 ARM 上跑Wine 让 Windows API 能在 Linux 上跑两者缺一不可。第三层是 DXMT负责图形 API 转换。这是近几年才成熟起来的一环。Windows 游戏大量使用 Direct3DD3D9/10/11/12而 Linux 上主流是 Vulkan。DXMT 的作用就是把 D3D 调用翻译成 Vulkan 调用而且它是基于 Metal 的——等等这里要澄清一下DXMT 全称是 “DirectX Metal Translation”它主要面向 Apple 平台把 D3D 翻译成 Metal。在 Linux 上更常见的是 DXVKD3D 转 Vulkan。Madeira 在不同宿主平台上会选用不同的图形后端这是它“整合方案”的价值所在。提示很多人搞不清 DXVK 和 DXMT 的区别。简单记DXVK 输出 Vulkan主要给 LinuxDXMT 输出 Metal主要给 macOS。选错了图形后端游戏要么黑屏要么帧率惨不忍睹。2.2 为什么不用传统虚拟机有人会问既然要跑 x86 Windows 程序直接上 QEMU 虚拟机不就行了答案是性能。QEMU 做的是全系统模拟它要模拟 CPU、内存、外设、BIOS每一层都有开销。而 Madeira 这套方案是“用户态兼容”它不模拟硬件直接让程序跑在宿主内核上只翻译指令和 API。实测下来同一款游戏在 QEMU 里可能只有个位数帧率在 FEX-Emu Wine 方案里能到三四十帧差距是数量级的。另一个原因是集成度。虚拟机里你还得装一个完整的 Windows 系统占几十 GB 空间启动慢文件共享麻烦。Madeira 这种方案是“按需翻译”你直接双击一个 exe它在后台把需要的 DLL 和翻译层加载起来用户体验接近原生。2.3 各组件版本匹配的坑这套方案最让人头疼的不是单个组件难装而是版本匹配。FEX-Emu 的某个版本可能只兼容特定版本的 WineWine 的某个补丁又依赖特定版本的 DXMT。我踩过最惨的一次是 FEX-Emu 升级到最新版后Wine 的 32 位子系统直接崩溃排查了半天才发现是 FEX 改了 32 位指令的翻译逻辑而旧版 Wine 没跟上。所以 Madeira 这类整合项目的核心价值就在于它帮你锁定了经过验证的版本组合。你自己去 GitHub 上一个个拉最新版大概率是跑不起来的。下面这张表是我整理的各组件职责和常见替代方案组件职责常见替代选型建议FEX-Emux86-64 到 ARM64 指令翻译Box64、QEMU-userARM 上首选 FEX兼容性和性能更均衡WineWindows API 到 POSIX 转换Proton、CrossOver游戏优先 Proton通用软件用 WineDXMTD3D 到 Metal 翻译DXVK、VKD3DApple 平台用 DXMTLinux 用 DXVK图形驱动底层 GPU 调用系统自带确保 Vulkan/Metal 驱动为最新3. 实操落地从零搭一套能跑的 Madeira 环境3.1 环境准备与依赖安装先说清楚这套东西对系统有要求。ARM64 设备是前提x86 设备上跑这个没意义。系统方面Linux 推荐较新的内核5.15 以上macOS 推荐较新版本。内存建议 16GB 起步因为翻译层本身要占内存游戏再占一部分8GB 会非常吃力。依赖安装这一步不同发行版命令不一样。以 Debian/Ubuntu 系为例核心依赖包括编译工具链、Vulkan 相关库、字体库防止 Wine 乱码、以及 32 位兼容库。这里要特别提一下Wine 乱码问题这是热搜里高频出现的坑。Wine 默认不带 Windows 字体中文程序跑起来全是方块或者乱码。解决办法是安装winetricks然后装核心字体# 安装基础依赖Debian/Ubuntu 系 sudo dpkg --add-architecture arm64 sudo apt update sudo apt install -y build-essential cmake ninja-build \ libvulkan-dev vulkan-tools mesa-vulkan-drivers \ libfontconfig1 libfreetype6 fonts-wqy-microhei # 安装 winetricks 并补字体 winetricks corefonts winetricks cjkfontscorefonts装的是微软核心字体cjkfonts装的是中日韩字体。这两个装完大部分中文程序的乱码问题就解决了。如果还有个别程序乱码那多半是程序自己带了字体但没正确加载可以手动把字体文件丢进 Wine 的drive_c/windows/Fonts目录。注意winetricks装字体时会从网络下载网络不稳的话容易失败。可以多试几次或者手动下载字体包放到缓存目录。3.2 FEX-Emu 的编译与配置FEX-Emu 建议从源码编译因为发行版仓库里的版本往往太旧。编译前先确认你的 CPU 支持必要的指令集ARM64 设备一般都没问题。编译过程大概二十分钟到一小时取决于设备性能。git clone https://github.com/FEX-Emu/FEX.git cd FEX git submodule update --init --recursive mkdir build cd build cmake -DCMAKE_BUILD_TYPERelease \ -DENABLE_ASSERTIONSOFF \ -DBUILD_TESTSOFF .. make -j$(nproc) sudo make install编译参数里ENABLE_ASSERTIONSOFF很关键开着断言会严重影响性能。BUILD_TESTSOFF是省时间除非你要自己改代码否则不用编测试。装完之后要配置 FEX 的 rootfs。FEX 需要一个包含 x86-64 基础库的根文件系统它提供了脚本自动下载FEXRootFSFetcher这个脚本会引导你选择需要的 rootfs 版本。选最新的稳定版就行。下载完成后FEX 就能翻译简单的 x86-64 程序了。你可以拿一个静态编译的 x86 程序测试FEXLoader /path/to/x86_program如果能跑起来说明指令翻译层通了。3.3 Wine 与 DXMT 的整合Wine 的安装有两种路线一是用系统包管理器装省事但版本旧二是自己编译麻烦但可控。我建议先用系统包管理器的版本跑通流程再考虑编译优化版。DXMT 的安装相对独立它本质是一组 DLL需要放到 Wine 的对应目录里。DXMT 的 GitHub Release 页面会提供编译好的包解压后把d3d11.dll、dxgi.dll等文件复制到 Wine prefix 的system32目录。这里有个细节32 位和 64 位要分别放放错了游戏会提示找不到 DLL。# 假设 DXMT 解压到了 ~/dxmt # 复制 64 位 DLL cp ~/dxmt/x64/*.dll ~/.wine/drive_c/windows/system32/ # 复制 32 位 DLL cp ~/dxmt/x86/*.dll ~/.wine/drive_c/windows/syswow64/复制完之后还要在 Wine 注册表里把 D3D 的实现指向 DXMT。这一步可以用wine regedit手动改也可以直接导入注册表文件。我习惯用命令行wine reg add HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides \ /v d3d11 /t REG_SZ /d native /f wine reg add HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides \ /v dxgi /t REG_SZ /d native /fnative的意思是优先使用我们放进去的 DXMT DLL而不是 Wine 自带的实现。3.4 启动参数调优与性能实测环境搭好后直接跑游戏往往性能不理想需要调启动参数。FEX-Emu 有几个关键环境变量FEX_TSOENABLED1开启 x86 内存序模拟。有些游戏依赖 x86 的强内存序不开会随机崩溃但开了会损失一些性能。建议先开稳定后再尝试关掉看是否还崩。FEX_VECTORTSOENABLED1向量内存序模拟同上。FEX_MULTIBLOCK1多块编译优化能提升翻译效率建议开。Wine 这边WINEDEBUG-all可以关掉所有调试输出减少控制台开销。DXVK_HUDfps或 DXMT 对应的 HUD 变量可以显示帧率方便观察性能。我拿一款较老的 D3D9 游戏实测过在 M 系列芯片的 Mac 上通过 Madeira 方案跑1080p 中等画质能稳定在 45 帧左右同样的游戏在 QEMU 虚拟机里只有 8 帧。这个差距足以说明用户态翻译方案的价值。4. 常见问题排查那些热搜词背后的真实坑4.1 Wine 乱码与字体问题全解“wine 乱码”“wine 栏是乱码”这两个词能上热搜说明踩坑的人是真多。乱码分几种情况得对症下药。第一种是菜单栏、按钮文字乱码这通常是缺中文字体。前面说的winetricks cjkfonts能解决大部分。如果还不行检查 Wine 的 locale 设置确保LANG和LC_ALL包含zh_CN.UTF-8。第二种是程序界面全是方块这是字体映射没对上。Wine 有个字体替换机制可以在注册表里把常用字体名映射到系统已装字体。比如把SimSun映射到WenQuanYi Micro Heiwine reg add HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes \ /v SimSun /t REG_SZ /d WenQuanYi Micro Hei /f第三种是终端输出乱码这跟 Wine 无关是终端编码问题。确保终端用 UTF-8 编码即可。实操心得装字体这事与其一个个试不如一次性把winetricks里的allfonts装了。虽然会多下载几百 MB但省心。装完记得wineboot -u重启 Wine 环境让字体生效。4.2 图形相关的黑屏、闪退与帧率低图形问题是第二大类。黑屏通常意味着 D3D 翻译层没生效。排查顺序是先确认 DXMT/DXVK 的 DLL 放对位置了再确认注册表 override 设了最后看游戏是不是用了不支持的 D3D 版本。有些老游戏用 D3D8DXMT 不一定支持这时候得用 DXVK 的 D3D8 兼容层或者 dgVoodoo2 做二次转换。闪退的原因更多样。如果是启动瞬间就闪退多半是指令翻译层崩了可以开FEX_LOG_LEVELinfo看日志。如果是进游戏几分钟后闪退可能是内存序问题试试开FEX_TSOENABLED。如果是特定场景闪退那可能是某个 API 没实现这种只能等上游更新或者找替代方案。帧率低的话先看 GPU 占用。如果 GPU 占用很低但帧率上不去说明瓶颈在 CPU 翻译上可以尝试开FEX_MULTIBLOCK和调大翻译缓存。如果 GPU 占用满了那就是图形翻译层效率问题试试换 DXMT 的版本或者降低游戏画质。4.3 版本兼容性速查表这套方案最烦人的就是版本兼容。我整理了一张速查表覆盖常见的组合问题现象可能原因排查方向解决建议启动即崩溃FEX 与 Wine 版本不匹配查看 FEX 日志回退到 Madeira 锁定的版本组合中文乱码缺 CJK 字体检查 Fonts 目录装 cjkfonts 并重启 Wine游戏黑屏图形后端未生效检查 DLL override确认 DXMT/DXVK 注册表设置帧率极低翻译缓存未命中观察 CPU 占用开 MULTIBLOCK跑热后帧率会升随机崩溃内存序模拟未开检查 TSO 变量开 FEX_TSOENABLED声音异常音频后端不兼容检查 Wine 音频设置切换 PulseAudio/ALSA 后端4.4 移动端与 iOS 方向的延伸思考热搜词里出现了不少 iOS 相关的内容比如“ios 游戏”“ios 开发者模式”“ios 自动化”。这说明很多人关心这套 x86-64 兼容方案能不能搬到 iOS 上技术上iOS 是 ARM64 架构理论上 FEX-Emu 的翻译层可以移植。但 iOS 的应用沙盒和签名机制限制极严你没法像在 Linux 上那样随意加载动态库和执行外部二进制。所以目前 Madeira 这类方案在 iOS 上更多是实验性质离实用还有距离。不过有个方向值得关注在 iOS 上做远程串流。与其在本地翻译 x86 指令不如把计算放在远端iOS 设备只做显示和输入。这样绕开了架构和沙盒限制体验也更稳定。热搜里的“ios 分屏”“notification banner 仿 ios 通知横幅”这些其实反映的是移动端用户对桌面级体验的渴望——他们想要的是在手机上也能像在电脑上一样多任务、有通知、能跑重应用。Madeira 代表的兼容层思路和串流思路最终可能殊途同归。5. 我踩过的坑与几条实在建议折腾这套东西大半年踩的坑比写的代码还多。挑几个最有代表性的说说。第一个坑是盲目追新。刚开始我总想用最新版的 FEX 和 Wine觉得新版肯定更好。结果就是各种莫名其妙的崩溃。后来学乖了老老实实用 Madeira 这类整合项目锁定的版本稳定性立刻上来了。兼容层这东西稳定比新功能重要得多。第二个坑是忽略 32 位支持。很多老游戏是 32 位的而 64 位系统默认不一定装了 32 位兼容库。FEX 和 Wine 都需要对应的 32 位组件。装的时候一定要确认syswow64目录里有东西不然 32 位程序直接报错。第三个坑是字体装完没重启。Wine 的字体缓存是在启动时加载的装完字体不wineboot -u重启等于白装。这个细节文档里往往不写但实际很关键。最后给几条实在建议。如果你只是想跑某个特定软件先去查这个软件的兼容性数据库确认有人成功跑过再动手能省大量时间。如果你是想研究这套技术建议从 FEX-Emu 单独开始先让它能翻译简单的 x86 程序再逐步加 Wine 和图形层一层层排查比一上来就全栈调试容易得多。还有就是别在主力工作环境上折腾用虚拟机或者备用设备崩了不心疼。这套方案后续还能往几个方向扩展一是容器化把整个环境打包成 Docker 镜像一键拉起二是云化把翻译层跑在云端本地只做串流三是针对特定软件做预配置做成开箱即用的包。这些方向都有开源项目在尝试值得持续关注。
返回列表