Advanced Programming in the UNIX Environment

CS631 - APUE - NetBSD/UTM Setup

This document will guide you through the setup of a NetBSD VM using UTM on an Apple M1 to perform all your course work on. Please follow these steps as shown; if you run into problems or have questions, please send them to the class mailing list.

If you prefer, you can also follow the video tutorial:

Installing your NetBSD VM

Creating a new UTM Image

First, install UTM from

Next, download the latest "-current" ISO for NetBSD/evbarm from and save it as ~/Desktop/NetBSD-9.99.97-evbarm-aarch64.iso.

Start UTM and select 'Create a New Virtual Machine':

Screenshot: UTM at first start

On the next screen, choose 'Virtualize', then 'Other' in the OS selection:

Screenshot: UTM new VM dialog  Screenshot: UTM OS selection dialog

On the next screen, select 'Boot ISO Image' and browse to the saved file ~/Desktop/NetBSD-9.99.97-evbarm-aarch64.iso and 'continue':

Screenshot: UTM Load ISO file

On the following screens, you can accept all the default values, although as far as disk space is concerned, 16 GB would be plenty.

Let's name the VM "apue".

Once the VM has been created, select the 'Settings' menu from the upper right "sliders" menu, then select 'Network' on the left and change the 'Network Mode' to "Bridged (Advanced)":

Screenshot: UTM VM
Menu  Screenshot: UTM Network Preferences

Installing NetBSD

Start the VM. You should see the 'Welcome to the NetBSD-9.99.97 Installation CD' screen, where you can hit return or wait for the timeout after which the system will boot into the NetBSD installer, where we'll follow a very basic NetBSD installation:

Screenshot: NetBSD
Welcome Screen  Screenshot: NetBSD
Installer 0

Select 'Installatation messages in English', then select 'Install NetBSD to hard disk'. Then:

Shall we continue? yes
Available disks: ld4
Guid Partition Table (GPT)
Use default partition sizes
Partition sizes are ok
Shall we continue? 'yes'
Select your distribution: 'Installation without X11'
Install from: 'CD-ROM / DVD /install image media'

NetBSD Installation Screenshot: Set Extraction

After extraction is complete, 'hit enter to continue', then set the root password. After this, you will be on the configuration screen show below:

NetBSD Installation Screenshot: Configuration

Here, we'll configure the network ('a' followed by return):

Available interfaces: 'vioifi0'
Network media type: <blank>
Perform autoconfiguration? yes

This should get you a DHCP lease and an overall network configuration that we wish to commit to the system:

Your host name: apue
Your DNS domain: <blank>
Are they ok? Yes
Do you want it installed in /etc? Yes

Back at the configure screen shown above, you can leave the option 'Fetch and unpack pkgsrc' disabled if you so choose -- we won't be using pkgsrc in this class, but if you're interested, installing it doesn't hurt.

Next, select:

'g: Enable sshd'
'h: Enable ntpd'
'i: Run ntpdate at boot'
'o: Add a user'

Note: it is required for this class to create and run your code as a non-root user, so this step is not optional. Choose your preferred username.

Add the user to 'wheel', so you can su(1).

Select a shell, e.g. /bin/sh and set a password.

NetBSD requires users to be in the 'wheel' group to run su(1), so only your newly created user should be able to do this.

This, together with the fact that the VM is intended for nothing of importance whatsoever may make it ok to not have any additional protections on the superuser account.

Select 'x: Finished configuring', then 'Hit enter to continue'.

Now you're back at the main install menu, where we can select 'x: Exit install System. This drops you into a shell, where we can power down the VM:

shutdown -p now

Once the VM has been shut down, you can close this window. Back in the main UTM screen, we now remove the ISO image from the virtual CD drive by selecting 'clear' from the drop-down menu labeled 'CD/DVD' at the bottom of the VM information.

Once done, you can now boot the newly installed NetBSD VM. You should first see the NetBSD bootloader, followed by the usual boot sequence:

Screenshot: NetBSD boot loader  Screenshot: NetBSD login screen

You can now log in and verify network connectivity, then power it down again:

NetBSD/evbarm (apue) (constty)

login: jschauma

NetBSD 9.99.97 (GENERIC) #0: Wed May 25 15:52:25 UTC 2022

Welcome to NetBSD!

apue$ ifconfig -a
vioif0: flags=0x8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	address: e2:47:b0:00:bd:cf
	status: active
	inet6 fe80::e047:b0ff:fe00:bdcf%vioif0/64 flags 0 scopeid 0x1
	inet broadcast flags 0
lo0: flags=0x8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 33624
	status: active
	inet6 ::1/128 flags 0x20
	inet6 fe80::1%lo0/64 flags 0 scopeid 0x2
	inet flags 0
apue$ su root -c "/sbin/shutdown -p now"

Note: it appears that as of 2022-06-03, UTM / QEMU does not correctly configure IPv6 networking: in bridged mode, if your local network supports IPv6, your VM will get an IPv6 address, but routing IPv6 traffic from the VM to the internet does not appear to work. In shared or emulated VLAN mode, the VM does not appear to get a DHCPv6 lease at all.

Using your VM

Starting headlessly

Unfortunately, UTM does not currently support fully headless operation. However, we don't want to have to open the app and click on things just to start our VM.

To avoid this, we can use qemu directly to start the VM. However, without UTM you cannot use bridged networking (easily). Using normal user networking works fine for the most part, but means ICMP won't work in your VM. If that doesn't bother you, then you can use e.g., this script to start your VM.

Minimize GUI Work with UTM

Alternatively, or if we need fully bridged networking, we can start the VM by using the convenient utm://start URL schema:

$ open utm://start?name=apue

This should open UTM and immediately start our VM. Neat!

But we still have the GUI in the foreground, even though we want to access our VM via ssh(1). There doesn't seem to be a good way around this right now, but until UTM supports full headless operation (or until you decide to ditch UTM and run QEMU directly), we can at least automate the minimization of those windows, too.

For that, open the Script Editor application, create a New Document, and enter the following:

tell application "System Events"
	tell process "UTM"
		set frontmost to true
		click menu item "Minimize" of menu "Window" of menu bar 1
		click menu item "Minimize" of menu "Window" of menu bar 1
	end tell
end tell

Save this script as as e.g., ~/bin/utm-minimize.scptand then give it a try: with UTM and our apue instance running:

$ osascript ~/bin/utm-minimize.scpt

You will need to grant Terminal 'Accessibility' privileges under 'System Preferences->Security & Privacy->Privacy->Accessibility'. Once that is done, we can then combine the open all with this application into a simple start-up script:

$ cat >~/bin/start-apue <<EOF
#! /bin/sh
open utm://start?name=apue
sleep 2
osascript ~/bin/utm-minimize.scpt >/dev/null >&1
$ chmod a+rx ~/bin/start-apue

When you run ~/bin/start-apue, that should now open UTM, start our VM, and then minimize the windows.

After you shut down the VM, the UTM application will still be running minimized, but we can likewise create a quick script to terminate our instance completely:

$ cat >~/bin/stop-apue <<"EOF"
#! /bin/sh
ssh apue "su root -c '/sbin/shutdown -p now'"
sleep 5
ps wwaux | awk '/UT[M].app/ { print $2 }' | xargs kill
$ chmod a+rx ~/bin/stop-apue

Set up your VM for this class

With the VM now ready for use, you can next follow the steps to set up everything for use in this class. That will include configuration of SSH, configuring your development environment, and fetching all source code and code examples.

These steps are more or less the same for use of UTM and VirtualBox, and you can find them in this document.

[Course Website]