「FEX-Emu」是一款開源軟體,它能夠在ARM架構的Linux系統轉譯x86架構的程式,進而執行Steam上的Windows遊戲。
圖例:在ARM架構的Raspberry Pi 5玩Steam的3D遊戲《Alpaca Stacka》
本文討論FEX-Emu的安裝與用法。
1. Fex-Emu簡介#
FEX-Emu啟動時會掛載自身的RootFS,並將x86程式轉譯為arm64的行程,目前僅支援arm64 (aarch64)的系統,不支援armhf 32位元。不過32位元x86架構的程式依然能夠轉譯執行。
討論這個專案的時候,常常會跟 Box64/Box86專案一同提及吧。根據Box64作者ptitSeb在2022年做的測試,FEX-Emu執行速度比QEMU User快,但是比Box64慢。
我自己測試的時候也是這種感覺,雖然FEX-Emu不斷的在更新,但是到了2024年,樹莓派上的FEX-Emu遊戲玩起來還是比Box64要卡。
即使如此,FEX-Emu還是有它的優勢在。
Fex-Emu原理圖如下:
相較Box64,FEX-Emu有RootFS,提供更完整的Linux環境,不用像Box64那樣得裝一堆額外套件補驅動。
論FEX-Emu比較有名的應用案例,就是Asahi Linux了。
讓Apple M1平台能跑Steam大型遊戲的功臣,Fex-Emu就是其中一個組件。 AAA gaming on Asahi Linux
FEX-Emu作者也在Qualcomm Snapdragon 8cx平台演示了玩《GTA 5》的可能性。
根據不可靠消息,Valve有在贊助FEX-Emu專案的開發,或許是在為Steam Deck的未來鋪路?這個消息我找不到新聞證實,只有一篇 Tom’s Hardware的新聞說Valve可能會推出ARM版的Steam Deck。
此外,既然Box64能移植到Android Termux proot執行,FEX-Emu或許能在Android跑?GitHub已經有一些試驗的專案了。但是FEX-Emu Wiki直接明說了:現階段不可能支援Android,主要還是以Linux為主。
2. 測試環境#
- Raspberry Pi 5
- Raspberry Pi OS 12 Bookworm
- FEX-Emu 2410
執行前請用指令vulkaninfo --summary
,檢查Raspberry Pi的GPU加速有無正常運作。
3. 安裝FEX-Emu#
- FEX-Emu目前僅支援4K Page的系統,Raspberry Pi 5使用16K Page,故需要調整系統開機參數,改回4K Page。
echo '# 4k pages
kernel=kernel8.img
'| sudo tee -a /boot/firmware/config.txt
2.重開機套用變更。執行指令確認已經啟用4K Page
getconf PAGESIZE
- Fex-Emu作者有提供Python安裝指令稿,但是僅支援Ubuntu,Debian不行。參考Wiki手動建置,安裝依賴套件:
sudo apt install git cmake ninja-build pkgconf ccache clang llvm lld binfmt-support libssl-dev python3-setuptools g++-x86-64-linux-gnu libgcc-12-dev-i386-cross libgcc-12-dev-amd64-cross nasm python3-clang libstdc++-12-dev-i386-cross libstdc++-12-dev-amd64-cross libstdc++-12-dev-arm64-cross squashfs-tools squashfuse libc-bin libc6-dev-i386-amd64-cross lib32stdc++-12-dev-amd64-cross qtdeclarative5-dev qml-module-qtquick-controls qml-module-qtquick-controls2 qml-module-qtquick-dialogs pkg-config libclang-dev libdrm-dev libxcb-present-dev libxcb-dri2-0-dev libxcb-dri3-dev libxcb-glx0-dev libxcb-shm0-dev libxshmfence-dev
- 複製FEX-Emu原始碼,編譯FEX-Emu
git clone --recurse-submodules https://github.com/FEX-Emu/FEX.git
cd FEX
mkdir Build
cd Build
CC=clang CXX=clang++ cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DUSE_LINKER=lld -DENABLE_LTO=True -DBUILD_TESTS=False -DENABLE_ASSERTIONS=False -G Ninja ..
ninja
- 安裝FEX-Emu
sudo make install
- FEX-Emu可能會跟box64與qemu-user-static衝突,故必須將
/etc/binfmt.d/
和/usr/lib/binfmt.d/
的檔案移除。
update-binfmts --display
- 向Linux的binfmt服務註冊FEX-Emu,讓系統自動將x86程式交給FEX-Emu轉譯
sudo ninja binfmt_misc
sudo systemctl status systemd-binfmt
4. 設定FEX-Emu的RootFS#
- 執行
FEXRootFSFetcher
,下載最新Ubuntu x86_64的RootFS到~/.fex-emu
,解壓縮
./FEXRootFSFetcher
- RootFS裡面的套件將作為FEX-Emu轉譯程式時的依賴,也就是說執行x86架構程式的時候會先從RootFS裡面去找相關的函式庫,但有些檔案並沒有預先安裝。此時可用
~/.fex-emu/RootFS
的指令稿,chroot進去RootFS,補足中文字體、AppImage libfuse等套件:
cd ~/.fex-emu/RootFS/Ubuntu_24_04
# 進入chroot
sudo ./unbreak_chroot.sh
apt update
apt install fonts-noto-cjk libfuse2
# 退出chroot
exit
sudo ./break_chroot.sh
- 接著執行
FEXConfig
圖形程式,將Ubuntu的RootFS設定為預設。
5. 執行x86架構的Linux程式#
Wiki寫得不清不楚的…我是看NicoD的影片才知道個大概
這裡執行的僅限x86架構的Linux二進位檔,Wine我們下一節再談。
將要執行的程式放到任意目錄,例如我使用 Firefox x86_64的二進位執行檔,下載後將tar.bz檔案解壓縮。
開啟終端機,用FEXLoader
執行,它會進行轉譯,並把x86_64的程式轉化為arm64的行程
FEXLoader ./firefox-bin
如果有註冊binfmt,那麼直接執行x86程式,系統應該也會自動交給FEX-Emu轉譯
./firefox-bin
至於FEXBash
是用來執行x86程式的封裝指令稿之用的。
這裡有個問題:既然有RootFS了,我們就chroot進去裝x86版本的程式就好了啊,為何要獨立執行呢?嗯,這就是FEX-Emu設計上讓人困惑的地方,程式究竟該裝在宿主機目錄呢,還是RootFS內呢?我是覺得,單一x86執行檔就放在RootFS外面執行,需要依賴套件管理器的x86程式再用RootFS內部的APT裝。
6. 用Wine執行Windows程式#
雖然Debian系發行版支援Multiarch,我們也不要在ARM的宿主機用APT硬裝x86的Wine套件,因為容易遇到依賴地獄問題,且不是所有Linux發行版都能像Debian這樣幹。
Box64執行Wine的方式是手動下載Wine的二進位執行檔,而非透過APT安裝。然而這種安裝方法十分麻煩,也不利於Winetricks執行。
那麼,就在Ubuntu的RootFS裡面裝x86版的Wine吧!FEX-Emu作者已經幫我們裝好了,可以直接用。
不信?執行FEXBash winecfg
,Wine界面這不就出來了嗎!
雖然Wine是裝在RootFS內部的,但WINEPREFIX卻是位於~/.wine
DXVK似乎沒有安裝的樣子,我們得手動 下載安裝DXVK放到對應位置。
如果要用Wine執行exe:
FEXBash
wine "exe路徑"
7. 執行Steam遊戲#
關於Steam安裝,FEX-Emu Wiki寫要裝在宿主機,不是RootFS,還說這是一個很複雜的程式,啟動很容易出問題。
- 給Debian啟用i386架構支援
sudo dpkg --add-architecture i386 && sudo apt update
- 從Steam官網下載deb套件
wget https://cdn.cloudflare.steamstatic.com/client/installer/steam.deb
sudo apt install ./steam.deb
- 在執行Steam前,需要設定以下兩個環境變數,跳過一些依賴的檢查
export STEAMOS=1
export STEAM_RUNTIME=1
- Steam的執行檔其實是一個封裝指令稿,故使用FEXBash執行:
FEXBash steam
等待依賴裝完。若Steam Client WebHelper崩潰,嘗試停用GPU加速。
只要Steam開起來後面就不用煩惱了,Steam會自動給Windows遊戲下載Proton。
理論上是這樣啦,但是在我的Raspberry Pi上Steam一直崩潰(Github issue也不時有人碰到),可能是官方更新太快,FEX-Emu作者來不及修正的緣故。這時得改用 SteamCMD下載遊戲了。
8. 測試FEX-Emu的3D加速#
通過FEXBash執行Wine,確認能使用3D加速。
比較下二者結果,確認GPU有沒有跑起來
glxinfo | grep OpenGL
→ 讀到Braodcom的GPU
FEXBash glxinfo | grep OpenGL
→ 讀到llvmpipe
FEXBash wine "exe路徑"
→ 讀到Braodcom的GPU
若FEX的RootFS內部無法使用3D加速,可能得使用 ThunkLib。