A Song of x86 on ARM - Part 2
By Salvador Liébana
Then, I don't remember exactly the moment, probably at the end of 2019, I discovered ptitSeb's attempt of x86 emulation on ARM with BOX86 i. By that time, Exagear was almost dead (also closed source and quite expensive!) and QEMU was a no-go due to performance reasons. ptitSeb is another great mind from the Pandora golden era; he has on his github repo tons of ports for ARM Linux, I can’t even enumerate them properly. If you are into ARM Linux gaming, Ptitseb is a “You-know-who” level reference like Notaz. Because most of the games that he wanted to have running on ARM Linux were desktop ones and used OpenGL desktop profile, he created a very nice project called GL4ESii; basically a wrapper that translates OpenGL calls to OpenGL ES ones, because at that time, most of our platforms didn't have a desktop GL profile at all on Linux, just OpenGL ES (AKA GLES). I didn’t need GL4ES on RPI3 because I was running on MESA and had 2.1 OpenGL profile at that moment, and while he showed a lot of x86 Linux games running slowly on his Pandora (quite underpowered by that time) my RPI3 was too weak for real x86 emulation, or at least I believed that and discarded the idea to even try it.
What I did try was to run some Mono games natively (yeah, not x86 emulation yet!) thanks to FNA after reading this article by Ptitseb himselfiii on Odroid magazine. Basically you only need a Mono game that has FNA library support iv and to compile some open source libraries plus some tweaks to make the games run with native Mono instead of x86 or x86_64 mono and libs…if you have the libs sources…if the libs version match with the ones that the game uses… so, it’s a hit or miss! A painful experience! On RPI3 I was able to run Owlboy, Hammerwatch, Stardew Valley.. but not that many because of lack of s3tc texture decompression support, available on RK3399 (and other newer Panfrost platforms) and RPI4.
At the end of 2019 the RPI4 launched, with 4 BIG cores and what I thought would be a far superior GPU, the Videocore 6…well, it wasn’t that fast on Desktop GL profile sadly. Inside x11 I measured an increase of performance around 25 % on that profile (2.1 GL) at that time. Quite disappointed! But hey, the 4 big cores are quite powerful ones! Then I attempted BOX86, the ptitSeb x86 userspace emulator for armhf platforms (AKA 32bit armv7 platforms)...with a twist. With a twist? Yes, there is a twist on BOX86 (and BOX64); and it’s that BOX86 will put a wrapper around most system x86 libraries allowing them to behave like native armhf ones, in order to improve performance and make the emulation easier (if not, you would have to get all those x86 libs from somewhere).
My first tests on BOX86 (end of 2019-early 2020) were without dynarecv, the part of the emulator that makes a dynamic recompilation at runtime and speeds up largely any emulation workload. Not because I desired that! It was that I just omitted to enable the dynarec on compilation. On emulation, running on interpreter (so, dynarec off) it’s about as 3 to 10 times slower than with dynarec. But my pi4 didn’t care that much about dynarec, it had a lot of CPU power to waste (not GPU tho), the wrapping was already doing a great job and the 4 big cores were working phenomenally to me…at least to me, someone that knows how hard it is to emulate x86 or any complex platform on a modestly powerful one. The first games tested were of course Linux x86 games, like Heretic 2, World of goo, Unreal Tournament 99 and tons of other games from GoG and Humble. I was following the BOX86 development day by day (like I do now, as a fervent ptitSeb acolyte), but the development was a bit stagnant until ptitseb got BOX86 to be able to emulate WINE x86 and then able to emulate x86 Windows software! Yes, the overhead was insane and it’s still problematic today, especially on DirectX games because WINE uses a wrapper to translate DirectX calls to OpenGL ones (not GLES of course, you need a GL capable GPU driver or GL4ES if not the case) and that means slowness and tons of cpu cycles wasted on that translation.. cycles we miss on the real thing, emulating the games themselves, and wine, and his libs!!
Steam Linux x86 was supported on BOX86 on that same year, 2020, but we lacked the “full” mode because the Steam client uses Chrome to handle browsing and Chrome ditched x86 a long time ago. So, Steam wasn’t really a thing, we relied on GoG, Humble and itch.io Linux x86 games releases because they were not DRM protected. There were many games that didn’t work well and do not work great now, especially the Unity ones, but BOX86/BOX64 are improving on these games day by day.
With BOX86 already “kinda” mature, ptitSeb jumped to a 64 bit version, BOX64vi that will require an aarch64 platform in order to emulate x86_64 Linux software (and months later WINE x86_64 was supported too!). It’s already on the Manjaro ARM repositories and also will be on Armbian’s soon!! But, to run BOX86 and x86 software on an aarch64 system you will need a full 32 bit userspace, like Windows x64 provides by default in order to run x86 windows software on a 64 bit OS. Installing that full set of 32 bit libs will “cost” around 1 gigabyte, more or less. But then you are able to run many RPI only software too, not just BOX86.
My favorite platform for testing both BOX86 and BOX64 are RK3399s but that will most probably change on the near future with RK3588s and competitor’s new SoC’s that will also have Panfrost support, essential for what I do! BOX86 and BOX64 are still not fully mature and we have a long way to the top! But we will be there!