Running QEMu based VM’s on OSX M1

Saurabh Sharma

A popular choice in the OSS QEMu is an open source machine emulator (system emulation/usermode emulation) and virtualizer. Since I recently moved to Apple M1 silicone, I had not option of sticking to VirtualBox and was forced to relook at my options.

The most recent version being 7.1.0-rc3 at the time of writing this blog.

qemu.org

In this blog let’s try and look at some of the commands I used to build an RockyLinux machine on a MacPro M1.

Samarthya

Look at the official man page here.

Samarthya

Another helpful link that I used

Define the disk image

> qemu-img create -f qcow2 centos4.brokers.test 15G
Formatting 'centos4.brokers.test', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=16106127360 lazy_refcounts=off refcount_bits=16

You can look at the detailed help via

> qemu-img --help
qemu-img version 7.0.0
Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers
usage: qemu-img [standard options] command [command options]
QEMU disk image utility

    '-h', '--help'       display this help and exit
    '-V', '--version'    output version information and exit
    '-T', '--trace'      [[enable=]<pattern>][,events=<file>][,file=<file>]
                         specify tracing options

The option we are interested in were

create [--object objectdef] [-q] [-f fmt] [-b backing_file [-F backing_fmt]] [-u] [-o options] filename [size]
OptionDescription
-fDefines the format. In our example qcow2
centos2.brokers.test.qcow2File name on the disk
15GSize of the disk in bytes. Optional suffixes 
“k” or “K” (kilobyte, 1024) 
“M” (megabyte, 1024k) and 
“G” (gigabyte, 1024M) and
“T” (terabyte, 1024G) are supported. 
https://linux.die.net/man/1/qemu-img
> qemu-img check -f qcow2 centos4.brokers.test
No errors were found on the image.
Image end offset: 262144
A helpful link too

Moving on; Once the disk has been defined let’s try and deploy the OS.

> qemu-system-aarch64 --version
QEMU emulator version 7.0.0
Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers

Let me explain few arguments before I dive deeper into it.

-machine
> qemu-system-aarch64 -machine help

You can look at the options you can supply by issuing the command above.

Supported machines are:
virt                 QEMU 7.0 ARM Virtual Machine (alias of virt-7.0)
virt-7.0             QEMU 7.0 ARM Virtual Machine

Sub-option

accel= selects accelerator supported accelerators are kvm, xen, hax, hvf, nvmm, whpx or tcg (default: tcg)

-accel [accel=]accelerator[,prop[=value][,...]]
                select accelerator (kvm, xen, hax, hvf, nvmm, whpx or tcg; use 'help' for a list)
                igd-passthru=on|off (enable Xen integrated Intel graphics passthrough, default=off)
                kernel-irqchip=on|off|split controls accelerated irqchip support (default=on)
                kvm-shadow-mem=size of KVM shadow MMU in bytes
                split-wx=on|off (enable TCG split w^x mapping)
                tb-size=n (TCG translation block cache size)
                dirty-ring-size=n (KVM dirty ring GFN count, default 0)
                thread=single|multi (enable multi-threaded TCG)

The other options are as under

-machine [type=]name[,prop[=value][,...]]
                selects emulated machine ('-machine help' for list)
                property accel=accel1[:accel2[:...]] selects accelerator
                supported accelerators are kvm, xen, hax, hvf, nvmm, whpx or tcg (default: tcg)
                vmport=on|off|auto controls emulation of vmport (default: auto)
                dump-guest-core=on|off include guest memory in a core dump (default=on)
                mem-merge=on|off controls memory merge support (default: on)
                aes-key-wrap=on|off controls support for AES key wrapping (default=on)
                dea-key-wrap=on|off controls support for DEA key wrapping (default=on)
                suppress-vmdesc=on|off disables self-describing migration (default=off)
                nvdimm=on|off controls NVDIMM support (default=off)
                memory-encryption=@var{} memory encryption object to use (default=none)
                hmat=on|off controls ACPI HMAT support (default=off)
                memory-backend='backend-id' specifies explicitly provided backend for main RAM (default=none)
                sgx-epc.0.memdev=memid,sgx-epc.0.node=numaid
-smp
> qemu-system-aarch64 -smp help

