Skip to content

Instantly share code, notes, and snippets.

@werdl
Created March 16, 2025 10:20
Show Gist options
  • Save werdl/fdd0fbb484cae8ca69b2923296d0b0cb to your computer and use it in GitHub Desktop.
Save werdl/fdd0fbb484cae8ca69b2923296d0b0cb to your computer and use it in GitHub Desktop.
Install Arch Linux ARM on Raspberry Pi 3

install arch linux on RPi 3

fdisk

  • plug in your SD card
  • replace sdX with the device name (find with lsblk)

fdisk /dev/sdX

  • o - clear out old partitions and create new MBR
  • p - none should be left
  • n, p, 1, ENTER, +500M - create a new primary boot parition, starting at the start of the disk with size 500MB/
  • t, c - set type to W95 FAT32
  • n, p, 2, ENTER x2 - create a new primary partition for data, taking up all remaining space
  • w - write to disk and exit

format

mkfs.vfat /dev/sdX1
mkfs.ext4 /dev/sdX2
mkdir boot root
mount /dev/sdX1 boot
mount /dev/sdX2 root

image

wget http://os.archlinuxarm.org/os/ArchLinuxARM-rpi-aarch64-latest.tar.gz
bsdtar -xpf ArchLinuxARM-rpi-aarch64-latest.tar.gz -C root
sync

