From 29c045b894f6ed0f51c1607e3f416c637bda871f Mon Sep 17 00:00:00 2001 From: Sean Kenneth Doherty <328402569+seankd3@users.noreply.github.com> Date: Fri, 6 Nov 2026 23:09:01 -0600 Subject: [PATCH 1/2] Keep the firmware DSDT to avoid stale GNVS addresses --- README.md | 9 ++-- acpi/acpi_builder.py | 103 +++++++++++++------------------------ config/p16-acpi | 3 +- packages/build-local.py | 2 +- scripts/build-acpi.py | 5 +- scripts/install-kernel.sh | 6 +-- scripts/install_state.py | 1 + scripts/verify-boot.py | 8 ++- tests/test_installation.py | 62 ++++++++++++++++++++++ 9 files changed, 116 insertions(+), 83 deletions(-) diff --git a/README.md b/README.md index 72883f7..fb9a29d 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ Confirm replacement of `power-profiles-daemon` if Pacman prompts for it. The Oma ## 3. Generate the ACPI overrides The [ACPI builder and battery-method transformations](https://github.com/pfeifferj/archlinuxarm-proart-p16/tree/3484cc008a9ee00b34c086c729e28e935cbc3430/01-platform/acpi/payload/provenance/hardware) -come from Josephine Pfeiffer's repository. Their source is retained unchanged; +come from Josephine Pfeiffer's repository. Their source is adapted here; this repository adds the Omarchy build/install wrappers and kernel-specific initramfs integration. See [the retained MIT license](acpi/LICENSE). @@ -133,17 +133,16 @@ sudo ./scripts/dump-acpi.sh python3 scripts/build-acpi.py ``` -The build uses the included ACPICA **20260408** source and checks the original tables and both generated overrides against pinned SHA-256 hashes. It rejects other firmware tables and tables that have already been patched. The dump script creates the parent `build/` directory with ownership assigned to the user who will compile the sources. It refuses to overwrite an existing `build/firmware/` directory. +The build uses the included ACPICA **20260408** source and checks the original tables and the generated ASUS SSDT override against pinned SHA-256 hashes. It rejects other firmware tables and tables that have already been patched. The dump script creates the parent `build/` directory with ownership assigned to the user who will compile the sources. It refuses to overwrite an existing `build/firmware/` directory. Outputs: ```text -build/acpi/kernel/firmware/acpi/DSDT.aml build/acpi/kernel/firmware/acpi/SSDT.aml build/acpi/manifest.json ``` -The DSDT corrects SSPM enumeration; the SSDT corrects EC and battery methods. The kernel includes the ARM64 allocation fix required for these overrides. Load the tables through the included initramfs hook for the P16 kernel. This does not flash the BIOS. +The SSDT corrects EC and battery methods. The existing `acpi_osi="!Windows 2022"` boot option enables SSPM. Keep the native DSDT: its firmware-data address can move between boots on the same BIOS. A copied DSDT can then hide CPU devices and prevent CPU frequency controls from loading. The initramfs hook includes only the ASUS SSDT. This does not flash the BIOS. ## 4. Build the P16 kernel @@ -459,7 +458,7 @@ They identify the inputs used here, independently of later upstream changes. | Component | Source and treatment in this repository | |---|---| -| ACPI builder and battery transformations | [Pfeiffer's ACPI sources](https://github.com/pfeifferj/archlinuxarm-proart-p16/tree/3484cc008a9ee00b34c086c729e28e935cbc3430/01-platform/acpi/payload/provenance/hardware): `acpi_builder.py`, `power-method-changes.json`, `power-source.sed` and `power-splice.json` are byte-identical copies under `acpi/`. Our scripts wrap them for local firmware dumps, builds and Omarchy installation. | +| ACPI builder and battery transformations | [Pfeiffer's ACPI sources](https://github.com/pfeifferj/archlinuxarm-proart-p16/tree/3484cc008a9ee00b34c086c729e28e935cbc3430/01-platform/acpi/payload/provenance/hardware): `power-method-changes.json`, `power-source.sed` and `power-splice.json` are byte-identical copies under `acpi/`. We adapted `acpi_builder.py` to retain the native DSDT. Our scripts wrap it for local firmware dumps, builds and Omarchy installation. | | ARM64 ACPI allocation fix | [Source patch](https://github.com/pfeifferj/archlinuxarm-proart-p16/blob/3484cc008a9ee00b34c086c729e28e935cbc3430/01-platform/kernel/patches/provenance/hardware/backports/acpi/0001-arm64-bound-acpi-override-allocation.patch): copied unchanged as [kernel/arm64-acpi-allocation.patch](kernel/arm64-acpi-allocation.patch), integrated into the Omarchy kernel recipe. | | Touchpad pressure workaround | [Source quirk](https://github.com/pfeifferj/archlinuxarm-proart-p16/blob/3484cc008a9ee00b34c086c729e28e935cbc3430/03-system/input-audio/payload/runtime/usr/share/libinput/60-h7607a-touchpad.quirks): same device IDs and pressure settings; local section name/DMI pattern and installation into `/etc/libinput/local-overrides.quirks` instead of a packaged `/usr/share/libinput/` file. | | Speaker firmware | [Source lock](https://github.com/pfeifferj/archlinuxarm-proart-p16/blob/3484cc008a9ee00b34c086c729e28e935cbc3430/07-build/media/payload/locks/hardware.json): extraction metadata for the three `spkid0` files is retained in [config/speaker-firmware.json](config/speaker-firmware.json). Firmware is downloaded from ASUS and extracted locally; no firmware binaries are redistributed. | diff --git a/acpi/acpi_builder.py b/acpi/acpi_builder.py index f8a95a7..0cadc1c 100644 --- a/acpi/acpi_builder.py +++ b/acpi/acpi_builder.py @@ -2,7 +2,7 @@ """Build the H7607BA.300 ACPI overrides from this P16's own firmware tables. No firmware table, nor anything derived from one, is distributed. Dump the -DSDT and SSDTs of your own P16 into a directory and pass it as --dump: +ASUS SSDT of your own P16 into a directory and pass it as --dump: UEFI: scripts/stage-acpi-dump.py stages the EDK2 Shell and a dump script on a mounted FAT32 stick. Boot the P16 from it with Secure Boot disabled; the @@ -11,17 +11,19 @@ Linux booted without h7607a-acpi.cpio, such as another distribution's live system on this P16: mkdir DIR - for table in /sys/firmware/acpi/tables/DSDT /sys/firmware/acpi/tables/SSDT*; do + for table in /sys/firmware/acpi/tables/SSDT*; do sudo cat "$table" | tee "DIR/${table##*/}" > /dev/null done -The DSDT and the ASUS SSDT (OEM ID _ASUS_, table ID ASUSSSDT) must be those of -firmware H7607BA.300. power-source.dsl is that SSDT disassembled by ACPICA iasl -20260408 and edited by power-source.sed. SSPM changes only its _STA predicate, -and six compiled ASUS methods are spliced into the original SSDT, since -compiling the whole table would rewrite unrelated AML. The two tables, the ASL -and the archive are written to their collection paths once every pinned hash -matches. +The ASUS SSDT (OEM ID _ASUS_, table ID ASUSSSDT) must be from firmware +H7607BA.300. power-source.dsl is that table disassembled by ACPICA iasl +20260408 and edited by power-source.sed. Six compiled ASUS methods are +spliced into the original SSDT. The SSDT, ASL and archive are written only +after every pinned hash matches. + +The native DSDT stays in use. Its firmware-data addresses can change between +boots even on the same BIOS. The required acpi_osi="!Windows 2022" boot option +already enables SSPM without replacing that table. """ import argparse import hashlib @@ -37,15 +39,12 @@ REPO = Path(__file__).resolve().parents[2] FIRMWARE = "H7607BA.300" -DSDT_INPUT = "0b9ed92671568cf36bade16262d068d1a4f3c85634159de46ae00bf0f727a402" SSDT_INPUT = "46d9ed16af06093cdb849df69646683317d53d7342dfd38f24eab00795d396f0" ASL_INPUT = "cff6e8be5665686c95bd83b5e2d73ed0abbacddecc416e57dbd29f91a746472a" -DSDT_OUTPUT = "80e0ad4a051704003d09029cb600a9814e1cd370ce774b9749dc09d2232b5aaf" SSDT_OUTPUT = "9b28ffc14c19f8b7ea2278de88ff9ec070f5f70401107d81fef067a916aa9695" -ARCHIVE_OUTPUT = "311dc5b456f1b7a9728814cd8ca105370bdca8383facec141f23217f43eac51d" +ARCHIVE_OUTPUT = "68420c5248a237b01267bf8713867f53358252d0d3935fb09c0e66b02c39153e" METHODS = ("RRA9", "RRA8", "WRA9", "WRA8", "RWEC", "GBST") ASUS_SSDT = b"_ASUS_ASUSSSDT" -DSDT_PATH = "assets/hardware/uefi/n1x-dsdt-baseline.bin" SSDT_PATH = "assets/hardware/uefi/n1x-asus-ssdt-baseline.bin" ASL_PATH = "provenance/hardware/power-source.dsl" ARCHIVE_PATH = "assets/hardware/acpi/h7607a-acpi.cpio" @@ -97,21 +96,6 @@ def encode_length(length, width): [(length >> (4 + i * 8)) & 255 for i in range(width - 1)]) -def patch_dsdt(original): - exact(original, DSDT_INPUT, "Firmware DSDT") - table(original, b"DSDT", b"NVDA\0\0ANGUS ", 4) - start = 0x10269 - predicate = b"_OSI\x0dWindows 2022\0" - require(original[start:start + len(predicate)] == predicate, "SSPM predicate changed") - modified = bytearray(original) - modified[start:start + len(predicate)] = b"\0" + b"\xa3" * (len(predicate) - 1) - struct.pack_into(" Date: Sat, 7 Nov 2026 09:15:03 -0600 Subject: [PATCH 2/2] Reject duplicate ACPI entries and document clean rebuilds --- README.md | 9 +++++++++ scripts/verify-boot.py | 14 +++++++------- tests/test_installation.py | 25 ++++++------------------- 3 files changed, 22 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index fb9a29d..5ef7631 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,15 @@ python3 scripts/build-acpi.py The build uses the included ACPICA **20260408** source and checks the original tables and the generated ASUS SSDT override against pinned SHA-256 hashes. It rejects other firmware tables and tables that have already been patched. The dump script creates the parent `build/` directory with ownership assigned to the user who will compile the sources. It refuses to overwrite an existing `build/firmware/` directory. +If you generated ACPI files with an older version, retain `build/firmware/` and move the old output aside before rebuilding: + +```bash +mv -T --no-clobber build/acpi build/acpi-before-native-dsdt +python3 scripts/build-acpi.py +``` + +If the backup directory already exists, choose another unused name. The builder refuses to replace different existing output bytes. + Outputs: ```text diff --git a/scripts/verify-boot.py b/scripts/verify-boot.py index 0fd6b11..94a1244 100755 --- a/scripts/verify-boot.py +++ b/scripts/verify-boot.py @@ -55,7 +55,7 @@ def verify_image(path): raise ValueError('Unzulässige ACPI-Deaktivierung im UKI') data = sec['.initrd'] offset = 0 - files = {} + files = [] while data[offset:offset + 6] in (b'070701', b'070702'): fields = [int(data[offset + 6 + i * 8:offset + 14 + i * 8], 16) for i in range(13)] size, namesize = (fields[6], fields[11]) @@ -64,16 +64,16 @@ def verify_image(path): start = start + namesize + 3 & ~3 if not start + size <= len(data): raise ValueError('Abgeschnittenes frühes CPIO-Archiv') - files[name] = data[start:start + size] + if name.startswith('kernel/firmware/acpi/'): + files.append((name, data[start:start + size])) offset = start + size + 3 & ~3 if name == 'TRAILER!!!': break - expected = {'kernel/firmware/acpi/' + name for name in PINS} - actual = {name for name in files if name.startswith('kernel/firmware/acpi/')} - if actual != expected: + expected = sorted('kernel/firmware/acpi/' + name for name in PINS) + if sorted(name for name, content in files) != expected: raise ValueError('Only the ASUS SSDT override is allowed; use the native firmware DSDT') - for name, pin in PINS.items(): - if not hashlib.sha256(files['kernel/firmware/acpi/' + name]).hexdigest() == pin: + for name, content in files: + if not hashlib.sha256(content).hexdigest() == PINS[name.removeprefix('kernel/firmware/acpi/')]: raise ValueError('Falsche ACPI-Tabelle im UKI: ' + name) with tempfile.NamedTemporaryFile() as tmp: tmp.write(data) diff --git a/tests/test_installation.py b/tests/test_installation.py index 43308a5..48458e2 100644 --- a/tests/test_installation.py +++ b/tests/test_installation.py @@ -35,25 +35,6 @@ def module(name, filename): class NativeDSDTTests(unittest.TestCase): - def test_relocated_dsdt_does_not_change_selected_asus_table(self): - ssdt = bytearray(36) - ssdt[:4] = b'SSDT' - struct.pack_into('