# Hardware support How Nomarchy enables CPUs, GPUs, laptops, firmware, and peripherals — and what to do when your machine is not in the happy path. > **Queue:** [`agent/BACKLOG.md`](../agent/BACKLOG.md) (PROPOSED › Hardware > product). Product framing: [`VISION.md`](VISION.md) § A. Design history: > [`ROADMAP.md`](ROADMAP.md). Docs map: [`README.md`](README.md). > Migration: [`MIGRATION.md`](MIGRATION.md). ## 1. Architecture (three layers) Nomarchy does **not** reimplement [nixos-hardware](https://github.com/NixOS/nixos-hardware). It stacks: ``` ┌─────────────────────────────────────────────────────────────────────┐ │ A. Always-on desktop floor │ │ modules/nixos/default.nix + power.nix + audio/BT │ │ redistributable firmware · fwupd · NM · PipeWire · PPD · ddcci │ └───────────────────────────────┬─────────────────────────────────────┘ │ ┌───────────────────────────────▼─────────────────────────────────────┐ │ B. nixos-hardware profiles (via mkFlake hardwareProfile) │ │ common-cpu-* · common-gpu-* · common-pc(-laptop|-ssd) · model │ │ microcode · GPU media · fstrim · vendor/model quirks │ └───────────────────────────────┬─────────────────────────────────────┘ │ ┌───────────────────────────────▼─────────────────────────────────────┐ │ C. nomarchy.hardware.* (modules/nixos/hardware.nix) │ │ gap above commons: GuC · amd-pstate · VA-API env · fprintd · │ │ IR-webcam hide · ROCm/NPU/latestKernel · I2C/DDC/CI │ └─────────────────────────────────────────────────────────────────────┘ ``` | Layer | Who turns it on | Where it lives | |-------|-----------------|----------------| | **A** | Distro defaults (`mkDefault`) | Any machine importing `nomarchy.nixosModules.nomarchy` | | **B** | Installer DMI/`lspci` → `hardwareProfile = [ … ]` | Downstream `flake.nix` (`mkFlake`) | | **C** | Installer probes → `system.nix`, or hand-edit | Downstream `system.nix` | `hardware-configuration.nix` (from `nixos-generate-config`) still owns initrd modules, filesystems, and the usual generate-config flags. The installer writes a real one; the template ships a placeholder you must replace. Unknown `hardwareProfile` names **fail at eval** with Levenshtein suggestions (`lib.nix`) — never silently ignored. ## 2. What works without thinking about it These ship on every Nomarchy system unless you override them: | Capability | Default | Notes | |------------|---------|--------| | Wi‑Fi / BT firmware blobs | `hardware.enableRedistributableFirmware` | iwlwifi, ath, rtw, brcm, SOF, … | | NetworkManager | on | Wi‑Fi UI: System › Network | | PipeWire + WirePlumber | on | | | Bluetooth + blueman | on | System › Bluetooth | | power-profiles-daemon | on | Menu + Waybar; TLP via `nomarchy.system.power.backend = "tlp"` | | External monitor brightness | `nomarchy.hardware.i2c.ddcci` **on** | DDC/CI → backlight devices | | Firmware updates (LVFS) | `services.fwupd.enable` | **Never auto-flashes** — see §4 | | SMART / UPower / pcscd (FIDO) | on | | | earlyoom | on | Process-level OOM, not cgroup kill of the whole session | **Not** default-on (need detect or uncomment): fprintd, GuC/HuC, amd-pstate, ROCm, NPU, thermald, charge limit, snapper (installer enables snapper), `latestKernel`. ## 3. Install path (best experience) `nomarchy-install` sources `pkgs/nomarchy-install/hardware-db.sh` and: 1. Probes CPU vendor, GPUs (`lspci`), battery, SSD, fingerprint USB VIDs, RGB+IR webcam names, NPU PCI class. 2. Looks up DMI `sys_vendor` × `product_name` in a ~60-entry model table (Framework, Dell XPS/Latitude, ThinkPad, Surface, ASUS ROG, Apple T2, System76). 3. Emits `MODULE …` lines → `hardwareProfile` list in `flake.nix`. 4. Emits `NOMARCHY hardware.*=…` → active + commented blocks in `system.nix`. 5. Asks you to confirm profiles (or pick manually from the full nixos-hardware attr list baked into the ISO). Override with `NOMARCHY_HW=auto|none|"mod1 mod2"`. **Live ISO** is intentionally *generic* (no model profile): broad GPU modules as *available*, redistributable firmware on, no baked `nomarchy.hardware.*`. Tuning happens at install time. Out of scope for the installer today: aarch64 (Pi, Snapdragon X), Steam Deck (Jovian), Apple Silicon (T2 Intel Macs only in the DB). ## 4. Firmware updates (deep dive) ### What we ship ```nix # modules/nixos/default.nix services.fwupd.enable = lib.mkDefault true; ``` fwupd talks to the [LVFS](https://fwupd.org/): UEFI capsule (BIOS), some SSDs, docks, Thunderbolt controllers, peripherals. It **only refreshes metadata** on its own. Applying an update is always an explicit user action. ### What you do today (CLI) ```sh # After first boot (and occasionally later): fwupdmgr refresh # optional; daemon often has metadata fwupdmgr get-devices # what LVFS can see fwupdmgr get-updates # pending fwupdmgr update # apply (may need reboot / battery / AC) ``` Disable on VMs/headless: `services.fwupd.enable = false;` in `system.nix`. ### Why this is under-discovered | Present | Missing | |---------|---------| | Daemon + package | Menu entry / Control Center | | README one-liner | First-boot / MOTD hint | | | Doctor check (“updates available”) | | | Waybar / updates panel integration | **Product direction (queued):** System › Firmware (or a Doctor section) that runs refresh → list → confirm → `fwupdmgr update`, plus a short post-install note when `fwupd` is enabled. Never auto-flash; pillar 1 (rock-stable) forbids silent BIOS writes. ### Thunderbolt Firmware for TB devices may appear via LVFS. There is **no** first-class `services.hardware.bolt` / security-level UI in Nomarchy — use plain NixOS options if you need bolt. ### Microcode / kernel firmware - **CPU microcode:** from nixos-hardware `common-cpu-*` and `nixos-generate-config` once redistributable firmware is on — not a separate `nomarchy.*` toggle. - **GPU GuC/HuC (Intel i915):** `nomarchy.hardware.intel.guc` → `i915.enable_guc=3`. Installer turns this **off** when the bound driver is `xe` (GuC is default there; the param is ignored). - **`hardware.enableAllFirmware`:** not set. Oddball non-redistributable Wi‑Fi still needs a manual NixOS fix (or a broader policy decision). ## 5. Fingerprint (deep dive) ### Detect → enable Installer scans USB vendor IDs common to libfprint (Goodix, Synaptics, Elan, …) via `lsusb` or `/sys/bus/usb/.../idVendor`. On hit: ```nix nomarchy.hardware.fingerprint.enable = true; # services.fprintd # nomarchy.hardware.fingerprint.pam = true; # login + sudo (opt-in) ``` ### Enroll (CLI today) ```sh fprintd-enroll # as your user fprintd-list "$USER" # then, if you want login/sudo: # uncomment fingerprint.pam in system.nix → sys-rebuild ``` PAM stays opt-in on purpose: password-only remains the cautious default until a finger is enrolled. ### Gaps - No System menu “Fingerprint” row (enroll / list / delete). - No “use for login” toggle that writes state + rebuild note. - Doctor does not check reader presence or enroll status. **Product direction (queued):** when `fprintd` is active, a self-gated menu module for enroll/list; optional PAM toggle via state + rebuild hint (same pattern as Bluetooth in Control Center). ## 6. NVIDIA (deep dive) ### What happens at install ``` lspci → NVIDIA ⇒ MODULE common-gpu-nvidia ``` That is the **entire** Nomarchy surface. Unfree packages are allowed (`allowUnfree = true` in the module and in `mkFlake`), so the proprietary path from nixos-hardware can evaluate. There is **no** `nomarchy.hardware.nvidia.*` for: - hybrid / PRIME (Intel+NVIDIA, AMD+NVIDIA) - open vs closed kernel module - power management / udev / suspend quirks - CUDA / container toolkit packages ### What a hybrid laptop user must do today 1. Confirm `common-gpu-nvidia` (and often `common-gpu-intel` or `common-gpu-amd`) are in `hardwareProfile`. 2. Read the relevant nixos-hardware module and [NixOS NVIDIA wiki](https://wiki.nixos.org/wiki/Nvidia). 3. Add plain NixOS options in `system.nix`, for example (illustrative — hardware-specific): ```nix # Example only — verify against your generation and nixos-hardware module. # hardware.nvidia.prime = { ... }; # hardware.nvidia.powerManagement.enable = true; # hardware.nvidia.open = false; # or true for open modules on newer cards ``` 4. Rebuild the system. Home Manager does not own the driver. ### Live ISO note The ISO lists `nouveau` among *available* initrd modules and does **not** force-load every GPU driver (avoids multi-driver panics). Proprietary NVIDIA on the live session is not the product focus; installed systems use the profile. **Product direction (queued):** when detection selects `common-gpu-nvidia`, emit a **commented** `system.nix` block with PRIME / power / open-module pointers (same pattern as ROCm / NPU comments), not a full second NVIDIA stack unless a maintainer commits to testing. ## 7. Day-2: “my laptop is mostly fine, make it fully fine” | Goal | How | Rebuild? | |------|-----|----------| | Power profile (perf/balanced/saver) | System menu / Waybar | No (PPD D-Bus) | | Charge limit 80% | Menu / `settings.power.batteryChargeLimit` | System (sysfs apply is separate backlog) | | Thermald (Intel) | Installer on for Intel laptops; else `power.thermal.enable` | System | | Fingerprint enroll | `fprintd-enroll` | No | | Fingerprint login | `fingerprint.pam = true` | System | | ROCm / Intel compute | Uncomment opt-ins in `system.nix` | System (large) | | NPU driver | Uncomment `npu` (+ often `latestKernel`) | System; userspace BYO | | Newer kernel for brand-new silicon | `nomarchy.hardware.latestKernel = true` | System | | Hide IR “dark camera” | Installer or `camera.hideIrSensor` | System | | Firmware | `fwupdmgr update` | Reboot if capsule requires | | Model quirks missing | Set better `hardwareProfile` (see §8) | System | | OpenRGB / printing / Steam | `nomarchy.services.*` | System | Theme switches never touch drivers (Home Manager only). ## 8. Unsupported or unlisted machines ### Still good floor Even with **no** DMI hit you usually get: - `common-cpu-{intel,amd}` - `common-gpu-{intel,amd,nvidia}` as applicable - `common-pc` or `common-pc-laptop` + optional `common-pc-ssd` - `nomarchy.hardware.intel` or `.amd` when vendor matches - Layer A (firmware, audio, BT, PPD, fwupd) You **lose** model-specific EC/suspend/keyboard/audio quirks that only exist in a named nixos-hardware module. ### Pick a profile after install 1. List candidates: ```sh nix eval github:NixOS/nixos-hardware#nixosModules \ --apply builtins.attrNames # or: the ISO ships hardware-modules.txt for the same list ``` 2. Set in your flake (installer already uses a list): ```nix hardwareProfile = [ "common-cpu-amd" "common-gpu-amd" "common-pc-laptop" "common-pc-ssd" "lenovo-thinkpad-t14-amd-gen3" # if it matches ]; ``` 3. `sudo nixos-rebuild switch --flake ~/.nomarchy#default` ### Template / migration (no installer) See [MIGRATION.md](MIGRATION.md): reuse `hardware-configuration.nix`, set `hardwareProfile`, uncomment `nomarchy.hardware` / power in `system.nix`. There is **no** post-install re-probe helper yet (queued as `nomarchy-detect-hw`). ### Re-detect sketch (future) The installer’s `nomarchy_detect_hw` is already a pure probe (stdout lines only). Exposing it as a package on PATH that prints suggested `hardwareProfile` + `system.nix` snippets would close the template gap without reinstalling. ## 9. Adding your model to the distro For contributors (and power users who will PR): 1. On the machine: ```sh cat /sys/class/dmi/id/sys_vendor cat /sys/class/dmi/id/product_name ``` 2. Find a matching attr in [nixos-hardware](https://github.com/NixOS/nixos-hardware) (or add one upstream first). 3. Append to `pkgs/nomarchy-install/hardware-db.sh` in `HARDWARE_DB`: ```bash "VendorRegex|Product regex|nixos-hardware-module-name" ``` First match wins — put specific lines above broad fallbacks. 4. Verify the name exists in the **pinned** nixos-hardware input (`mkFlake` will throw if not). A CI check that every DB name ∈ `nixosModules` is queued so lock bumps cannot silently break installs. 5. Optional: note on-hardware QA steps in `agent/HARDWARE-QUEUE.md`. ## 10. Doctor and hardware health (current vs target) **Today** (`nomarchy-doctor`): failed units, disk space, theme-state validity/git, generation age, snapper timer. **No** Wi‑Fi, GPU, fwupd, or fingerprint checks. **Target checks** (queued, all read-only, each failure prints one fix command — same doctor contract): | Check | Pass condition | Suggested fix line | |-------|----------------|--------------------| | NetworkManager | device connected or wifi radio on | open System › Network | | Audio sink | default sink exists | System › Audio | | GPU accel | `glxinfo`/`vainfo` smoke (if installed) | check `hardwareProfile` / drivers | | Fingerprint | if USB VID matched / fprintd unit | `fprintd-enroll` or enable option | | fwupd | daemon active; optional “updates pending” warn | `fwupdmgr get-updates` | | Battery threshold | if laptop + limit set, sysfs writable | power docs | ## 11. Option quick reference Full tables: [README § options](../README.md). Hardware-shaped surface: | Option | Role | |--------|------| | `mkFlake.hardwareProfile` | nixos-hardware name or list | | `nomarchy.hardware.intel.enable` / `.guc` / `.computeRuntime` | Intel gap layer | | `nomarchy.hardware.amd.enable` / `.pstate` / `.vaapi` / `.rocm.*` | AMD gap layer | | `nomarchy.hardware.fingerprint.enable` / `.pam` | fprintd + PAM | | `nomarchy.hardware.npu.enable` | in-kernel NPU only | | `nomarchy.hardware.latestKernel` | `linuxPackages_latest` | | `nomarchy.hardware.camera.hideIrSensor` / `.irMatch` | dual-sensor webcams | | `nomarchy.hardware.i2c.enable` / `.ddcci` | I2C + external backlight | | `nomarchy.system.power.*` | PPD/TLP, laptop, thermald, charge limit | | `nomarchy.system.bluetooth.enable` | BT stack | | `services.fwupd.enable` | LVFS (native NixOS, default on) | ## 12. Ease summary | Situation | Effort | |-----------|--------| | Known model in DB (Framework, many ThinkPads, …) | Low — install and go | | Unknown modern Intel/AMD laptop | Low–medium — commons cover a lot | | Firmware updates | Medium — CLI only until product work lands | | Fingerprint for login | Medium — enroll CLI + PAM uncomment | | Hybrid NVIDIA | High — plain NixOS/wiki territory | | ROCm / NPU userspace | High — opt-in + expert | | Contribute a new DMI line | Medium for someone who can PR | ## 13. Related files | Path | Role | |------|------| | `modules/nixos/hardware.nix` | `nomarchy.hardware.*` | | `modules/nixos/power.nix` | PPD/TLP, charge limit, thermald | | `modules/nixos/default.nix` | firmware, fwupd, ddcci default | | `pkgs/nomarchy-install/hardware-db.sh` | DMI DB + probes | | `pkgs/nomarchy-install/nomarchy-install.sh` | writes flake + system.nix | | `lib.nix` | `hardwareProfile` resolution | | `templates/downstream/system.nix` | commented opt-ins | | `agent/HARDWARE-QUEUE.md` | on-machine V3 checks |