mv root/boot/* boot
umount boot root
  • note that sync might take a while, this is normal

grab packages

  • plug your SD card into the RPi and boot
  • login as root (password root)

WiFi

  • if you have ethernet, skip this step
ip link set <interface> up
wpa_passphrase "SSID" "passphrase" | tee /etc/wpa_supplicant.conf
wpa_supplicant -B -i <interface> -c /etc/wpa_supplicant.conf
dhcpcd
  • replace internet with your interface name (find with ip link show)

init keyrings

pacman-key --init
pacman-key --populate archlinuxarm
  • pacman-key --init might take a while, again don't worry
  • later you might wish to disable checking:
# /etc/pacman.conf

[options]
SigLevel = Never

get package list

  • run pacman -Syu, but then type n when prompted for confirmation
  • take the list of packages, and substitue them into pkgs in packages.py. I have left mine in there, but these might differ for you depending on when you are using this guide
  • run the python file, it will download all the tarballs to your CWD

cache packages

  • move the tarballs to pacman's cached files, to trick it into thinking it downloaded the packages
mount /dev/sdX2 /mnt
mv ./*.pkg.tar.xz /mnt/var/cache/pacman/pkg/
umount /mnt

upgrade

  • run pacman -Syu on your RPi, and no download should be necessary
  • wait for this job to complete
  • you now have an up-to-date system

utilities

pacman -S sudo base-devel git
  • and then configure sudo by editing /etc/sudoers and following the instructions within

sway

  • I managed to get sway working with the following steps:
pacman -S sway qt5-wayland qt6-wayland foot netsurf
  • then by copying /etc/sway/config to ~/.config/sway/config and editing it:
~/.config/sway/config
  bindsym $mod+n exec netsurf
  • you can then run sway either from tty with sway or with a DM of your choice (I hear lightdm works well on RPis)
  • note that the default unprivileged user account is alarm, password alarm, you can either add that user to the sudo/wheel group or create a new one if you wish to use sudo
import os
import urllib.request
pkgs = '''acl-2.3.2-1 archlinux-keyring-20250123-1
archlinuxarm-keyring-20240419-1 argon2-20190702-6 attr-2.5.2-1
audit-4.0.3-1 base-3-2 bash-5.2.037-2 binutils-2.44-1 brotli-1.1.0-3
bzip2-1.0.8-6 ca-certificates-20240618-1
ca-certificates-mozilla-3.109-1 ca-certificates-utils-20240618-1
coreutils-9.6-4 cryptsetup-2.7.5-2 curl-8.12.1-1 dbus-1.16.2-1
dbus-broker-36-4 dbus-broker-units-36-4 dbus-units-36-4
device-mapper-2.03.31-1 dhcpcd-10.2.2-1 dialog-1:1.3_20250116-1
diffutils-3.11-2 dnssec-anchors-20190629-4 duktape-2.7.0-7
e2fsprogs-1.47.2-1 expat-2.7.0-1 file-5.46-3 filesystem-2024.11.21-1
findutils-4.10.0-2 firmware-raspberrypi-20240831-2 gawk-5.3.1-2
gcc-libs-14.2.1+r753+g1cd744a6828f-1 gdbm-1.24-2 gettext-0.24-1
glib2-2.84.0-1 glibc-2.41+r6+gcf88351b685d-1 gmp-6.3.0-2
gnulib-l10n-20241231-1 gnupg-2.4.7-1 gnutls-3.8.9-1 gpgme-1.24.2-1
grep-3.11-1 gzip-1.13-4 hwdata-0.393-1 iana-etc-20250213-1 icu-76.1-1
iproute2-6.13.0-1 iptables-1:1.8.10-2 iputils-20240905-1 iw-6.9-1
jansson-2.14-4 json-c-0.18-1 kbd-2.7.1-2 keyutils-1.6.3-3 kmod-34.1-1
krb5-1.21.3-1 ldns-1.8.4-1 leancrypto-1.2.0-2 less-1:668-1
libarchive-3.7.7-3 libassuan-3.0.0-1 libbpf-1.5.0-1 libcap-2.75-1
libcap-ng-0.8.5-3 libedit-20250104_3.1-1 libelf-0.192-4 libffi-3.4.7-1
libgcrypt-1.11.0-3 libgpg-error-1.51-1 libidn2-2.3.7-1 libksba-1.6.7-1
libldap-2.6.9-1 libmnl-1.0.5-2 libnetfilter_conntrack-1.0.9-2
libnfnetlink-1.0.2-2 libnftnl-1.2.8-1 libnghttp2-1.65.0-1
libnghttp3-1.8.0-1 libnl-3.11.0-1 libnsl-2.0.1-1 libp11-kit-0.25.5-1
libpcap-1.10.5-2 libpsl-0.21.5-2 libsasl-2.1.28-5 libseccomp-2.5.6-1
libsecret-0.21.6-1 libssh2-1.11.1-1 libsysprof-capture-47.2-3
libtasn1-4.20.0-1 libtirpc-1.3.6-1 libunistring-1.3-1 libusb-1.0.27-1
libverto-0.3.2-5 libxcrypt-4.4.38-1 libxml2-2.13.6-3
licenses-20240728-1 linux-aarch64-6.13.6-1 linux-api-headers-6.13-1
linux-firmware-20250311.b69d4b74-2
linux-firmware-whence-20250311.b69d4b74-2 lmdb-0.9.33-1 lz4-1:1.10.0-2
mkinitcpio-39.2-3 mkinitcpio-busybox-1.36.1-1 mpfr-4.2.1-6 nano-8.3-1
ncurses-6.5-3 net-tools-2.10-3 netctl-1.29-2 nettle-3.10.1-1
npth-1.8-1 openresolv-3.13.2-2 openssh-9.9p2-1 openssl-3.4.1-1
p11-kit-0.25.5-1 pacman-7.0.0.r6.gc685ae6-2 pam-1.7.0-2
pambase-20230918-2 pciutils-3.13.0-2 pcre2-10.45-1 pcsclite-2.3.1-1
pinentry-1.3.1-5 polkit-126-2 popt-1.19-2 procps-ng-4.0.5-2
psmisc-23.7-1 raspberrypi-bootloader-20250312-1 readline-8.2.013-1
sed-4.9-3 shadow-4.17.3-1 sqlite-3.49.1-1 systemd-257.4-1
systemd-libs-257.4-1 systemd-sysvcompat-257.4-1 tar-1.35-2
tpm2-tss-4.1.3-1 tzdata-2025a-1 uboot-raspberrypi-2025.01-1
util-linux-2.40.4-1 util-linux-libs-2.40.4-1 which-2.23-1
wireless-regdb-2025.02.20-1 wireless_tools-30.pre9-4
wpa_supplicant-2:2.11-3 xz-5.6.4-1 zlib-1:1.3.1-2 zstd-1.5.7-2'''
pkg_list = [a.replace('\n','') for a in pkgs.split(' ') if a!='']
repos = ["core", "extra", "community", "alarm"]
def download_package(pkg):
for repo in repos:
url = f"http://mirror.archlinuxarm.org/aarch64/{repo}/{pkg}-aarch64.pkg.tar.xz"
try:
print(f"Trying to download {pkg} from {repo}...")
urllib.request.urlretrieve(url, f"{pkg}-aarch64.pkg.tar.xz")
print(f"Successfully downloaded: {pkg} from {repo}")
return
except Exception as e:
print(f"Failed to download {pkg} from {repo}. Error: {e}")
continue
for repo in repos:
url = f"http://mirror.archlinuxarm.org/aarch64/{repo}/{pkg}-any.pkg.tar.xz"
try:
print(f"Trying to download {pkg} from {repo}...")
urllib.request.urlretrieve(url, f"{pkg}-aarch64.pkg.tar.xz")
print(f"Successfully downloaded: {pkg} from {repo}")
return
except Exception as e:
print(f"Failed to download {pkg} from {repo}. Error: {e}")
continue
print(f"Could not download {pkg} from any repository.")
for pkg in pkg_list:
download_package(pkg)
print("Download attempt complete.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment