I totally believe that many of you have been there before. You buy a Raspberry 4, excited about all the bells and whistles, make an Arch 64 bit bootable SD card, boot it up… and then try to find your usb keyboard, microHDMI connector, switch screens and what not just to set up the WiFi to log in remotely. Well, fear not, this should help you to boot up and Arch Linux with WiFi configured right away.

I’ll just make it a little longer here and we’ll start from beginning.

Why do you need an aarch64 Arch linux?

You don’t. Now with this out of the way, we can continue.

Jokes aside, Arch is MY favorite distro and a choice I made for my desktop and servers as well.

  • It is a rolling release
  • It has a fairly robust and friendly package manager + AUR repositories
  • Is lightweight
  • Is CLI friendly
  • Is 64bit raspberry compatible
  • Is the one with a cool logo
  • It isn’t an out-of-the-box GUI distro
  • It is a little more advanced

What will we need?

We’ll need some things first – for a successful boot of a Raspi hanging on the WiFi.

  • Raspberry Pi4 (4GB RAM version preferred as of writing – 8G has issues with USB and network. Minor. They don’t work)
  • 4-32GB microSD card. I use 16GB – the smallest I could get with an A1 /A2 app class rating
  • Usb hub / adapter able to deliver 2A / 5V
  • USB-C cable
  • (Alternatively other means of powering, including 5V pin input, or 3.3V input. See https://www.raspberrypi.org/documentation/hardware/raspberrypi/power/README.md for more info)
  • Some luck and Linux knowledge. Windows not supported here

Setting up initial stuff and getting the image

Let’s set up a couple things here. First off, let’s get the image that we copy to the SD. This is big, so it takes time. Secondly, important!!!!, find out which of your devices is the SD card. /dev/sdb in my case. A 16GiB uSD == 14.9GB. Yeah, they lied to you…

# I usually do this under sudo -i and my working directory is /root as I am lazy
# Need to download the image
wget -q http://os.archlinuxarm.org/os/ArchLinuxARM-rpi-aarch64-latest.tar.gz &
[1] 13495

# specify the hostname for th new node
NODE_NAME=lxd-node4

# PLEASE use your own device name
# if in doubt, use 'lsblk' to find out:
# NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
# sda           8:0    0 111,8G  0 disk 
# └─sda1        8:1    0 111,8G  0 part /mnt/ssd2
# sdb           8:16   1  14,8G  0 disk <---------------- THIS IS MINE!!!
# └─sdb1        8:17   1  14,8G  0 part 
# sr0          11:0    1   3,1G  0 rom  
# nvme0n1     259:0    0 232,9G  0 disk 
# ├─nvme0n1p1 259:1    0   300M  0 part /boot/efi
# └─nvme0n1p2 259:2    0 232,6G  0 part /
# specify the device here
DEVICE=/dev/sdb

Destroy whatever is on the SD card

Allright, let’s bring it on. We first need to get rid of anything and everything that lieth on the SD card of choice:

# unmount and remove everything (destroys all the data on the card, mind you)
umount $DEVICE*
parted $DEVICE rm 2
parted $DEVICE rm 1

umount: /dev/sdb: not mounted.
Error: Partition doesn't exist.
Information: You may need to update /etc/fstab.

# make partitions (if you don't have parted on your linux distro, get it, it's cool)
# apt install parted # on ubuntu
# pacman -S parted   # on arch
parted -s $DEVICE 'mklabel msdos'
parted -s $DEVICE 'mkpart primary fat32 0% 200MiB'
parted -s $DEVICE 'mkpart primary ext2 200MiB 100%'

# Make filesystems and mount them
ls -ld root || mkdir root
ls -ld boot || mkdir boot
mkfs.vfat /dev/sdb1
mount /dev/sdb1 boot
mkfs.ext4 /dev/sdb2
mount /dev/sdb2 root

# Check
[temelin ~]# lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda           8:0    0 111,8G  0 disk 
└─sda1        8:1    0 111,8G  0 part /mnt/ssd2
sdb           8:16   1  14,8G  0 disk 
├─sdb1        8:17   1   199M  0 part /root/boot
└─sdb2        8:18   1  14,6G  0 part /root/root
sr0          11:0    1   3,1G  0 rom  
nvme0n1     259:0    0 232,9G  0 disk 
├─nvme0n1p1 259:1    0   300M  0 part /boot/efi
└─nvme0n1p2 259:2    0 232,6G  0 part /

# If the file is complete and the download is not running anymore
# ps -ef | grep wget
root       13495    9408  2 15:10 pts/5    00:00:00 wget -q http://os.archlinuxarm.org/os/ArchLinuxARM-rpi-aarch64-latest.tar.gz
# still running, give it some more time

# once complete
bsdtar -xpf ArchLinuxARM-rpi-aarch64-latest.tar.gz -C root
sync
mv root/boot/* boot
sync

Configure the image for use with Raspi4 and preconfigure the WIFI

Keep in mind you have to be extra careful with the special characters in your configs (i.e. escaping all special chars in your pass).

There is one more caveat to the wifi configuration here. The default network daemon (as of writing) is netctl. This can be changed in the future, so keep it in mind. Now, netctl works in such a way, that you need to enable it in the the netctl service in a “special” manner. You need to pass a profile name in the service link. Let’s inspect it:

/etc/systemd/system/multi-user.target.wants/netctl@wlan0\x2dSuperSSID.service -> /usr/lib/systemd/system/netctl@.service

the section netctl@wlan0\x2dSuperSSID.service actually specifies which profile should be loaded (the filename in /etc/netctl/wlan0-SuperSSID. The brutally escaped \0x2d is an ASCII literal character, meaning ‘-‘ or ‘Dash’. So the link name netctl@wlan0-SuperSSid.service says, that netctl should be called as service, with the profile name wlan0-SuperSSID. This “-” needs to be escaped as well. Or, alternatively you can of course NOT use these special characters.

# Need to adjust stuff for Raspi4 to boot correctly and the hostname
sed -i 's/mmcblk0/mmcblk1/g' root/etc/fstab
echo $NODE_NAME > root/etc/hostname

# just checking
cat root/etc/fstab | grep mmcblk1 && echo FSTAB OK
cat root/etc/hostname | grep $NODE_NAME && echo HOSTNAME OK

# Now for the Wifi
echo 'Description="Ventil did this"
Interface=wlan0
Connection=wireless
Security=wpa
ESSID=SuperSSID
IP=dhcp
Key=SUpersecret\ pass\!' > root/etc/netctl/wlan0-SuperSSID

# checking again
cat root/etc/netctl/wlan0-SuperSSID

# This actually enables the systemd service responsible for the WiFi config
ln -s /usr/lib/systemd/system/netctl@.service root/etc/systemd/system/multi-user.target.wants/netctl@wlan0\\x2dSuperSSID.service

umount boot root

# Boot it up!

As said, boot it up and look at your DHCP leases if it comes up. Oh, you need a DHCP enabled network. 🙂

Now that you have hopefully successfully booted up, you san simply get to your Raspi via ssh (as sshd is enabled by default on Arch) and do the initial config and update (Don’t do the update for a 8G, it breaks the OS – as of time of writing).

pacman-key --init
pacman-key --populate
pacman -Sy archlinux-keyring
pacman-key --refresh-keys

pacman -Syyu #breaks on 8G, works for 4G Pi4

Voila! You have your almost headless Raspi Server installation. Enjoy.