Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ __pycache__/

# Acceptance test harness artifacts
test-runs/**

# Agent harness artifacts
.superlite/
73 changes: 73 additions & 0 deletions bin/omarchy-iso-boot-aarch64
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/bin/bash
#
# Boot an aarch64 Omarchy ISO in QEMU under UEFI.
#
# The x86_64 counterpart is bin/omarchy-iso-boot, which hardcodes
# qemu-system-x86_64 and OVMF. This is the ARM equivalent, kept separate until
# plans/aarch64-support.md item 9 folds both into one arch-aware script.
#
# Firmware: Arch Linux ARM does not package edk2-armvirt, so AAVMF is staged
# from Debian's architecture-independent qemu-efi-aarch64 package into
# ~/.local/share/aavmf. See docs/alarm-iso.md.
#
# No KVM here: on Snapdragon X the Gunyah hypervisor owns EL2 and Linux runs at
# EL1, so this is TCG emulation and boots slowly even on an ARM host.
#
# Usage: omarchy-iso-boot-aarch64 [release/omarchy.iso] [--serial] [--memory MB]

set -euo pipefail

FW_DIR="${OMARCHY_AAVMF_DIR:-$HOME/.local/share/aavmf}"
CODE="$FW_DIR/AAVMF_CODE.no-secboot.fd"
VARS_TEMPLATE="$FW_DIR/AAVMF_VARS.fd"
VARS="/tmp/omarchy-aavmf-vars.fd"

ROOT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
ISO=""
MEMORY=4096
SERIAL=false

while (($#)); do
case "$1" in
--serial) SERIAL=true ;;
--memory) MEMORY="$2"; shift ;;
-*) echo "Unknown option: $1" >&2; exit 1 ;;
*) ISO="$1" ;;
esac
shift
done

[[ -n $ISO ]] || ISO=$(\ls -t "$ROOT"/release/*.iso 2>/dev/null | head -n1 || true)
[[ -n $ISO && -f $ISO ]] || { echo "No ISO found; pass one explicitly." >&2; exit 1; }

command -v qemu-system-aarch64 >/dev/null ||
{ echo "qemu-system-aarch64 not installed: sudo pacman -S qemu-system-aarch64 qemu-ui-gtk" >&2; exit 1; }
[[ -f $CODE ]] ||
{ echo "UEFI firmware missing at $CODE" >&2; exit 1; }

# The vars store is written to, so never hand QEMU the pristine template.
cp -f "$VARS_TEMPLATE" "$VARS"

args=(
-machine virt
-cpu max
-m "$MEMORY"
-smp 4
-drive "if=pflash,format=raw,unit=0,file=$CODE,readonly=on"
-drive "if=pflash,format=raw,unit=1,file=$VARS"
# The ISO is a hybrid image with its own GPT, so it is attached as a plain
# disk rather than a CD -- which is also how the USB stick presents it.
-drive "if=none,id=iso,format=raw,readonly=on,file=$ISO"
-device virtio-blk-pci,drive=iso,bootindex=0
-device virtio-rng-pci
)

if $SERIAL; then
# Headless: GRUB and the kernel both talk to the virt machine's PL011.
args+=(-nographic)
else
args+=(-device virtio-gpu-pci -display gtk -serial mon:stdio)
fi

echo "Booting ${ISO##*/} (TCG, no KVM — expect this to be slow)"
exec qemu-system-aarch64 "${args[@]}"
40 changes: 37 additions & 3 deletions bin/omarchy-iso-make
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@ LOCAL_OMARCHY_PATH=""
LOCAL_PKGS_PATH=""
while [[ $# -gt 0 ]]; do
case $1 in
--arch)
OMARCHY_ARCH="${2:-}"
case $OMARCHY_ARCH in
x86_64 | aarch64) ;;
*)
echo "Error: --arch must be x86_64 or aarch64" >&2
exit 1
;;
esac
shift 2
;;
--no-cache)
NO_CACHE=1
shift
Expand Down Expand Up @@ -57,7 +68,7 @@ while [[ $# -gt 0 ]]; do
;;
*)
echo "Unknown option: $1"
echo "Usage: $0 [--no-cache] [--keep-pkg-cache] [--no-boot-offer] [--debug] [--edge] [--dev|--rc] [--local-source <omarchy-checkout> <pkgs-checkout>]"
echo "Usage: $0 [--arch x86_64|aarch64] [--no-cache] [--keep-pkg-cache] [--no-boot-offer] [--debug] [--edge] [--dev|--rc] [--local-source <omarchy-checkout> <pkgs-checkout>]"
exit 1
;;
esac
Expand Down Expand Up @@ -119,12 +130,33 @@ mkdir -p "$BUILD_RELEASE_PATH"

OMARCHY_ISO_REF="${OMARCHY_ISO_REF:-quattro}"
OMARCHY_MIRROR="${OMARCHY_MIRROR:-stable}"
OMARCHY_ARCH="${OMARCHY_ARCH:-x86_64}"

# Vanilla Arch is x86_64-only, so aarch64 builds run against Arch Linux ARM.
# Building aarch64 on an x86_64 host works through binfmt/QEMU but is slow;
# a native arm64 host is much faster.
case $OMARCHY_ARCH in
aarch64)
BUILD_IMAGE="menci/archlinuxarm:base-devel"
BUILD_PLATFORM="linux/arm64"
;;
*)
BUILD_IMAGE="archlinux/archlinux:latest"
BUILD_PLATFORM="linux/amd64"
;;
esac

