Skip to content

Add safe Windows firmware extraction for Snapdragon laptops - #221

Open
birkskyum wants to merge 19 commits into
omacom:masterfrom
birkskyum:upstream/qcom-firmware-extract
Open

birkskyum wants to merge 19 commits into
omacom:masterfrom
birkskyum:upstream/qcom-firmware-extract

Conversation

@birkskyum

@birkskyum birkskyum commented Aug 27, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds qcom-firmware-extract as a fallback for firmware not already available to Linux. It reads the running device tree and stages missing files from a readable Windows driver store or backup directory (-d), so the installer can preserve them before partitioning.

  • Installs under /usr/lib/firmware/updates. Differing variants require a unique companion-hash match within the same device-tree node; ambiguous or missing files are skipped without stopping other files.
  • Matches the kernel's plain, zstd and xz firmware lookup. Gzip files do not hide missing loadable firmware.
  • Includes board-selected GPU zap firmware in the initramfs and rebuilds when that configuration changes, even without extraction.

Discovery requires a device tree. An empty result on an ACPI-only machine does not establish firmware completeness. This does not download OEM packages or provide Linux drivers.

Dependencies

Targets omarchy-pkgs/master. Consumers in omacom/omarchy#8672, omacom/omarchy#8673 and omacom/omarchy-iso#129 are merged into their respective dragon branches. This package can land and be published independently of #222 and #223.

Jimmy Van Veen authored the original extractor; Birk Skyum added matching and partial-install fixes. Original authorship is preserved.

Validation

September 16 verification passed against master 5fe2367: native ARM64 build of 1-4, extractor regressions, ShellCheck and whitespace checks. Hosted self-tests and build-isolation checks pass.

The current extraction/install path has not been rerun on the physical Yoga.

Earlier validation

The September 6 integration build built the extractor and shim. Earlier Windows extraction started ADSP and CDSP on the Yoga, but CDSP startup alone does not demonstrate compute acceleration.

The September 10 image included this package and booted without extraction; its missing CDSP companion remained unresolved. Integrated results and limits describe that image, not a new extraction test.

@JimmayVV

JimmayVV commented Aug 27, 2026 •

Copy link
Copy Markdown

Confirming provenance. qcom-firmware-extract is mine. The companion-hash matching is a real improvement. The "newest wins" rule was only ever tested against one driver store. Thanks for catching it.

JimmayVV and others added 4 commits September 6, 2026 00:48
Copy the vendor-signed Qualcomm firmware named by a Snapdragon laptop device tree from its Windows driver store into /usr/lib/firmware/updates.
@birkskyum
birkskyum force-pushed the upstream/qcom-firmware-extract branch from 2196071 to 040b8e0 Compare September 5, 2026 23:24
@ryanrhughes ryanrhughes added the build-approved Maintainer approved this PR to build on the self-hosted pool label Sep 28, 2026
@turbineBMW

Copy link
Copy Markdown

Tested on a Surface Pro 11 (X1E80100, microsoft,denali-oled) against its own Windows partition: it stages 3 of the 5 files. The device tree asks for qcom/x1e80100/microsoft/Denali/adsp_dtb.mbn and cdsp_dtb.mbn, but Windows ships them as adsp_dtbs.elf and cdsp_dtbs.elf in the matching driver packages, so the exact-name search misses them.

I have a small commit on top of your current head that looks for the Windows *_dtbs.elf name when the device-tree name isn't found. Exact names still win, and your companion matching still picks between variants: turbineBMW/omarchy-pkgs@c66e300. With it the Surface stages 5 of 5, and the ADSP and CDSP boot with the device-tree images taken from the .elf files. test.sh passes.

Happy for you to cherry-pick it into this PR, or I can open it as a follow-up after this merges. Whichever you prefer.

The Surface Pro 11 device tree asks for adsp_dtb.mbn and cdsp_dtb.mbn,
but Windows ships them as adsp_dtbs.elf and cdsp_dtbs.elf, so
extraction left both DSP device-tree images missing. Look for the
Windows name when the device-tree name is not found. Exact names still
take precedence, and the existing companion matching still selects
between variants.

Validated with test.sh and on a Surface Pro 11 against its own Windows
driver store: 5 of 5 firmware files staged, up from 3, and the ADSP and
CDSP boot with the device-tree images taken from the .elf files.
Any stage manifest, even an empty one, made --stage exit as already
staged and made --install use only the stage, so Windows was never read
again. A --stage rerun now keeps the staged files and looks for the
rest, and --install scans Windows only for what the stage lacks. -d
still replaces both. A rerun without root, which cannot read Windows,
keeps the stage and succeeds as before. Each run reads the stage
manifest once.

Mount points honour QCOM_FW_ROOT so the tests can stub the partition
scan. Both root checks now take the user ID from QCOM_FW_TEST_EUID when
the tests set it, and the install-mode check no longer skips when
QCOM_FW_ROOT is set.
Some device trees name firmware that should not be copied from Windows:
files a board package produces or holds back until they are tested, and
files the machine's boot firmware loads before Linux, which Windows
drivers do not carry.
On the Surface Laptop 8 these are its USB4 router image and SOCCP pair.

A board package can now list such names in
/usr/share/qcom-firmware-extract/provided.d/<compatible>.list. On a
machine with that compatible they are never searched for, installed or
reported by --list-missing, and the log names the list for each one. An
unreadable list or an entry containing a space is skipped with a
warning.

A copy an earlier --install made of a newly listed name stays in place:
the same bytes would not show that the file is still this tool's copy,
since a board's own tool may keep the same file there. The next
--install stops recording it and prints where it is, for the board
package or the user to remove.

Since --list-missing omits listed names, a board must not list firmware
that a hardware check relies on unless its package installs it before
the check runs.
Since the stage became the first source, --install takes a staged file
only by its exact device-tree path. After a full-disk install the stage
is the only copy, so a device tree that files an image under another
path could no longer be served from it. After Windows, fall back to a
staged file with the same name that the stage manifest lists, but not
when Windows refused differing variants of it as ambiguous.
With every name installed or listed, --list-missing prints nothing,
--stage and --install neither list nor mount partitions, and listed
names are not installed from Windows or the stage. A control run
without the list does scan. Listing the names again leaves the copies
it installed in place but stops recording them, and another missing
file still sends the extractor to Windows for that file alone.
--install mounts the Windows partitions whenever the stage lacks a
file, which after a full-disk install can be every later run, and it
mounted every NTFS partition, USB disks included. It now reads only
partitions on disks that lsblk reports as neither removable, hotplug
nor USB. --stage in the live session still reads all of them, internal
disks first, and -d takes a driver store from anywhere.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build-approved Maintainer approved this PR to build on the self-hosted pool

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants