Skip to content

Add generic Snapdragon X support on aarch64 - #8672

Merged
birkskyum merged 17 commits into
omacom:dragonfrom
birkskyum:upstream/snapdragon
Sep 13, 2026
Merged

birkskyum merged 17 commits into
omacom:dragonfrom
birkskyum:upstream/snapdragon

Conversation

@birkskyum

@birkskyum birkskyum commented Aug 27, 2026 •

Copy link
Copy Markdown

Summary

  • Adds Qualcomm detection, Windows-on-ARM device trees in UKIs, Snapdragon kernel parameters and Freedreno Vulkan support.
  • Uses available Linux firmware first and attempts to fill missing model-matched firmware from a staged or readable Windows driver store. Missing ADSP firmware or a failed inspection leaves DSP startup disabled without aborting setup.
  • Keeps DSPs stopped when the root filesystem is on USB.
  • Restores Arch Linux ARM repositories and key trust during offline-install finalization.
  • Preserves ARM repository order, signature settings and mirror files during pacman refresh. Only a recognized Omarchy server's channel is rewritten. Private, missing or ambiguous Omarchy repository configurations are refused without writes or upgrades. Unpublished stable/RC refreshes remain blocked and do not silently select edge.
  • Preserves existing UKI settings when setup runs again.

Dependencies and provenance

Carries Sean's ARM runtime prerequisites from #8039 and Jimmy Van Veen's generic Snapdragon work from JimmayVV/omarchy@snapdragon, with original authorship preserved. The #8039 code is already in this branch; if that PR lands first, rebase this branch to leave only the Snapdragon changes.

Jim Martin's repository-preserving ARM refresh is included with his authorship preserved. The stable/RC safeguard remains while those ARM repositories are unpublished and #8781's rollback is unmerged. That rollback is not required for this guarded refresh change, and it is not included here.

The systemd shutdown fix and camera stack described below are separate follow-ups, not merge prerequisites.

Validation

  • Bash 5 regression tests pass for missing firmware, failed inspection, repeated UKI setup and ARM/x86 repository handling. Refresh tests cover repository priority, signature policies, mirror preservation, private/ambiguous configuration refusal, repeated refreshes, backups, install-finalization compatibility, unchanged x86 channels, unsupported ARM channels and read/copy/hook failures. Upgrade calls are stubbed, including verification that pacman failures propagate.
  • ShellCheck and whitespace checks pass.
  • The September 9 repository-preserving refresh passes its focused tests in an isolated ARM64 container and the full CLI suite in a separate ARM64 test container. The new preservation regression fails against the previous template-based refresh. The full shell suite was not rerun for this revision.
  • Yoga Slim 7x, HP EliteBook Ultra G1q and ASUS Vivobook S15 hardware reports are recorded here and in Boot and install Omarchy on Snapdragon X ARM64 systems omarchy-iso#129. The initial ASUS report used the August 28 ISO at 5c3bce42d65b4443e619568dadd7a0b263107d8d. A September 7 ASUS follow-up reached the installer welcome screen and connected to Wi-Fi using the pinned September 6 integration image. That is live-session validation, not a fresh installation or confirmation of every current PR change. Board-specific display and audio coverage differs.

The installed Yoga hardware report confirms Limine without the hash warning, graphical disk unlock, polished shutdown/reboot, Wi-Fi, Bluetooth, speakers and microphone. The shutdown result used a separate systemd v261.2 backport of systemd/systemd#43671, not a change included in this PR. The hardware report also covers the fast, denoised camera preview and subsequent Chromium live-video test on an experimental setup. Camera enablement remains separate from this PR.

Before the September 9 refresh revision, repository regression tests also passed on the physical Yoga using temporary files and stubbed upgrades. Enabling only the ARM edge repository on the installed Yoga made ChatGPT and VS Code discoverable through pacman, with no package upgrade or ALARM database/mirror change. The repository-preserving revision has only been tested in isolated containers so far. Neither result is a fresh-install or full-upgrade validation. The separate speaker-reset kernel fix, archlinuxarm/PKGBUILDs#2217, has merged.

