When hardwareProfile includes common-gpu-nvidia, emit a comment-only plain NixOS block (PRIME / powerManagement / open-module) in the installer region of system.nix — same pattern as ROCm/NPU opt-ins. HARDWARE.md §6 product direction marked shipped. Close #59. Verified: V0 (patch-template smoke + negative + bash -n).
16 KiB
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(PROPOSED › Hardware product). Product framing:VISION.md§ A. Design history:ROADMAP.md. Docs map:README.md. Migration:MIGRATION.md.
1. Architecture (three layers)
Nomarchy does not reimplement 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:
- Probes CPU vendor, GPUs (
lspci), battery, SSD, fingerprint USB VIDs, RGB+IR webcam names, NPU PCI class. - Looks up DMI
sys_vendor×product_namein a ~60-entry model table (Framework, Dell XPS/Latitude, ThinkPad, Surface, ASUS ROG, Apple T2, System76). - Emits
MODULE …lines →hardwareProfilelist inflake.nix. - Emits
NOMARCHY hardware.*=…→ active + commented blocks insystem.nix. - 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
# modules/nixos/default.nix
services.fwupd.enable = lib.mkDefault true;
fwupd talks to the LVFS: 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)
# 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 | First-boot / MOTD hint |
| README one-liner | Doctor check (“updates available”) |
System ▸ Firmware menu (nomarchy-menu firmware) |
Waybar / updates panel integration |
System ▸ Firmware (shipped): a self-gated System-submenu row (present
whenever fwupdmgr is on PATH, i.e. services.fwupd.enable, default-on)
that opens a terminal and runs fwupdmgr refresh → get-updates →
confirm → fwupdmgr update. It never auto-flashes — fwupdmgr update
confirms each device and prompts for the reboot a capsule needs; pillar 1
(rock-stable) forbids silent BIOS writes.
Still queued: a post-install / MOTD one-liner when fwupd is active,
a Doctor “updates available” check, and Waybar/updates-panel integration.
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-*andnixos-generate-configonce redistributable firmware is on — not a separatenomarchy.*toggle. - GPU GuC/HuC (Intel i915):
nomarchy.hardware.intel.guc→i915.enable_guc=3. Installer turns this off when the bound driver isxe(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:
nomarchy.hardware.fingerprint.enable = true; # services.fprintd
# nomarchy.hardware.fingerprint.pam = true; # login + sudo (opt-in)
Enroll (CLI today)
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
- Confirm
common-gpu-nvidia(and oftencommon-gpu-intelorcommon-gpu-amd) are inhardwareProfile. - Read the relevant nixos-hardware module and NixOS NVIDIA wiki.
- Add plain NixOS options in
system.nix, for example (illustrative — hardware-specific):
# 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
- 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 (shipped #59): when common-gpu-nvidia is in
hardwareProfile, the installer emits a commented system.nix block
with PRIME / power / open-module pointers (same pattern as ROCm / NPU
comments). A full nomarchy.hardware.nvidia.* stack stays optional and
needs a maintainer + hardware-queue coverage.
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 applicablecommon-pcorcommon-pc-laptop+ optionalcommon-pc-ssdnomarchy.hardware.intelor.amdwhen 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
-
List candidates:
nix eval github:NixOS/nixos-hardware#nixosModules \ --apply builtins.attrNames # or: the ISO ships hardware-modules.txt for the same list -
Set in your flake (installer already uses a list):
hardwareProfile = [ "common-cpu-amd" "common-gpu-amd" "common-pc-laptop" "common-pc-ssd" "lenovo-thinkpad-t14-amd-gen3" # if it matches ]; -
sudo nixos-rebuild switch --flake ~/.nomarchy#default
Template / migration (no installer)
See 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):
-
On the machine:
cat /sys/class/dmi/id/sys_vendor cat /sys/class/dmi/id/product_name -
Find a matching attr in nixos-hardware (or add one upstream first).
-
Append to
pkgs/nomarchy-install/hardware-db.shinHARDWARE_DB:"VendorRegex|Product regex|nixos-hardware-module-name"First match wins — put specific lines above broad fallbacks.
-
Verify the name exists in the pinned nixos-hardware input (
mkFlakewill throw if not). A CI check that every DB name ∈nixosModulesis queued so lock bumps cannot silently break installs. -
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. 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 |