DEV Community

Takahiko Inayama
Takahiko Inayama

Posted on

Do M1 Mac Dream of x86 Linux?

My primary machine is MacBook Pro 14” with M1 Max chip. It’s been great so far. It’s “scary” fast. But there is only one thing I can’t do with it. It doesn’t support to run Intel based VMs with Virtualization Framework due to the limitation of Rosetta translation layer.

About the Rosetta Translation Environment | Apple Developer Documentation

Rosetta can translate most Intel-based apps, including apps that contain just-in-time (JIT) compilers. However, Rosetta doesn’t translate the following executables:

  • Kernel extensions
  • Virtual Machine apps that virtualize x86_64 computer platforms

So I can’t run x86 VMs with VirtualBox like I often done with Intel Mac.

I’ve written another article about this topic. I used UTM at last time.

How to run x86 Linux on M1 MacBook?

Running Vagrant with QEMU backend

Let’s try Vagrant as a frontend at this time. Vagrant supports bunch of virtualization softwares as its backend.

vagrant-qemu is a great plugin for Apple Silicon Mac owners like me.

QEMU support to translate CPU instructions. Actually, Docker had been used QEMU to run x86 containers on Apple Silicon Mac before its transition to Rosetta.

The Magic Behind the Scenes of Docker Desktop | Docker

With support for Apple M1 ARM Mac and QEMU included in Docker Desktop, you are able to build and use multi-architecture images (Linux x86, ARM, Windows) on whatever platform you are working on out of the box.

There is an amazing gist which describe how to run VMs with QEMU and Vagrant.

Run x86 VM's on Mac M1 arm using vagrant with qemu hypervisor

Running x86 Linux VMs

Running Rocky Linux 9

Running Rocky Linux 9 is pretty simple.

You’ll need a Vagrantfile like this.

Vagrant.configure("2") do |config|
    config.vm.box = "rockylinux/9"

    config.vm.provider "qemu" do |qe|
      qe.arch = "x86_64"
      qe.machine = "q35"
      qe.cpu = "max"
      qe.net_device = "virtio-net-pci"
      qe.memory = "8G"
      qe.smp = "cpus=10,sockets=1,cores=10,threads=1"
    end
    config.vm.synced_folder '.', '/vagrant', disabled: true
    config.vm.network "forwarded_port", guest: 8080, host: 18080
  end
Enter fullscreen mode Exit fullscreen mode

Then you can use it with no hustles.
Image description

Running Rocky Linux 8

Running Rocky Linux 8 is a bit tricky.(Including on Vagrant with VirtualBox backend)

You can’t run images on Vagrant directly.

Vagrant box rockylinux/8 - Vagrant Cloud

You’ll stuck on during vagrant up with a Vagrantfile like this.

Vagrant.configure("2") do |config|
    config.vm.box = "rockylinux/8"

    config.vm.provider "qemu" do |qe|
      qe.arch = "x86_64"
      qe.machine = "q35"
      qe.cpu = "max"
      qe.net_device = "virtio-net-pci"
      qe.memory = "8G"
      qe.smp = "cpus=10,sockets=1,cores=10,threads=1"
    end
    config.vm.synced_folder '.', '/vagrant', disabled: true
    config.vm.network "forwarded_port", guest: 8080, host: 18080
  end
Enter fullscreen mode Exit fullscreen mode

You’ll find it failed to boot by using QEMU Monitor.
Image description

I’ve experienced the symptom like this before when I tried to run this OS with Vagrant and VirtualBox. All you have to do is make UEFI available while booting.

How to do it with QEMU? Fortunately, there is a package named Open Virtual Machine Firmware(OVMF). You can download its BIOS data from a package for Debian.

Debian -- Package Search Results -- ovmf

You’ll find data.tar.xz in it when you extracted it. So extract this too. Then you’ll find the BIOS image in usr/share/OVMF/OVMF.fd.

Then you need to tweak the Vagrantfile like this.

Vagrant.configure("2") do |config|
    config.vm.box = "rockylinux/8"

    config.vm.provider "qemu" do |qe|
      qe.arch = "x86_64"
      qe.machine = "q35"
      qe.cpu = "max"
      qe.net_device = "virtio-net-pci"
      qe.memory = "8G"
      qe.smp = "cpus=10,sockets=1,cores=10,threads=1"

      # Added
      qe.extra_qemu_args = %w(-bios /path/to/OVMF.fd)
    end
    config.vm.synced_folder '.', '/vagrant', disabled: true
  end
Enter fullscreen mode Exit fullscreen mode

And….

Tada! It’s working!!

Image description

Conclusion

Vagrant made it simple to create and configure VMs. It’s nice to be able to use it to run x86 Linux on my M1 Mac.

Of course UTM is still great for GUI usage. But vagrant-qemu definitely filled more lightweight VM usage.

References

This article is also available on Medium.

Top comments (0)