Allows you to specify specific cores and cpu values

smp-opts options:
clusters=<num>
cores=<num>
cpus=<num>
dies=<num>
maxcpus=<num>
sockets=<num>
threads=<num>
-smp [[cpus=]n][,maxcpus=maxcpus][,sockets=sockets][,dies=dies][,clusters=clusters][,cores=cores][,threads=threads]
                set the number of initial CPUs to 'n' [default=1]
                maxcpus= maximum number of total CPUs, including
                offline CPUs for hotplug, etc
                sockets= number of sockets on the machine board
                dies= number of dies in one socket
                clusters= number of clusters in one die
                cores= number of cores in one cluster
                threads= number of threads in one core
-drive
> qemu-system-aarch64 -drive help
qemu-system-x86_64: -drive help: Must specify either driver or file

Look at the detailed options as below

-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]
       [,cache=writethrough|writeback|none|directsync|unsafe][,format=f]
       [,snapshot=on|off][,rerror=ignore|stop|report]
       [,werror=ignore|stop|report|enospc][,id=name]
       [,aio=threads|native|io_uring]
       [,readonly=on|off][,copy-on-read=on|off]
       [,discard=ignore|unmap][,detect-zeroes=on|off|unmap]
       [[,bps=b]|[[,bps_rd=r][,bps_wr=w]]]
       [[,iops=i]|[[,iops_rd=r][,iops_wr=w]]]
       [[,bps_max=bm]|[[,bps_rd_max=rm][,bps_wr_max=wm]]]
       [[,iops_max=im]|[[,iops_rd_max=irm][,iops_wr_max=iwm]]]
       [[,iops_size=is]]
       [[,group=g]]
                use 'file' as a drive image
-boot

The sequence of boot. You can choose value based on CD-ROM “d” or hard-disk “c“.

-boot [order=drives][,once=drives][,menu=on|off]
      [,splash=sp_name][,splash-time=sp_time][,reboot-timeout=rb_time][,strict=on|off]
                'drives': floppy (a), hard disk (c), CD-ROM (d), network (n)
                'sp_name': the file's name that would be passed to bios as logo picture, if menu=on
                'sp_time': the period that splash picture last if menu=on, unit is ms
                'rb_timeout': the timeout before guest reboot when boot failed, unit is ms
-m

Memory requirements for the guest system. My system has 32G so I can spare some for good quality VM’s (2048).

-m [size=]megs[,slots=n,maxmem=size]
                configure guest RAM
                size: initial amount of guest memory
                slots: number of hotplug slots (default: none)
                maxmem: maximum amount of guest memory (default: none)
NOTE: Some architectures might enforce a specific granularity
-name
-name string1[,process=string2][,debug-threads=on|off]
                set the name of the guest
                string1 sets the window title and string2 the process name.
-nographic

(Optional) disable graphical output and redirect serial I/Os to console

-vga

Display settings

[std|cirrus|vmware|qxl|xenfb|tcx|cg3|virtio|none]
select video card type

Time to deploy the VM using the CDROM and boot preference for the ISO.

> qemu-system-aarch64 -boot d -machine virt,highmem=off -accel hvf -bios QEMU_EFI.fd -cdrom ./Rocky-9.0-aarch64-dvd.iso -m 2G -hda centos4.brokers.test -cpu host -device virtio-gpu-pci -name centos4.brokers.test -display cocoa,show-cursor=on,full-grab=on -device qemu-xhci -device usb-tablet -device intel-hda -device usb-kbd   

It should pop a window for you to follow the steps to install linux. Some of the reference images are attached below.

Once installation is completed you will be prompted to reboot.

Final steps

Once you are done you can shut down the VM and change the option -boot to c from d and now it will boot from disk

> qemu-system-aarch64 -boot c -machine virt,highmem=off -accel hvf -bios QEMU_EFI.fd -cdrom ./Rocky-9.0-aarch64-dvd.iso -m 2G -hda centos4.brokers.test -cpu host -device virtio-gpu-pci -name centos4.brokers.test -display cocoa,show-cursor=on,full-grab=on -device qemu-xhci -device usb-tablet -device intel-hda -device usb-kbd 
All done and machine is accessible

Help