Recipe: Set up an Arch Linux ARM virtual workstation with UTM on Apple Silicon computers
/docs/other/developer-workstation/arch-aarch64/apple-silicon-utm/
Install UTM
- Download and install UTM if you have not done so already.
Obtain an Arch Linux ARM image
- Find the Arch Linux ARM image pre-built by UTM and select “Open in UTM”.
Run the Arch Linux ARM image as the virtual machine to create the development VM with
-
In UTM, add a virtual disk that becomes the development VM:
-
Select the downloaded “ArchLinux” virtual machine and open the settings (click on the three sliders icon all the way to the right in the toolbar). Adjust the following settings:
-
In the “Information” section:
- Change the name to something suitable, such as “ubosdev”.
-
In the “Drives” section of the sidebar, click “New…”:
-
Select “interface: VirtIO”
-
Enter a size suitable for your needs, such as 60 GB. This only means the disk may grow up to 60GB, not that it starts out that large.
-
Click “Create”. This will become the root disk of the Arch Linux ARM virtual workstation.
-
Click “Save”.
-
-
-
-
Now start the virtual machine by selecting it in the sidebar, and clicking the run icon (">"). Accept the defaults in the boot loader (or just wait) and wait until the boot sequence ends and the login prompt appears.
Install Arch on the empty disk and configure it
-
When the login prompt appears on the console, log in with “root” / “root”.
-
Update the bootstrap VM and install some packages we need:
# pacman -Sy # pacman -S archlinux-keyring archlinuxarm-keyring # pacman -Su # pacman -S btrfs-progs gptfdisk parted dosfstools arch-install-scripts vi
-
Zero out the first bytes on the disk for extra robustness:
# dd if=/dev/zero of=/dev/vdb bs=1M count=8 conv=notrunc
-
Clear the partition table:
# sgdisk --clear /dev/vdb
-
Create the partitions (UEFI, /boot and /) and change them to the right types.
# sgdisk --new=1::+1M /dev/vdb # sgdisk --new=2::+512M /dev/vdb # sgdisk --new=3:: /dev/vdb # sgdisk --typecode=1:EF02 /dev/vdb # sgdisk --typecode=2:EF00 /dev/vdb
-
Make sure changes are in effect:
# sync # partprobe /dev/vdb
-
Create filesystems for partitions other than the UEFI partition:
# mkfs.vfat /dev/vdb2 # mkfs.btrfs /dev/vdb3
-
Mount the partitions so we can install:
# mount /dev/vdb3 /mnt # mkdir /mnt/boot # mount /dev/vdb2 /mnt/boot
-
Perform the actual install:
# pacstrap /mnt base
-
Generate the right
fstab
:# genfstab -U -p /mnt >> /mnt/etc/fstab
-
Chroot into your future root disk and continue the installation:
# arch-chroot /mnt
-
Install more packages:
# pacman -Sy # pacman -S linux-aarch64 mkinitcpio amd-ucode sudo vim btrfs-progs spice-vdagent qemu-guest-agent \ gdm gnome-console gnome-control-center gnome-session gnome-settings-daemon \ gnome-shell gnome-keyring nautilus
If asked which alternatives to install, choose the defaults.
-
Check that the auto-generated content of
/etc/pacman.d/mirrorlist
makes sense. Edit accordingly. -
Create a ramdisk:
# mkinitcpio -p linux-aarch64
-
Configure the boot loader:
# bootctl --path /boot install
-
Install a locale:
# perl -pi -e 's!#en_US.UTF-8 UTF-8!en_US.UTF-8 UTF-8!' /etc/locale.gen # locale-gen
-
Set up networking:
# echo '[Match]' > /etc/systemd/network/wired.network # echo 'Name=en*' >> /etc/systemd/network/wired.network # echo '' >> /etc/systemd/network/wired.network # echo '[Network]' >> /etc/systemd/network/wired.network # echo 'DHCP=ipv4' >> /etc/systemd/network/wired.network # echo 'IPv4Forwarding=1' >> /etc/systemd/network/wired.network # echo 'IPv6Forwarding=1' >> /etc/systemd/network/wired.network # systemctl enable systemd-networkd systemd-resolved systemd-timesyncd
-
Create a user with the right permissions and no password:
# useradd -m ubosdev # chmod 755 ~ubosdev # passwd -d ubosdev # echo ubosdev ALL = NOPASSWD: ALL > /etc/sudoers.d/ubosdev # chmod 600 /etc/sudoers.d/ubosdev
-
No root password:
# passwd -d root
-
Exit from the
arch-chroot
shell with^D
.
-
-
Remainder of networking setup:
# rm /mnt/etc/resolv.conf # ln -s /run/systemd/resolve/stub-resolv.conf /mnt/etc/resolv.conf
-
Configure UEFI:
-
Loader configuration:
# echo timeout 4 > /mnt/boot/loader/loader.conf # echo default arch >> /mnt/boot/loader/loader.conf
-
Boot entry configuration:
# echo title Arch > /mnt/boot/loader/entries/arch.conf # echo linux /Image >> /mnt/boot/loader/entries/arch.conf # echo initrd /amd-ucode.img >> /mnt/boot/loader/entries/arch.conf # echo initrd /initramfs-linux.img >> /mnt/boot/loader/entries/arch.conf # echo options root=PARTUUID=$(lsblk -o PARTUUID /dev/vdb3 | tail -1 ) rootfstype=btrfs rw cgroup_disable=memory add_efi_memmap >> /mnt/boot/loader/entries/arch.conf
-
-
Power off the virtual machine:
# systemctl poweroff
Remaining configuration
-
Start the VM again and wait until the login prompt appears.
-
At the console, log in as
ubosdev
. There is no password. -
Fix the locale (command won’t run earlier)
% sudo localectl set-locale LANG=en_US.UTF-8
-
Enable Gnome:
% sudo systemctl enable gdm
-
Power off the virtual machine:
% sudo systemctl poweroff
Add virtual graphics for the VM
-
In UTM, select the VM, and in the popup, “Edit”.
-
Under “Devices”, click “New…” and “Display”.
-
Click “Save”.