# Linux Desktop on Apple Silicon 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.

Fortunately, Linux already works on Apple Silicon/M1. But how *practical* is it?

- Two native ports exist.
  - Corellium. It is obsolete. https://corellium.com/blog/linux-m1
  - Asahi Linux. It is greatly improving and may be usable for certain
    workloads, but it lacks e.g. graphics acceleration for now.
    https://asahilinux.org
- QEMU can 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 bridge 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:

https://www.youtube.com/watch?v=k0bVlVQU2JQ&list=PLesZxBYUPr3wdU3sONUv4Q7UDOg1Dn_Ue&index=4

## Modifications

### QEMU

#### ui/cocoa

- Added OpenGL support.
- Enforced pixel by pixel display.
- Added cursor composition.
- Improved key mappings (e.g. Japanese IME keys, 2021-06-17)

#### hw/block

- File locking on macOS is fixed. (2021-07-07, Add `file.locking=on` to `drive`
  to prevent drive breakage in case you concurrently launch the same virtual
  machine by mistake.)

#### coreaudio

- Fix device change (2022-02-26)

### Virgil 3D renderer

Improved OpenGL ES support.

## Do It Yourself

## @knazarov's Homebre Formulae

It is independently maintained so may be a bit older, but you may still find it
useful.

https://github.com/knazarov/homebrew-qemu-virgl

### Setup

1\. Open a terminal.

2\. Install GLib, Meson, Pixman, pkg-config and spice-protocol with Homebrew.

```bash
brew install glib meson pixman pkg-config spice-protocol
```

3\. Make a empty directory and change the working directory to it.

4\.

```bash
curl -L https://gist.github.com/akihikodaki/87df4149e7ca87f18dc56807ec5a1bc5/raw/2e1e5572cec78625df452b16b0ee924ef86aed0d/run.sh | bash -
```

5\.

```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.

6\.

```bash
curl -LO https://download.fedoraproject.org/pub/fedora/linux/releases/41/Silverblue/aarch64/iso/Fedora-Silverblue-ostree-aarch64-41-1.4.iso
```

7\.

```bash
./run -cdrom Fedora-Silverblue-ostree-aarch64-41-1.4.iso
```

Proceed the installation process, and now you can run Fedora by executing `./run`.

Note: you won't get keyboard to work before Linux boots because TianoCore, the UEFI firmware does not support virtio-keyboard used in this configuration.

### Updating

Just download the latest `run.sh` and execute it in your workspace directory.

## Choosing OpenGL profile

Edit `run`.

- `gl=off` will disable Virgil 3D GPU. Most stable but laggy.
- `gl=core` will enable OpenGL.framework. Unstable.
- `gl=es` will enable ANGLE. Stable and fast.

## Upstreaming

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

## Some insights

### QEMU

This QEMU modification is **not** secure. The graphics acceleration code lives
in the same process with everything else of the virtual machine and it is
*huge*; the graphics stack involves LLVM for shader compilation, and a simple
bug in the stack can lead to complete takeover of the guest.

vhost-user-gpu provides graphics acceleration isolation, but it needs
modifications to run outside Linux because:
- historically, vhost-user is a re-implementation 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. The graphics acceleration process would be still shared and it would
remain possible that one graphical process exploit leads to disclosure of the
entire graphics output anyway.

### Linux desktop on Apple Silicon/M1 in general

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 the
resource 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. Asahi Linux is promising and
you may find it favorable than my modified QEMU for your use case even today.