@birkskyum

Copy link
Copy Markdown
Author

@JimmayVV — thank you for the Snapdragon work. Your three snapdragon branches are what made the Yoga Slim 7x installation possible. I have opened the generic work for upstream review with your original commit authorship preserved: this PR, omacom/omarchy-iso#129, and omacom/omarchy-pkgs#221. The drafts are intentionally still gated on a fresh encrypted-install test. Please review or correct the split; I am happy to restructure it around how you want the work presented.

@JimmayVV

JimmayVV commented Aug 27, 2026 •

Copy link
Copy Markdown

@birkskyum, thank you. This is what I was hoping would happen. I only did this to get the ball moving, and seeing it boot a second machine with audio working is more than I managed on my own. I'm happy for these PRs to be the upstream path with you driving. I'll review, test on the G1q, and otherwise stay out of the way.

The split looks right to me, and the provenance is accurate on all five PRs. One thing I think needs a look, which I've left on omacom/omarchy-pkgs#222 since it lives there. The pkgbase shim also wrote usr/lib/modules/<ver>/vmlinuz, and I think mkinitcpio still needs that file on Arch Linux ARM even after Zesko !64.

Testing on an HP EliteBook Ultra G1q with the X1E-78-100 and linux-aarch64 7.2-2, from these same commits. It installs and boots via Limine. Display at native resolution with GPU acceleration, Wi-Fi, Bluetooth, keyboard, touchpad and touchscreen all work. Audio doesn't yet. The card needs a topology and UCM name that upstream hasn't given the G1q, and I have a small follow-up for that. The encrypted path is also open. On the G1q the LUKS prompt comes up with the panel dark and no keyboard driver in the initramfs, so it looks hung. That's JimmayVV/omarchy-iso#25, and it may be useful for your encrypted-install gate.

Anything new from me, audio, USB-C root disks, encrypted installs, will be small follow-ups after these land rather than additions to this stack.

@birkskyum

Copy link
Copy Markdown
Author

Correction to the Yoga validation above: microphone input works, but the internal speakers currently produce no sound during playback. I have corrected the PR descriptions; Yoga audio output remains an open hardware item.

@birkskyum
birkskyum marked this pull request as ready for review August 28, 2026 00:18
Copilot AI balanced review requested due to automatic review settings August 28, 2026 00:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds aarch64 and Qualcomm Snapdragon X installation support, including boot configuration, firmware, graphics, and Arch Linux ARM package sources.

Changes:

  • Adds ARM-safe Node, mkinitcpio, and pacman handling.
  • Configures Qualcomm DTBs, firmware, kernel parameters, and Freedreno.
  • Integrates Qualcomm detection and hardware setup.

Tip

If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
install/user/mise-work.sh Selects architecture-specific Node bundles.
install/post-install/pacman.sh Restores ARM repositories and key trust.
install/omarchy-other.packages Stages the Qualcomm extractor package.
install/hardware/vulkan.sh Installs Freedreno on Qualcomm systems.
install/hardware/qualcomm/kernel-params.sh Adds Snapdragon boot parameters.
install/hardware/qualcomm/firmware.sh Installs firmware and DSP safeguards.
install/hardware/qualcomm/dtb-uki.sh Embeds Qualcomm DTBs in UKIs.
install/hardware/all.sh Runs Qualcomm setup leaves.
etc/mkinitcpio.conf.d/thunderbolt_module.conf Restricts Thunderbolt to x86_64.
default/pacman/pacman-aarch64.conf Defines Arch Linux ARM repositories.
default/pacman/mirrorlist-aarch64 Adds the ARM package mirror.
bin/omarchy-hw-qualcomm-soc Detects Qualcomm device-tree systems.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread install/hardware/qualcomm/firmware.sh Outdated
Comment thread install/hardware/qualcomm/dtb-uki.sh Outdated
Comment thread default/pacman/mirrorlist-aarch64 Outdated
@JimmayVV

