Linux Desktop on Apple Silicon/M1 in Practice
I bought M1 MacBook Air. It is the fastest computer I have, and I have been a GNOME/GNU/Linux user for long time. It is obvious conclusion that I need practical Linux desktop environment on Apple Silicon/M1.
Fortunately, Linux already works on Apple Silicon/M1. But how practical is it?
- Two native ports exist, but they don't have enough device support yet. It certainly takes some time.
- QEMU can run with Hypervisor.framework with:
It allows to run code on CPU natively. But what about GPU? Unfortunately, QEMU is also not optimized so much for macOS.
As I needed Linux desktop right now, I decided to hack QEMU. The most difficult challenge is obviously accelerated graphics, but there is Virgil 3D; a birdge to expose host OpenGL to the guest. https://virgil3d.github.io
It unfortunately didn't work on macOS host. So I just made it work. That's it. Here is a video demonstrating OpenGL on Linux on Apple Silicon/M1:
- The hvf patches are merged into current master.
- The installation script is fixed.
- Added OpenGL support.
- Enforced pixel by pixel display.
- Tells physical/pixel window size to the guest. Now Fedora can properly deal with Retina and respond to window size change.
- Added cursor composition.
- A bug which keeps e.g. command key pressed is fixed.
Added device change support. (i.e. you can plug/unplug an earphone while QEMU is running.)
- Add punchhole operation. (The disk image consumes physical storage only when it actually has data.)
- Optimized transfer unit.
Virgil 3D renderer
Improved OpenGL ES support.
Do It Yourself
1. Disable System Integrity Protection
You can enable it again after setup. It must be disabled to build ANGLE.
2. Open a terminal.
3. Install GLib, Meson, Pixman and pkg-config with Homebrew.
brew install glib meson pixman pkg-config
4. Make a empty directory and change the working directory to it.
curl https://gist.githubusercontent.com/akihikodaki/87df4149e7ca87f18dc56807ec5a1bc5/raw/8a27f179aba5564fb1cba77561c65298c0cbce01/run.sh | bash -
bin/qemu-img create var/virtio.raw 64G
It doesn't consume the physical space until it has data, so you can make the image very large. However, you will see odd behavior if you try to write data more than the physical disk allows.
curl -O https://download.fedoraproject.org/pub/fedora/linux/releases/33/Silverblue/aarch64/iso/Fedora-Silverblue-ostree-aarch64-33-1.2.iso
./run -cdrom Fedora-Silverblue-ostree-aarch64-33-1.2.iso
Proceed the installation process, and now you can run Fedora by executing
Just download the latest
run.sh and execute it in your workspace directory.
Choosing OpenGL profile
gl=offwill disable Virgil 3D GPU. Most stable but laggy.
gl=corewill enable OpenGL.framework. Unstable.
gl=eswill enable ANGLE. Stable and fast.
Test OpenGL with piglit.
piglit run all -x spec@ext_timer_query@time-elapsed -x 'spec@arb_timer_query@query gl_timestamp' --timeout 9 results/all
The disabled tests will cause qemu crash due to the following bug: https://bugs.chromium.org/p/angleproject/issues/detail?id=5701
vhost-user-gpu would prevent QEMU process from crashing by isolating graphics acceleration process, but it needs modifications to run outside Linux because:
- historically, vhost-user is a reimplementation of Linux kernel's vhost interface, and it relies on kernel headers for interface definitions and
- vhost-user uses eventfd which is only available on Linux.
It shouldn't be difficult, but I'm satisfied even without process isolation so I don't.
Upstreaming is in progress. Hopefully the features I implemented will work just by running
brew install qemu in the future.
- Epoxy: https://github.com/anholt/libepoxy/pull/239
- QEMU: https://patchew.org/search?q=project%3AQEMU+from%3Aakihiko.odaki%40gmail.com
- Virgil 3D renderer: https://gitlab.freedesktop.org/virgl/virglrenderer/-/merge_requests?scope=all&utf8=✓&state=all&author_username=akihiko.odaki
As I described here, such a virtualization software is practical and efficient approach to run Linux desktop. The performance overhead is also acceptable for daily use, and it even provides better integration of Linux and macOS. For example, you can switch macOS and Linux with three-finger gesture on trackpad. You can use VirtFS.
However, there are complexities that such a virtualization adds. It basically means sharing one hardware with two systems, so you have to allocate them properly or it ends up with bad user experience. The allocation problem happens everywhere (HID like keyboard, computing resource like CPU, power management, etc.). This approach is efficient but not the best.
In long term, native Linux port is the best option. However, it is not practical if it takes too long before it becomes available. Therefore, we should consider hybrid approaches. marcan42, the founder of Asahi Linux, has an idea to run macOS on KVM on Linux to support complex devices, for example: https://twitter.com/marcan42/status/1361999648819269636
Another approach is to get macOS device support softwares work on Linux. In the past, there was NDISWrapper, a project to bring some Windows drivers to Linux. There was also Cider, a research project to "duct-tape" XNU's IOKit to Linux to bring macOS drivers to Android. https://www.cs.columbia.edu/~nieh/pubs/asplos2014_cider.pdf
By taking those approaches, it is possible to reduce dependencies on macOS gradually, not at once.
@knazarov wrote Homebrew formulae.