Running Arch Linux ARM (ALARM) on Hetzner Cloud nodes powered by Ampere® Altra® CPUs is actually quite straight-forward.

When creating a new instance the distro in the image doesn't matter as it will be replaced anyway. It can then be booted into Rescue Mode from where the the procedure follows a Generic AArch64 Installation.

The rootfs needs to be wiped while the EFI partition may be re-used depending on its current contents:

root@rescue ~ $ mkfs.ext4 -L root /dev/sda1
root@rescue ~ $ mount -o noatime /dev/sda1 /mnt
root@rescue ~ $ mkdir /mnt/boot
root@rescue ~ $ mount /dev/sda15 /mnt/boot

After preparing the mount points the bootstrapping tarball can be extracted

root@rescue ~ $ wget "http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz"
root@rescue ~ $ bsdtar -xpf ArchLinuxARM-aarch64-latest.tar.gz -C /mnt

followed by a chroot into ALARM:

root@rescue ~ $ mount --bind /dev /mnt/dev
root@rescue ~ $ mount -t proc proc /mnt/proc
root@rescue ~ $ mount -t sysfs sys /mnt/sys
root@rescue ~ $ chroot /mnt

Using systemd-boot as EFI loader works just fine

[root@rescue /]$ bootctl install

with a simple loader entry as /boot/loader/entries/arch.conf:

title    Arch Linux ARM
linux    /Image
initrd   /initramfs-linux.img
options  root=UUID=2d168f48-9b84-418a-86f4-8f0986953899 rw

(don't forget to replace the UUID!)

For networking (without cloud-init) one can use DHCP for IPv4 but IPv6 addresses need to be set statically according to the Cloud config:

[root@rescue /]$ rm /etc/systemd/network/*
[root@rescue /]$ cat <<EOF > /etc/systemd/network/eth.network
[Match]
Name=enp*

[Network]
DHCP=ipv4
Address=2a01:XXXX:YYYY:ZZZZ::1/64
Gateway=fe80::1
IPv6AcceptRA=no
EOF

After that the system should be set up for first boot but it may be desirable to add a couple of polishing steps:

  • set a proper root password (or better add SSH keys and disable password auth)
  • initialize Pacman (pacman-key --init and pacman-key --populate archlinuxarm)
  • set a hostname and time zone

When leaving the chroot there may be a gpg-agent that needs to be killed before the rootfs can be unmounted:

root@rescue ~ $ killall gpg-agent
root@rescue ~ $ umount -R /mnt
root@rescue ~ $ systemctl reboot