Copy link
Copy Markdown

I think I found why the speakers are silent on both machines. Arch Linux ARM's linux-aarch64 config leaves CONFIG_RESET_GPIO off. Since 6.9 the wsa884x driver releases the amps' shared reset-gpios line through the reset framework, and without that option the reset core silently reports no reset, so the board's output-low pin default keeps the WSA8845 amps in shutdown and they never attach on SoundWire. Mainline's arm64 defconfig, Fedora, Ubuntu and Debian all build it as a module. On the G1q the two amps show UNATTACHED with SWR CMD errors on their controller; the Yoga wires its four amps the same way, which fits mic input working while playback is silent. Nothing in Omarchy can supply it, so I plan to send a one-line config PR to ALARM once I've confirmed it with a rebuilt kernel. No change needed to these PRs. Details: JimmayVV/omarchy-iso#26 (comment)

@birkskyum

Copy link
Copy Markdown
Author

Thanks, Jimmy. I independently checked the current official ALARM config and upstream Yoga DTS. ALARM has CONFIG_SND_SOC_WSA884X=m and # CONFIG_RESET_GPIO is not set; the Yoga defines four WSA8845 devices on two shared reset-gpios lines whose pinctrl defaults are output-low. That fully fits the physical result here: microphone capture works, PipeWire exposes the speaker path, but internal playback is silent. I have documented this as an external ALARM kernel dependency on #8672 and #8673. No GPIO forcing or Omarchy workaround will be attempted.

@birkskyum

Copy link
Copy Markdown
Author

The speaker fix is now physically validated on the Yoga and submitted upstream as archlinuxarm/PKGBUILDs#2217. With CONFIG_RESET_GPIO=m, all four WSA8845 devices changed from UNATTACHED to Attached, and the internal speakers produced audible output under speaker-test. I updated this PR and #8673 so they no longer list speaker playback as unresolved.

oceanapplications and others added 9 commits September 6, 2026 00:48
Each of these is an unconditional assumption that only holds on x86_64. None
is x86-specific in spirit, and each one blocks or breaks an ARM64 install.

