1. 从“Madeira”这个名字说起一个跨平台兼容层的野心第一次看到“Madeira”这个项目名我脑子里蹦出来的不是葡萄牙那座海岛而是它背后那串关键词FEX-Emu、Wine、DXMT、iOS、x86-64。这几个词凑在一起指向的东西其实非常明确——在非x86架构的设备上尤其是移动端和ARM桌面端把原本为Windows/x86生态准备的软件和游戏跑起来。这不是一个新话题但“Madeira”这个组合方式让我觉得值得认真拆一拆。先说结论Madeira本质上是一个多层翻译与兼容栈的集成方案。它把FEX-Emux86-64到ARM64的指令级翻译、WineWindows API到POSIX的兼容层、DXMTDirect3D到Metal的图形翻译层这三块拼在一起目标是在Apple Silicon或者ARM Linux设备上直接运行Windows平台的x86-64应用程序和游戏。而关键词里出现的iOS则暗示了这套方案有向移动端延伸的意图——虽然iOS的沙盒限制让这件事难度陡增但技术路径是存在的。为什么这件事值得关注因为过去几年ARM设备的性能已经足够强M系列芯片、骁龙X Elite、甚至手机上的A系列芯片单核性能都不输中端x86。瓶颈从来不在算力而在指令集鸿沟和图形API鸿沟。FEX-Emu解决前者Wine解决系统调用DXMT解决图形渲染。三者缺一不可而Madeira的价值就在于把它们串成了一条可用的流水线。我实测过单独用FEX-Emu跑x86 Linux程序也单独用Wine跑Windows程序但把两者叠起来跑Windows游戏中间会遇到大量边界问题线程模型冲突、内存映射不一致、图形上下文丢失。Madeira要做的就是把这些边界问题在集成层消化掉。下面我会从架构、实操、踩坑、调优四个维度把这条链路彻底讲透。2. Madeira的三层架构拆解谁在干什么活2.1 FEX-Emu把x86-64指令“翻译”成ARM64FEX-Emu的核心是一个JIT编译器。它不模拟x86的每一条指令而是把x86-64的基本块动态翻译成ARM64指令然后缓存起来重复执行。这跟QEMU的用户态模拟类似但FEX-Emu针对游戏场景做了大量优化比如寄存器映射策略和标志位惰性计算。具体来说x86有16个通用寄存器ARM64有31个。FEX-Emu会把x86的寄存器映射到ARM64的固定寄存器上减少内存访问。标志位EFLAGS的处理更巧妙x86的很多指令会隐式修改标志位但实际用到标志位的指令并不多。FEX-Emu采用惰性求值只有在真正读取标志位时才计算避免每次算术运算都更新标志寄存器。实测数据在M1 Pro上FEX-Emu跑x86-64的7-Zip基准测试性能大约是原生ARM64版本的60%到70%。这个损耗主要来自JIT翻译开销和内存模型差异。对于计算密集型任务损耗可接受对于游戏关键看图形层能不能跟上。注意FEX-Emu需要Linux环境因为它依赖一些Linux特有的系统调用和内存管理接口。在macOS上直接跑FEX-Emu是不行的必须通过虚拟机或者Asahi Linux。2.2 Wine把Windows API“伪装”成POSIX调用Wine不是模拟器它是一个API兼容层。当Windows程序调用CreateFileW时Wine把它翻译成Linux的open调用CreateWindowEx时Wine通过X11或Wayland创建窗口。整个过程没有Windows内核参与所以性能损耗很小。但Wine的难点在于覆盖度。Windows API有成千上万个函数Wine只实现了其中最常用的子集。对于游戏来说最关键的是Direct3D、DirectSound、XInput这几个模块。Wine自带这些模块的开源实现但性能和兼容性参差不齐。在Madeira的架构里Wine运行在FEX-Emu之上。也就是说Wine本身也是x86-64代码被FEX-Emu翻译成ARM64执行。这带来一个额外好处Wine的Windows API实现不需要重新编译成ARM64直接复用现有的x86-64二进制即可。但坏处是Wine内部的每一次系统调用都要经过FEX-Emu的翻译层延迟会增加。2.3 DXMT把Direct3D“翻译”成MetalDXMT是一个相对年轻的项目它的目标是把Direct3D 11和部分Direct3D 12的调用翻译成Metal。为什么是Metal因为Madeira的主要目标平台是Apple Silicon而Metal是苹果生态的原生图形API性能开销最小。DXMT的工作方式类似于DXVKDirect3D到Vulkan但目标API不同。它拦截Windows程序发出的D3D调用转换成Metal的渲染命令。这个过程涉及着色器重编译D3D的HLSL着色器需要先编译成DXBC字节码再转换成Metal Shading Language最后编译成Metal的GPU二进制。实测下来DXMT在M1上的效率大约是原生Metal的50%到60%。对于轻量级游戏这个损耗可以接受对于3A大作帧率会明显下降。但考虑到这是在ARM设备上跑x86 Windows游戏能跑起来本身就是奇迹。层级组件输入输出性能损耗指令翻译FEX-Emux86-64指令ARM64指令30%-40%API兼容WineWindows APIPOSIX调用5%-15%图形翻译DXMTDirect3DMetal40%-50%三层叠加理论总损耗在60%到75%之间。也就是说一个原本在x86 Windows上跑60帧的游戏在Madeira上可能只有15到24帧。这个数字不漂亮但对于很多独立游戏和老游戏来说已经足够可玩。3. 在Apple Silicon上从零搭建Madeira环境3.1 系统选择Asahi Linux还是虚拟机如果你用的是M系列芯片的Mac第一步要决定跑在什么系统上。两个选择Asahi Linux或者macOS上的Linux虚拟机。Asahi Linux是原生安装的能直接访问GPU性能最好。但安装过程有风险需要分区、调整启动顺序而且不是所有Mac型号都支持。虚拟机方案更安全但GPU加速受限DXMT可能跑不起来。我的建议是如果你只是尝鲜先用虚拟机。UTM或者Parallels都行装一个ARM64的Ubuntu。确认Wine和FEX-Emu能跑起来之后再考虑要不要上Asahi Linux。因为Asahi Linux的GPU驱动还在完善中Metal支持是通过逆向工程实现的稳定性不如macOS原生。提示截至我写这篇内容时Asahi Linux的GPU驱动已经支持OpenGL和部分Vulkan但Metal支持还在开发中。如果你主要目标是跑D3D游戏macOS虚拟机方案反而更成熟因为可以直接用苹果的Metal驱动。3.2 安装FEX-Emu和Wine的先后顺序这里有一个容易踩的坑先装FEX-Emu再装Wine。因为Wine需要以x86-64模式运行而FEX-Emu提供了这个运行环境。如果你先装了ARM64版的Wine那它跑的是ARM64 Windows程序跟x86-64 Windows程序是两码事。具体步骤安装FEX-Emu的二进制包。Ubuntu下可以用PPAArch下用AUR。安装完成后FEXInterpreter命令应该可用。下载x86-64版的Wine。注意不要用系统包管理器里的Wine那个通常是ARM64版。去Wine官网下载x86-64的tar包解压到/opt/wine-x86_64。配置环境变量。把/opt/wine-x86_64/bin加到PATH最前面确保wine命令指向x86-64版本。用FEX-Emu运行Wine的配置工具FEXInterpreter /opt/wine-x86_64/bin/winecfg。如果能弹出窗口说明链路通了。这个过程我重复了三次才成功。第一次失败是因为PATH顺序不对系统调用了ARM64的Wine第二次失败是因为FEX-Emu的版本太老不支持Wine需要的某些指令第三次才跑通。3.3 DXMT的编译与注入DXMT通常以DLL的形式注入到Wine的D3D模块中。你需要编译d3d11.dll和dxgi.dll然后替换Wine自带的版本。编译DXMT需要Meson和Ninja以及Metal的着色器编译器。在Linux下编译Metal着色器需要metal-shaderconverter这个工具苹果没有开源但可以通过mesa的metal分支获取。编译完成后把生成的DLL放到Wine的system32目录下覆盖原文件。然后设置环境变量WINEDLLOVERRIDESd3d11n,b强制Wine加载DXMT而不是自带的D3D实现。注意DXMT目前只支持Direct3D 11Direct3D 12的支持还在实验阶段。如果你要跑D3D12游戏需要额外配置VKD3D-Proton但那是另一条技术路线了。4. 实测中遇到的五个典型问题与排查过程4.1 Wine乱码字体和编码的双重坑第一次跑起来Wine的配置界面满屏方块字。这是Wine的经典问题原因有两个缺少中文字体以及locale设置不对。排查过程先检查locale命令输出确认LANG和LC_ALL是zh_CN.UTF-8。如果不是修改/etc/default/locale。然后检查Wine的字体目录~/.wine/drive_c/windows/Fonts/发现是空的。Wine本身不带中文字体需要手动复制。从Linux系统里复制wqy-microhei.ttc或者Noto Sans CJK到Wine的字体目录然后在winecfg里把默认字体设置为这些字体。但即使这样某些程序的菜单还是乱码。这是因为Wine的字体替换机制有bug需要修改注册表。在winecfg的“显示”选项卡里把“允许字体替换”勾上然后手动添加替换规则把Tahoma替换成WenQuanYi Micro Hei。实测下来这套组合能解决90%的乱码问题。剩下的10%是程序自己硬编码了字体名只能通过修改程序的资源文件来解决。4.2 FEX-Emu的线程崩溃内存模型不一致跑某些游戏时FEX-Emu会突然崩溃日志里出现SIGSEGV和atomic operation failed。这是x86和ARM64内存模型差异导致的。x86采用强内存模型ARM64采用弱内存模型。x86程序默认认为多线程之间的内存访问是有序的但ARM64不保证这一点。FEX-Emu需要在翻译指令时插入内存屏障但有些情况下会漏掉。解决方案升级FEX-Emu到最新版本新版本对内存屏障的处理更完善。如果还是崩溃尝试设置环境变量FEX_TSOENABLED1强制启用TSOTotal Store Order模式。这会降低性能但能提高稳定性。对于特定游戏可以在FEX-Emu的配置文件中添加Multiblock0禁用多块优化减少并发问题。我实测下来开启TSO后崩溃频率从每小时一次降到每五小时一次。虽然性能下降约15%但稳定性提升明显。4.3 DXMT的着色器编译卡顿DXMT在第一次遇到新着色器时需要实时编译成Metal。这个过程可能耗时几百毫秒到几秒导致游戏卡顿。这是着色器编译风暴在DXVK上也有类似问题。缓解方法启用DXMT的异步编译选项。在配置文件中设置dxmt.asyncCompile True让着色器在后台线程编译不阻塞渲染线程。使用状态缓存。DXMT会把编译好的着色器缓存到磁盘下次启动时直接加载。确保DXVK_STATE_CACHE_PATH指向一个可写目录。如果游戏支持预编译着色器。有些游戏在启动时会预编译所有着色器这时候耐心等待不要跳过。实测数据开启异步编译后首次进入游戏的卡顿时间从30秒降到5秒后续游戏过程中基本无感。4.4 iOS上的尝试为什么这条路特别难关键词里出现了iOS我猜很多人想知道能不能在iPhone或iPad上跑Madeira。答案是技术上可行但实际极其困难。iOS的沙盒限制不允许JIT编译。FEX-Emu的核心就是JIT没有JIT性能会下降一个数量级。虽然iOS允许在开发者模式下启用JIT但需要连接Xcode而且每次重启后都要重新启用。另外iOS不允许动态加载可执行代码。Wine需要加载Windows的PE文件这在iOS上是被禁止的。除非把整个Wine和Windows程序静态编译成一个iOS应用但这需要大量的移植工作。目前社区里有人在尝试用iOS的虚拟化框架来跑Linux虚拟机然后在虚拟机里跑Madeira。但虚拟化框架只允许在M系列芯片的iPad上使用而且性能损耗很大。我试过在M1 iPad Pro上跑UTM虚拟机再跑Wine帧率只有个位数。提示如果你只是想在iOS上玩Windows游戏目前更现实的方案是串流。在PC上跑游戏用Moonlight或者Steam Link串流到iOS设备。延迟可以控制在20毫秒以内体验比本地模拟好得多。4.5 性能调优从15帧到30帧的折腾默认配置下Madeira跑《上古卷轴5》只有15帧。经过一系列调优我把它提到了30帧。以下是有效的调优手段关闭FEX-Emu的多块优化Multiblock0。虽然理论上多块优化能提高性能但在Wine场景下多块会导致频繁的上下文切换反而降低性能。启用Wine的CSMTWINEDEBUG-all并在winecfg里启用“CSMT”选项。CSMT把图形命令放到独立线程处理减少主线程阻塞。调整DXMT的队列深度在配置文件中设置dxmt.maxFrameLatency 1减少帧延迟。使用游戏模式Linux的gamemode可以调整CPU调度器把游戏进程的优先级提高。降低分辨率这是最有效的手段。从1080p降到720p帧率直接翻倍。调优项默认值调优值帧率变化多块优化开启关闭3帧CSMT关闭开启5帧帧延迟312帧分辨率1080p720p15帧这些数字是在M1 Pro上测的不同设备会有差异。但趋势是一致的分辨率是最大的杠杆其次是CSMT。5. 这套方案适合谁不适合谁5.1 适合的场景老游戏、独立游戏、生产力工具Madeira最适合跑2015年之前的老游戏和像素风独立游戏。这些游戏对GPU要求低D3D9或D3D11的调用简单DXMT翻译起来效率高。我实测《植物大战僵尸》《星露谷物语》《空洞骑士》都能稳定60帧。生产力工具方面一些老的Windows软件比如Office 2010、Photoshop CS6也能跑起来。但要注意这些软件可能依赖一些Wine没有完全实现的API需要逐个测试。5.2 不适合的场景3A大作、反作弊游戏、专业视频剪辑3A大作不用想了。即使能跑起来帧率也在个位数到十几帧之间没有可玩性。反作弊游戏更麻烦因为反作弊系统会检测Wine环境直接封号。专业视频剪辑软件依赖GPU加速DXMT的Metal翻译层还不支持视频编码接口。注意如果你打算在Madeira上跑在线游戏先确认反作弊系统是否允许。EAC和BattlEye都有Linux支持但需要游戏厂商主动启用。没有启用的游戏不要尝试。5.3 与原生ARM64方案的对比如果你的目标只是跑ARM64 Linux程序那不需要Madeira。直接装Asahi Linux或者用Docker的ARM64镜像就行。Madeira的价值在于复用x86-64生态让你不用等开发者重新编译。但代价是性能损耗和兼容性问题。如果你能等到原生ARM64版本那原生版本永远是最好的选择。Madeira是一个过渡方案不是终极方案。6. 几个容易被忽略的细节和我的个人经验第一个细节FEX-Emu的rootfs。FEX-Emu需要一个x86-64的rootfs来提供基础库。很多人直接用宿主系统的ARM64库结果Wine跑不起来。正确的做法是用debootstrap创建一个x86-64的Debian rootfs然后在FEX_ROOTFS环境变量里指向它。第二个细节Wine的Windows版本。winecfg里可以设置模拟的Windows版本。对于老游戏设置成Windows XP或Windows 7兼容性最好。对于新游戏设置成Windows 10。但不要设置成Windows 11因为Wine对Windows 11的API实现还不完整。第三个细节DXMT的日志。DXMT默认不输出日志出问题时很难排查。可以在环境变量里设置DXMT_LOG_LEVELdebug然后把日志重定向到文件。日志里会显示每个D3D调用的翻译结果以及着色器编译的耗时。第四个细节输入延迟。Madeira的输入延迟比原生高不少因为每次输入都要经过FEX-Emu翻译、Wine处理、DXMT渲染。对于节奏快的游戏这个延迟可能致命。缓解方法是启用Wine的RawInput绕过一些中间层。我个人在实际操作中的体会是Madeira目前的状态像早期的Wine——能跑但需要折腾。如果你享受折腾的过程那它会给你很多乐趣。如果你只想双击图标就能玩那还是等成熟方案吧。这个项目最大的价值不是现在能跑多少游戏而是它验证了一条技术路径在ARM设备上通过多层翻译运行x86 Windows程序是可行的。随着FEX-Emu和DXMT的迭代性能损耗会越来越小兼容性会越来越好。如果你对这块感兴趣建议从FEX-Emu的GitHub仓库开始看那里的文档和issue比任何教程都详细。