Acer M5-481T fails Ghostty because Ivy Bridge HD 4000 tops out at OpenGL 4.2 in Mesa; Ghostty needs 4.3 — a generation ceiling, not a missing driver. Document that plus UEFI/x86_64, RAM, and storage floors (Nix store generations + BTRFS snapper + hibernate swap≈RAM). Linked from README, docs map, HARDWARE.md; #95 points here.
23 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.
Minimum bar (OpenGL, RAM, disk, UEFI): REQUIREMENTS.md
— read that before calling a machine “unsupported”; this file is the
enablement stack and quirk list.
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 | Doctor check (“updates available”) |
| README one-liner | Waybar / updates panel integration |
System ▸ Firmware menu (nomarchy-menu firmware) |
|
| MOTD + first-boot tip (#43) |
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.
Hints (#43 / #73): MOTD cheat-sheet line + nomarchy-control-center --first-boot tip when fwupdmgr is on PATH. Fingerprint / doctor tips
follow the same pattern (fingerprint MOTD only when
nomarchy.hardware.fingerprint.enable).
Still queued: 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)
# nomarchy.hardware.fingerprint.parallel = false; # sequential prompt instead
Enroll (menu or CLI)
Shipped #55: System › Fingerprint (self-gated when fprintd-list is
on PATH) — a single Fingerprint (on/off) switch, plus Enroll / List /
Verify / Delete all (all usable while it's off — turning it on needs an
enrolled finger). The switch writes settings.fingerprint.pam, the one
state key behind both halves of "use my finger": login/sudo PAM here,
and the lock-screen unlock in modules/home/idle.nix. It runs
nomarchy-fingerprint, which sudos a system rebuild and then a home
switch, because the two halves live in different configurations.
It does not decide whether login prompts at all: auto-login skips the greeter entirely, so this adds the finger to the prompts that actually happen — sudo, the lock screen, and the greeter only when auto-login is off.
Hints (#73): MOTD line when fingerprint.enable is on; first-boot
tip when fprintd-list is on PATH (SUPER+M → System › Fingerprint /
fprintd-enroll). No permanent nag without a reader.
# CLI still works:
fprintd-enroll
fprintd-list "$USER"
nomarchy-fingerprint toggle # or on | off | status — what the menu row runs
PAM stays opt-in on purpose: password-only remains the cautious default until a finger is enrolled. Full enroll on a real reader is V3/hardware.
Auto-login
settings.greeter.autoLogin (System › Auto-login, or nomarchy-autologin [toggle|on|off|status]) decides whether boot goes straight to the desktop
or stops at the greeter. The installer seeds it ON for LUKS-encrypted
machines — the disk passphrase already gates the machine, so a greeter
password is a second prompt for the same thing — and leaves it off
without LUKS, where the greeter is the only thing between power-on and the
desktop. It's baked into greetd at system rebuild, so the change shows on
the next boot.
Auto-login and fingerprint are independent, and auto-login wins at boot: with it on you are never asked for anything at startup, whatever the fingerprint switch says. Turn auto-login off and the greeter asks — for a password, or a password or finger when fingerprint is on.
Both are in-flake state rather than lines in system.nix on purpose: a
hand-set nomarchy.system.greeter.autoLogin (or
nomarchy.hardware.fingerprint.pam) outranks the state and pins the
setting, leaving the menu toggle unable to move it. That's the escape
hatch, not the default — leave those lines commented to use the menu.
Parallel prompt (password or finger, whichever first)
With fingerprint.pam on, sudo/login/hyprlock show one prompt that
accepts either factor — type the password or touch the sensor
(2026-07-12; pam-fprint-grosshack, an fprintd fork, since stock PAM
can't express parallel factors). This is the default;
fingerprint.parallel = false restores stock pam_fprintd's sequential
wait-for-the-reader-then-password. Lockout safety is structural: the
module never validates passwords itself — a typed password is handed to
the normal pam_unix rule, and every failure (no reader, fprintd hung,
timeout) falls through to password, so finger auth can only ever add a
way in. Verify the wiring with
grep pam_fprintd_grosshack /etc/pam.d/sudo. Known cosmetic quirk: after
a fingerprint win a leftover password prompt may linger on the console.
Doctor
nomarchy-doctor reports fprintd unit + enroll status when present.
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; first-class wrappers deferred for v1):
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). No nomarchy.hardware.nvidia.*
stack for v1 — hybrid PRIME remains wiki/plain NixOS until a maintainer
commits to hardware 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 / CC — live sysfs + state; boot oneshot re-applies | No rebuild for live; rebuild bakes Nix option |
| 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 |
Dual-sensor webcam / IR hide
Many dual-sensor modules (e.g. ThinkPad T14s) expose colour + IR as two identically named “Integrated Camera” nodes. Picking the IR node yields a black/dark greyscale frame — the classic “my webcam is dark” symptom.
nomarchy.hardware.camera.hideIrSensor (installer-on when RGB+IR names
are detected; overridable irMatch) drops the IR node from WirePlumber’s
v4l2 monitor so native PipeWire pickers only offer the colour camera.
The kernel /dev/video* node stays open, so Howdy-style face unlock still
works. Design history: ROADMAP § Webcam.
What it does not cover: apps that list cameras via libcamera or
the xdg-desktop-portal / Flatpak camera path still see both
sensors — a Flatpak Zoom (or similar) user can still pick the black IR
“camera”. That is intentional: a blanket libcamera disable would risk
external USB cams that need the libcamera path, and surgical internal-only
libcamera rules could not match early enough (only device.api binds
before the WirePlumber monitor rule).
Workaround: prefer the colour device in the picker (or any non-IR name). Apps that default to the first v4l2 colour source without a picker are fine.
Further engineering (needs T14s-class hardware): (b) a WirePlumber
libcamera monitor rule disabling GREY-only nodes; (c) a libcamera/udev
quirk at the libcamera layer. Neither is implemented — the recommended
path is document-only until those can be verified on real dual-sensor
hardware (see agent/HARDWARE-QUEUE.md › T14s).
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.
Post-install re-probe (shipped #58):
nomarchy-detect-hw # human report + suggested snippets
nomarchy-detect-hw --raw # MODULE / NOMARCHY / DETAIL protocol lines
Prints suggested hardwareProfile and system.nix lines; does not
rewrite the flake. Paste after review, then sudo nixos-rebuild switch.
9. Install-tested machines (hall of fame)
Models that have seen a real Nomarchy session (live ISO, install, or day-to-day QA) — not a guarantee of every feature, just a public seed list. DB coverage (hardware-db.sh) is broader; this table is the smaller “someone actually sat at it” set.
| Model | DMI (sys_vendor × product_name / version) |
Typical hardwareProfile |
Last noted | Notes |
|---|---|---|---|---|
| Lenovo ThinkPad T14s Gen 4 (AMD) | LENOVO × 21F8CTO1WW / ThinkPad T14s Gen 4 |
common AMD laptop + SSD (plus nomarchy.hardware.amd / fingerprint / IR cam as probed) |
2026-07 | Maintainer day-to-day + HARDWARE-QUEUE (IR portal, fingerprint, NPU). Dual-sensor webcam is the motivating IR case. |
| Dell Latitude 5410 | Dell Latitude 5410 (Intel) | common Intel laptop + SSD (+ GuC when enabled) | 2026-07 | Primary Intel hardware-QA host (session, themes, polkit, bar). |
| Dell Latitude 5310 | Dell Latitude 5310 (Intel) | same family as 5410 | 2026-07 | Charge-limit / power QA sibling (see HARDWARE-QUEUE). |
Send your DMI line
If you install Nomarchy on a machine and it works (or fails in an interesting way), open a PR that:
- Adds a row to the table above (model, DMI, profile, date, short notes).
- Optionally adds a
HARDWARE_DBline inpkgs/nomarchy-install/hardware-db.shwhen nixos-hardware has a matching module (§10).
Quick DMI grab:
printf '%s | %s | %s\n' \
"$(cat /sys/class/dmi/id/sys_vendor)" \
"$(cat /sys/class/dmi/id/product_name)" \
"$(cat /sys/class/dmi/id/product_version)"
nomarchy-detect-hw # suggested MODULE / NOMARCHY lines
10. 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. Install-tested status goes in the hall-of-fame table (§9).
11. Doctor and hardware health (current vs target)
Today (nomarchy-doctor): failed units, disk space, theme-state
validity/git, generation age, snapper; hardware section self-gates per
machine (NetworkManager, audio sink, GPU smoke, fprintd, fwupd, charge
limit, battery health, hibernate/zram). All read-only; each ✖ prints one
fix command.
| 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 reports it | power docs / restart charge-limit unit |
| Battery health | cycle_count and/or charge|energy_full÷design % when sysfs exports them | report-only (warn if <70% of design) |
| First-boot pre-activate | installer log present + no HM generation | home-manager switch --flake ~/.nomarchy -b bak |
| Hibernate / zram | disk swap + resume=; zram active | docs/MIGRATION.md → Enabling hibernation |
12. 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 / .parallel |
fprintd + PAM (parallel password-or-finger prompt by default) |
nomarchy.hardware.npu.enable |
in-kernel NPU only |
nomarchy.hardware.latestKernel |
linuxPackages_latest |
nomarchy.hardware.camera.hideIrSensor / .irMatch |
dual-sensor webcams (v4l2 only; §7) |
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) |
13. 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 |
14. 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 |