1. etc/mkinitcpio.conf.d/thunderbolt_module.conf

   MODULES+=(thunderbolt) is unconditional, but Thunderbolt is x86-oriented
   hardware and the module is not built for every architecture -- Arch Linux
   ARM's aarch64 kernel has no `thunderbolt`. mkinitcpio treats an unresolvable
   MODULES entry as a hard error, so *every* initramfs build fails:

     ==> ERROR: module not found: `thunderbolt'

   That means no UKI, no boot entry, and an install that completes and then
   cannot boot.

2. install/post-install/pacman.sh

   This overwrites /etc/pacman.conf unconditionally. That config points
   [core]/[extra]/[multilib] at Omarchy's mirror of Arch, which is x86_64-only,
   and [omarchy] at pkgs.omarchy.org/stable/$arch, which 404s for aarch64.
   ([multilib] is 32-bit x86 libraries and exists on no ARM mirror at all.)
   Applying it on ARM leaves the installed system unable to update anything.

3. install/user/mise-work.sh

   Node publishes its builds as linux-x64 / linux-arm64, which does not match
   uname -m. The bundled-tarball lookup hardcodes linux-x64, so on ARM it finds
   nothing and the install aborts with "no bundled Node tarball". The sed that
   parses the version back out of the filename needs the same treatment.

All three were found by installing Omarchy on aarch64 (Arch Linux ARM) and are
fixed here the same way: derive from uname -m rather than assuming.
The previous guard skipped the pacman.conf restore on aarch64 on the grounds
that Omarchy's config points at x86-only repositories. But at that point the
target still carries the live ISO's pacman.conf, which knows only the offline
mirror, and that directory does not exist on the installed system. Skipping
therefore left every aarch64 install unable to run pacman at all, which is the
outcome the guard claimed to prevent.

Derive the config from Omarchy's template instead: drop [multilib], keep
[omarchy] (its $arch placeholder resolves correctly), add Arch Linux ARM's
[alarm] and [aur] repositories, and leave the mirrorlist the distribution
installed rather than replacing it with Omarchy's x86_64 mirror of Arch. The
x86_64 path is unchanged.
Snapdragon laptops boot with the device tree for their exact model and the
firmware provides none. The live ISO already boots them with a systemd-stub
UKI that carries every candidate tree as .dtbauto sections and picks one by
SMBIOS hardware id; the installed system built its UKIs with no tree at all,
so the first reboot after the install had nothing to boot.

Add the omarchy-hw-qualcomm-soc probe (root device-tree compatible starts
with qcom,) and a hardware leaf that lists the trees in /etc/kernel/uki.conf,
which mkinitcpio hands to ukify for every UKI limine-mkinitcpio-hook builds.
The list is a snapshot of /boot/dtbs/qcom taken when the leaf runs; the file
header says so, and the enumeration retires when ukify accepts globs.
The same set Fedora's Snapdragon images and the live ISO carry, as a
limine-entry-tool drop-in so limine-update folds it into every entry, with
each parameter's reason and retirement condition in the file.
Adreno GPUs are platform devices, so the lspci vendor scan in vulkan.sh
never sees them; ask the SoC probe instead.
…s exist

Arch Linux ARM keeps the redistributable Qualcomm blobs in
linux-firmware-qcom; the installed system had none of them. The vendor-signed
DSP firmware comes later from the owner's Windows partition; until it is
there the DSP driver's failing probe resets the USB-C mux, which drops a
USB-C root disk and hangs the boot (seen on the HP EliteBook Ultra G1q).
install/hardware/qualcomm/firmware.sh installs qcom-firmware-extract next to
linux-firmware-qcom and runs it in the target: the files the device tree
names (GPU zap shader, audio and compute DSP images) are taken from the stage
the ISO saved before the disk was written, or from a Windows partition still
on disk, into /usr/lib/firmware/updates. The audio-DSP blacklist now follows
what is actually missing (qcom-firmware-extract --list-missing) instead of a
path glob, so it clears itself once the firmware is present.

install/omarchy-other.packages lists qcom-firmware-extract (arch=any) so the
offline mirror carries it.
With real DSP firmware the Type-C port controller takes over the ports once
the ADSP is up and resets them, which drops a root disk behind a USB-C port
(G1q, external NVMe: cdsp up at 10.8 s, I/O errors and a read-only root at
22 s). Installs whose root disk reports TRAN=usb keep qcom_q6v5_pas
blacklisted (no audio or battery reporting) until the kernel stops resetting
connected ports; internal-disk installs are unchanged.
The final pacman restore is skipped entirely on ARM, which leaves the
installed system pointed at the live ISO's offline config -- a file:// repo
under a bind mount that only exists during the install. The first thing a new
aarch64 desktop does is fail:

  $ sudo pacman -Sy evtest
  failed retrieving file 'offline.db' from disk: Could not open file
  /var/cache/omarchy/mirror/offline/offline.db

No pacman -S, no omarchy-update. The skip was right that Omarchy's channel
configs cannot be applied on ARM -- [core]/[extra] come from Omarchy's mirror
of Arch, which builds x86_64 only, [multilib] is 32-bit x86, and the Omarchy
package repository serves no aarch64 tree -- but the configuration it keeps
instead is the offline one, so it trades a broken config for no config.

Restore Arch Linux ARM's repositories there instead: [core] [extra] [alarm]
[aur], its stock set, through a mirrorlist of its own because ALARM serves
$arch/$repo where Arch serves $repo/os/$arch. [options] is kept byte-identical
to the x86_64 channel configs. [omarchy] is left out until that tree exists;
including it would 404 on every sync, and Omarchy's own packages simply hold
at the versions the ISO installed.

Three further things the restore has to do that the x86_64 path does not:

- Take archlinuxarm-keyring while the offline mirror is still the active
  source. Arch's `base` pulls in archlinux-keyring and nothing pulls in this
  one, and the repositories being written are unreachable during an offline
  install.

- Write the mirrorlist unconditionally. The target's mirrorlist carries
  Omarchy's and Arch's x86_64 mirrors ahead of ALARM's, so a sync logs 404s
  from mirror.omarchy.org, mirror.rackspace.com and geo.mirror.pkgbuild.com
  before it finds anything.

- Populate the keyring. The install leaves ALARM's build key untrusted on the
  target, so the first signed install fails with "Arch Linux ARM Build System
  <builder@archlinuxarm.org> is unknown trust".

x86_64 keeps running the same two lines it ran before, and every other
architecture keeps the behaviour it had before the skip was introduced.
@birkskyum

birkskyum commented Sep 6, 2026 •

Copy link
Copy Markdown
Author

@JimmayVV, thanks again for your work on this. Since your G1q report, the shared speaker-reset fix has merged in archlinuxarm/PKGBUILDs#2217, and we've got speakers and graphical disk unlock working on the Yoga. Some of these fixes may help the G1q too, including JimmayVV/omarchy-iso#25.

Would you be interested in testing a G1q-specific update when you have time? If you've already tried a newer kernel with your HP topology/UCM fixes, I'd also be interested to hear how it went.

I'd adapt the Yoga-specific unlock changes and provide rollback instructions first, keeping the USB-root DSP safeguard if you're still using an external disk. No reinstall or Lenovo firmware needed.

@jdvmi00

jdvmi00 commented Sep 9, 2026

Copy link
Copy Markdown

@birkskyum thanks for carrying this forward. One part of the PR I'd like to raise
before it gets reviewed: the bin/omarchy-refresh-pacman change.

The template approach writes a fixed ALARM config and appends [omarchy] for
edge. On the DGX Spark installs we're testing, that overwrite loses things the ISO
put there on purpose:

  • The [omarchy] section sits above [core]/[alarm] in the installed config
    so a compatibility package can override a broken ALARM transition. The
    template puts it last.
  • Installs built with OMARCHY_PKGS_MIRROR (self-hosted or interim mirrors,
    which omarchy-iso documents as a supported build input) get repointed at
    pkgs.omarchy.org and lose their base mirror pins.
  • It's the same failure class as omarchy-refresh-pacman drops hardware-specific repos (arch-mact2 on T2 Macs), silently orphaning linux-t2 #9853 on x86, where the refresh drops
    [arch-mact2] and orphans the running kernel.
  • Refusing stable/rc is hard-coded, so the script needs another change when
    those trees publish.

An alternative that avoids all four: on aarch64, leave the existing config
alone and only rewrite the channel segment of the [omarchy] Server line,
refusing to touch anything it doesn't recognise. Branch with tests here:
https://github.com/jdvmi00/omarchy/tree/spark/arm-pacman-refresh
(diff: quattro...jdvmi00:omarchy:spark/arm-pacman-refresh)

Limitations, to be upfront: it can't reset a broken ARM config the way the x86
template path can, and on an install pointed at a private mirror it refuses
rather than switching. Only edge resolves for aarch64 today, so switching to
stable/rc still fails at the database download; #8781's rollback would cover
that cleanly.

Happy to fold this into your branch instead of a separate PR if you'd prefer.
Testing so far is the isolated shell test only; I haven't yet run a real
refresh on the DGX Spark because its config points at the interim mirror.

@birkskyum

Copy link
Copy Markdown
Author

Thanks, Jim. Looks like you’re right about the refresh losing the repository ordering and mirror choices set by the installer. I’ll fold your change into this branch, preserving your authorship.

@jdvmi00

jdvmi00 commented Sep 9, 2026

Copy link
Copy Markdown

Confirmed the fold, thanks. The ARM refresh test, the aarch64 pacman test, and
the CLI tests pass for me on the branch head.

@birkskyum
birkskyum changed the base branch from quattro to dragon September 13, 2026 15:46
@birkskyum
birkskyum merged commit a7e80db into omacom:dragon Sep 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants