In this article we will show you how to run Ubuntu on Mac using QEMU, a machine emulator and virtualiser.
This is normally quite useful if you need to have a Linux distribution running for any reason, like learning or testing.
1 – Installing QEMU
brew install qemu
Once you have finished the installation on your local machine, you can double check the version using the qemu executable installed. The executable you should use will depend on what system are you currently running on.
You can see a list of all the executables for each architecture that Homebrew has installed in our machine.
$ ls /opt/homebrew/bin/qemu-* /opt/homebrew/bin/qemu-edid /opt/homebrew/bin/qemu-system-cris /opt/homebrew/bin/qemu-system-mips64el /opt/homebrew/bin/qemu-system-s390x /opt/homebrew/bin/qemu-img /opt/homebrew/bin/qemu-system-hppa /opt/homebrew/bin/qemu-system-mipsel /opt/homebrew/bin/qemu-system-sh4 /opt/homebrew/bin/qemu-io /opt/homebrew/bin/qemu-system-i386 /opt/homebrew/bin/qemu-system-nios2 /opt/homebrew/bin/qemu-system-sh4eb /opt/homebrew/bin/qemu-nbd /opt/homebrew/bin/qemu-system-loongarch64 /opt/homebrew/bin/qemu-system-or1k /opt/homebrew/bin/qemu-system-sparc /opt/homebrew/bin/qemu-storage-daemon /opt/homebrew/bin/qemu-system-m68k /opt/homebrew/bin/qemu-system-ppc /opt/homebrew/bin/qemu-system-sparc64 /opt/homebrew/bin/qemu-system-aarch64 /opt/homebrew/bin/qemu-system-microblaze /opt/homebrew/bin/qemu-system-ppc64 /opt/homebrew/bin/qemu-system-tricore /opt/homebrew/bin/qemu-system-alpha /opt/homebrew/bin/qemu-system-microblazeel /opt/homebrew/bin/qemu-system-riscv32 /opt/homebrew/bin/qemu-system-x86_64 /opt/homebrew/bin/qemu-system-arm /opt/homebrew/bin/qemu-system-mips /opt/homebrew/bin/qemu-system-riscv64 /opt/homebrew/bin/qemu-system-xtensa /opt/homebrew/bin/qemu-system-avr /opt/homebrew/bin/qemu-system-mips64 /opt/homebrew/bin/qemu-system-rx /opt/homebrew/bin/qemu-system-xtensaeb
In our case we are running a MacBook using Apple M1 Pro chip. This chip belongs to the category of ARM processors family, therefore the architecture of our machine is AArch64 or ARM64. We are very happy with this latest version of Apple Silicon processors, if you’re looking for a new good laptop for development click on the link below.
Coming back to our main topic, having an ARM64 architecture system means that we should run the following and see something like what’s shown below as the output.
$ qemu-system-aarch64 --version QEMU emulator version 7.2.0 Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers
You can check what architecture your system has by executing this:
$ uname -m arm64
As you can see, in our system it return
arm64. Check what your architecture is and stick to that executable, it will work for some commands like
"qemu-system-XXX --version", but it’s better to clarify this from the very beginning to avoid confusion.
2 – Download Ubuntu (or any Linux Distribution)
3 – Create empty image
Create a QEMU empty image where to install your Ubuntu OS later. To do so, run the following command:
$ qemu-img create -f raw ~/qemu/ubuntu-latest.raw 40G
4 – Download pre-built EDK2 UEFI image for QEMU
You can download the image from this link:
(Alternatively you can build them yourself, although we’ve decided to keep it simpler as that would be out of the scope of this article)
To make things easier, you can move the
.tar.gz file to your
~/qemu directory. For example:
mv ~/Downloads/QEMU_EFI-*.tar.gz ~/qemu
If you are interested in understanding what UEFI drivers are, you can also check this article.
5 – Decompress the tar.gz file
In order to get the content of this compressed file, you will have to decompress it by running:
tar xzvf QEMU_EFI-*.tar.gz
You should be seeing these two new files in your current location once decompression is done:
Let’s start with the installation now!
7 – Install Ubuntu Server
At this point, we should have everything we need to install Ubuntu server in our virtual machine. Our example will work for our ARM machine, so you’ll have to change it slightly for your system.
In our Macbook M1 Pro, the command looks like the following:
qemu-system-aarch64 \ -monitor stdio \ -M virt,highmem=off \ -accel hvf \ -cpu host \ -smp 4 \ -m 3000 \ -bios QEMU_EFI.fd \ -device virtio-gpu-pci \ -display default,show-cursor=on \ -device qemu-xhci \ -device usb-kbd \ -device usb-tablet \ -device intel-hda \ -device hda-duplex \ -drive file=ubuntu-latest.raw,format=raw,if=virtio,cache=writethrough \ -cdrom ubuntu-22.04.1-live-server-arm64.iso
If your ISO image and your QEMU_EFI.fd file are not located in the current directory, you’ll have to modify the paths accordingly or move them to your current directory.
It’s worth mentioning that at the time of writing (22/12/2022), there’s a bug in QEMU that doesn’t allow to set our memory higher than 3GB using
highmem=off in our M1. Hopefully this will be sorted in the future.
Once you run the command above, if everything goes well, you should be seeing a screen similar to this:
"Try or Install Ubuntu Server" and hit Enter. You will have to go through the installation wizard, but it’s very simple. Nothing special to worry about.
You should be seeing a screen similar to this during the final process of the installation:
You’ll have to wait until the option at the bottom shows
"Reboot Now". Please don’t cancel it before that, even if the label at the top already shows
Once the installation is completed, you can then quit at any time and modify the previous script to always boot from the image instead of from the CD-ROM image (ISO). Let’s see how!
8 – Start Ubuntu using QEMU
This step is very similar to the one we specified earlier, the only difference is that we will be removing the
-cdrom option from our command.
It’d look like this then:
qemu-system-aarch64 \ -monitor stdio \ -M virt,highmem=off \ -accel hvf \ -cpu host \ -smp 4 \ -m 3000 \ -bios QEMU_EFI.fd \ -device virtio-gpu-pci \ -display default,show-cursor=on \ -device qemu-xhci \ -device usb-kbd \ -device usb-tablet \ -device intel-hda \ -device hda-duplex \ -drive file=ubuntu-latest.raw,format=raw,if=virtio,cache=writethrough
You will notice how the command is almost identical, the only difference is that we have removed the final line specifying the CD-ROM image to initially boot from.
Every time you want to start your Ubuntu server, you will have to run this command. Therefore, we recommend that you create either a script or an alias for it.
We prefer creating an alias, as it could be used from anywhere in your path. For instance, you could add the following alias to your bash profile or any other shell you currently use. We use zsh, therefore we’ll be adding this to our
alias ubuntu='qemu-system-aarch64 \ -monitor stdio \ -M virt,highmem=off \ -accel hvf \ -cpu host \ -smp 4 \ -m 3000 \ -bios QEMU_EFI.fd \ -device virtio-gpu-pci \ -display default,show-cursor=on \ -device qemu-xhci \ -device usb-kbd \ -device usb-tablet \ -device intel-hda \ -device hda-duplex \ -drive file=ubuntu-latest.raw,format=raw,if=virtio,cache=writethrough'
Once you open a new terminal (or reload your context using
"source ~/.zshrc"), you should be able to run the following:
$ ubuntu QEMU 7.2.0 monitor - type 'help' for more information
This will start QEMU using your new Ubuntu image. If everything goes well you should be seeing a new QEMU window showing something like this:
You will have to use the username and password that you defined during your installation and that’s it! You should be logged in and ready to use your new Linux terminal.
In this article we have learned how to start a Ubuntu server using QEMU in a completely free manner, not needing to pay for any of the existing virtualisation solutions that we’d have to pay for.
The new Apple Silicon processors makes this a bit more difficult, but using QEMU it’s quite simple, as you have seen previously. Support for M1and M2 processors will be increasing rapidly in the next few months anyways, so don’t worry too much about it!
That’s all from us today, we hope you’ve found this article useful and we’re hoping to see you back with us soon!
Thanks for reading us!