diff --git a/docs/firmware.md b/docs/firmware.md index eb6bd4e..fb79159 100644 --- a/docs/firmware.md +++ b/docs/firmware.md @@ -16,11 +16,11 @@ installs them: Networking therefore works on a freshly written image. Graphics does not: see below. -## What has to come off the Windows partition +## What you have to supply -These are signed against per-model keys and Fedora does not ship them, so on a -stock install they exist only inside the machine's Windows partition. Nothing -about them is unredistributable in principle — the equivalent files for the +These are signed against per-model keys and Fedora does not ship them, so a +stock install has none of them. Nothing about them is unredistributable in +principle — the equivalent files for the ThinkPad X13s *are* in linux-firmware — it is that nobody has obtained permission for this model. See [If you have no backup](#if-you-have-no-backup). @@ -91,10 +91,13 @@ msm_dpu ae01000.display-controller: Direct firmware load for qcom/a630_sqe.fw fa ``` `overlay/etc/dracut.conf.d/10-c630.conf` puts the Adreno files in the initramfs -for this reason, and `c630-firmware` adds the extracted DSP blobs to it after -extraction — the ADSP has to be up before the root filesystem is mounted, and -dracut rejects `install_items` globs that match nothing, so the entry can only -be written once the files exist. +for this reason, and `c630-firmware` adds `qcdxkmsuc850.mbn` once it exists. + +Only the GPU needs this. The ADSP, CDSP, SLPI, venus and modem all probe around +forty seconds in, well after the real root is mounted, and load from it +perfectly happily. That distinction is worth keeping: `qcdsp2850.mbn` alone is +60 MB, so sweeping the whole firmware directory into the initramfs would inflate +it roughly twentyfold for no benefit. ## Finding them on a backup @@ -115,8 +118,14 @@ files turn up nothing, look for those directories wholesale: find /mnt/backup -type d -iname 'qc*.inf_arm64_*' ``` -Expect a few hundred KB to a few MB each. `file` reports them as `data` — they -are signed Qualcomm MBN containers, not ELF, apart from `ipa_fws.elf`. +Sizes range from 14 KB (`qcdxkmsuc850.mbn`) to 60 MB (`qcdsp2850.mbn`). +Despite the `.mbn` extension they are ELF images, and `file` should say so: + +``` +qcdxkmsuc850.mbn: ELF 32-bit LSB executable, QUALCOMM DSP6, version 1 (SYSV) +``` + +Anything reporting as text or HTML is a download that went wrong. Lenovo does not appear to publish a driver package for the 81JL containing these. If the backups turn up nothing, see [If you have no @@ -147,19 +156,37 @@ licensing question, not a technical one. `qcom/sdm850/LENOVO/81JL/` has simply never been contributed. Fedora ships no sdm850 model firmware at all, so it will not turn up in a `linux-firmware` -update. Two routes: +update. Three routes, easiest first: + +**The WOA-Project reference drivers.** +collects the Windows-on-ARM driver packages by SoC. The C630's are three +cabinet files, and between them they hold every file this machine asks for: + +| Cabinet | Contains | +|---|---| +| `qcdx850.cab` | `qcdxkmsuc850.mbn` (zap shader), `qcvss850.mbn` (venus) | +| `qcipa850.cab` | `ipa_fws.elf` | +| `qcsubsys850.cab` | `qcadsp850.mbn`, `qccdsp850.mbn`, `qcslpi850.mbn`, `qcdsp1v2850.mbn`, `qcdsp2850.mbn`, and `WLANMDSP.MBN` | + +That last one is a bonus — the WiFi firmware, which is not in the device tree's +`firmware-name` list but is what the onboard ath10k needs. + +`cabextract` or `7z x` will open them: + +```sh +for f in qcdx850.cab qcipa850.cab qcsubsys850.cab; do 7z x -o./extracted "$f"; done +find ./extracted -iname 'qc*850.mbn' -o -iname 'ipa_fws.elf' -o -iname 'WLANMDSP.MBN' +``` + +Ignore the `_nm` and `_CLS` variants; the device tree asks for the plain names. +Verify what you get with `file` — they should report as +`ELF 32-bit LSB executable, QUALCOMM DSP6`, not as text or HTML. **Lenovo's Digital Download Recovery Service.** Lenovo builds a Windows recovery image against a machine's serial number and lets the owner download it. That image contains `Windows/System32/DriverStore/FileRepository`, and -therefore all eight files. It is your machine, so you are entitled to the -image, and it yields the exact blobs for your model rather than a stranger's. -Mount the image and search it the same way as any other backup: - -```sh -find /mnt/recovery -type f \ - \( -iname 'qc*850.mbn' -o -iname 'ipa_fws.elf' \) -printf '%10s %p\n' -``` +therefore all eight files. Slower than the cabinets, but it is unambiguously +your own machine's firmware. **Another C630 owner.** The aarch64-laptops project is where these have circulated before, and any 81JL's copy is as good as your own. diff --git a/overlay/usr/local/sbin/c630-firmware b/overlay/usr/local/sbin/c630-firmware index b0e2aaf..0f7dc21 100755 --- a/overlay/usr/local/sbin/c630-firmware +++ b/overlay/usr/local/sbin/c630-firmware @@ -34,14 +34,19 @@ fi qcom-firmware-extract "$@" echo -# The ADSP has to be up before the root filesystem is mounted, so these have to -# travel in the initramfs. Only write the glob now that the files exist — -# dracut objects to install_items that match nothing. +# Only the GPU zap shader has to travel in the initramfs. msm_dpu probes around +# six seconds in, while the initramfs is still the root filesystem, and never +# retries. Everything else — ADSP, CDSP, SLPI, venus, modem — is probed well +# after the real root is mounted and loads from there quite happily. +# +# This matters: qcdsp2850.mbn alone is 60MB. Globbing the whole directory into +# the initramfs, which is what this used to do, would have bloated it roughly +# twentyfold to no purpose. FW_DIR=/usr/lib/firmware/updates/qcom/sdm850/LENOVO/81JL -if compgen -G "${FW_DIR}/*.mbn" >/dev/null || compgen -G "${FW_DIR}/*.elf" >/dev/null; then - printf 'install_items+=" %s/*.mbn %s/*.elf "\n' "$FW_DIR" "$FW_DIR" \ - > /etc/dracut.conf.d/20-c630-extracted-firmware.conf - echo "Extracted firmware will be included in the initramfs." +if [ -f "${FW_DIR}/qcdxkmsuc850.mbn" ]; then + printf 'install_items+=" %s/qcdxkmsuc850.mbn "\n' "$FW_DIR" \ + > /etc/dracut.conf.d/20-c630-zap-shader.conf + echo "GPU zap shader will be included in the initramfs." fi echo "Regenerating the initramfs..."