Ubuntu on Mac - QEMU

Run Ubuntu on Mac using QEMU

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

The first step is to install QEMU, we are going to use Homebrew to install it on our machine. If you need help to install or use Homebrew, please read our article “How to Use Homebrew in Mac (OSX)”.

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.

Run Ubuntu On Mac Using QEMU » The Bored Dev

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)

In order to be able to install an operating system running on a virtual machine in QEMU, you will need an ISO image containing the OS.

If your system belongs to the ARM family, you can download the most recent Ubuntu version for ARM architectures here. Otherwise, for x86 families you can download it here.

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:

https://gist.github.com/theboreddev/5f79f86a0f163e4a1f9df919da5eea20#:~:text=QEMU_EFI%2Dcb438b9%2Dedk2%2Dstable202011%2Dwith%2Dextra%2Dresolutions.tar.gz

(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:

QEMU_EFI.fd                                                            
QEMU_VARS.fd

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:

Ubuntu on Mac - Install
Image Credit: Author

Select "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:

Ubuntu on Mac - Installation
Image Credit: Author

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 "Install complete!".

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 .zshrc file.

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:

Ubuntu on Mac - Terminal
Image Credit: Author

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.

Conclusion

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!