DOCKER_ARGS=(
--rm
--privileged
--platform "$BUILD_PLATFORM"
-e "OMARCHY_ISO_REF=$OMARCHY_ISO_REF"
-e "OMARCHY_MIRROR=$OMARCHY_MIRROR"
-e "OMARCHY_ARCH=$OMARCHY_ARCH"
-e "OMARCHY_PKGS_MIRROR=${OMARCHY_PKGS_MIRROR:-}"
-e "OMARCHY_TARGET_PKGS_MIRROR=${OMARCHY_TARGET_PKGS_MIRROR:-}"
-e "OMARCHY_BASE_MIRROR=${OMARCHY_BASE_MIRROR:-}"
-e "OMARCHY_EXTRA_PKGBUILDS=${OMARCHY_EXTRA_PKGBUILDS:-}"
-e "OMARCHY_INSTALL_DEBUG=${OMARCHY_INSTALL_DEBUG:-}"
-e "HOST_UID=$(id -u)"
-e "HOST_GID=$(id -g)"
Expand All @@ -148,8 +180,10 @@ fi

# Mount the build cache directory where packages are downloaded. Channels use
# different package snapshots and must never share an offline mirror cache.
# Architectures must not share one either: the cached packages are arch-specific,
# so a shared key would let an aarch64 build consume x86_64 packages and vice versa.
if [[ -z "$NO_CACHE" ]]; then
OFFLINE_REPO_BUILD_CACHE_DIR="$HOME/.cache/omarchy/iso_${OMARCHY_MIRROR}/airootfs/var/cache/omarchy"
OFFLINE_REPO_BUILD_CACHE_DIR="$HOME/.cache/omarchy/iso_${OMARCHY_MIRROR}_${OMARCHY_ARCH}/airootfs/var/cache/omarchy"
mkdir -p "$OFFLINE_REPO_BUILD_CACHE_DIR"
DOCKER_ARGS+=(-v "$OFFLINE_REPO_BUILD_CACHE_DIR:/var/cache/airootfs/var/cache/omarchy")
else
Expand All @@ -166,7 +200,7 @@ if ! docker version &>/dev/null; then
DOCKER=(sudo docker)
fi

"${DOCKER[@]}" run "${DOCKER_ARGS[@]}" archlinux/archlinux:latest /$BUILD_SCRIPT
"${DOCKER[@]}" run "${DOCKER_ARGS[@]}" "$BUILD_IMAGE" /$BUILD_SCRIPT

latest_iso=$(\ls -t "$BUILD_RELEASE_PATH"/*.iso | head -n1)
iso_ref="${latest_iso%.*}-$OMARCHY_ISO_REF.iso"
Expand Down
83 changes: 83 additions & 0 deletions builder/aarch64-excludes.packages
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Packages excluded from aarch64 builds.
#
# Omarchy's package lists are written for x86_64. Most entries here are hardware
# or platform support that cannot exist on ARM; a smaller group is software Arch
# Linux ARM simply does not carry. Anything listed is dropped before the offline
# mirror is populated, because pacman aborts the whole transaction on the first
# unresolvable target.
#
# NOT excluded, and must be built for aarch64 and published to the package repo:
# tzupdate (also needed by the live ISO itself)
# tensaku
# hyprland-preview-share-picker

# --- CPU microcode (x86-only concept) ---
#
# archinstall.packages deliberately lists both so the mirror contains whichever
# the target CPU needs. Neither exists for ARM.
amd-ucode
intel-ucode

# --- Apple T2 / Intel Macs (x86-only by definition) ---
apple-bcm-firmware
apple-t2-audio-config
asdcontrol
linux-t2
linux-t2-headers
macbook12-spi-driver-dkms
t2fanrd

# --- Intel-specific ---
intel-ipu7-camera
intel-lpmd
intel-media-driver
libva-intel-driver
linux-ptl
linux-ptl-headers
thermald
vpl-gpu-rt

# --- NVIDIA and 32-bit x86 ---
lib32-nvidia-580xx-utils
lib32-nvidia-utils
nvidia-580xx-dkms
nvidia-580xx-utils

# --- x86 laptop/vendor hardware ---
asusctl
dell-xps-touchpad-haptics
dell-xps13-sidecar-amps
qmk-hid
tuxedo-drivers-nocompatcheck-dkms
yt6801-dkms

# --- x86 firmware, boot, and VM guest tooling ---
broadcom-wl
hyperv
memtest86+-efi
open-vm-tools
qemu-user-static-binfmt
refind
virtualbox-guest-utils-nox

# --- Arch releng live-ISO entries with no ARM equivalent ---
#
# The live ISO package list is derived from releng's packages.x86_64, which
# carries x86 rescue and firmware tooling.
b43-fwcutter
edk2-shell
linux-firmware-marvell
memtest86+
syslinux

# --- Not packaged for Arch Linux ARM ---
#
# These are a genuine reduction in what the installed system offers, not an
# architecture impossibility. Build them for aarch64 and remove them here if any
# turn out to matter.
dotnet-runtime
obs-studio
obsidian
pinta
reflector
yay-debug
Loading