From cf6182114501dd3918d15150dc3bf342272184bd Mon Sep 17 00:00:00 2001 From: Martin Messer Date: Fri, 9 Jan 2026 13:16:49 +0100 Subject: [PATCH 01/14] modules: add Nvidia Jetson Nano Boot Module --- modules/default.nix | 1 + modules/platform.nix | 16 ++++++++++++++++ modules/platforms/nvidiaJetsonOrinNano.nix | 19 +++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 modules/platform.nix create mode 100644 modules/platforms/nvidiaJetsonOrinNano.nix diff --git a/modules/default.nix b/modules/default.nix index 5e2178f..1b7dcb1 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -1,4 +1,5 @@ { + platform = import ./platform.nix; profiles = import ./profiles; vms = import ./vms.nix; } diff --git a/modules/platform.nix b/modules/platform.nix new file mode 100644 index 0000000..b0ea86e --- /dev/null +++ b/modules/platform.nix @@ -0,0 +1,16 @@ +{ lib, ... }: +{ + options.ctrl-os.platform = lib.mkOption { + type = + with lib.types; + nullOr (enum [ + "nvidia-jetson-orin-nano" + ]); + description = "The platform, we are running on."; + default = null; + }; + + imports = [ + ./platforms/nvidiaJetsonOrinNano.nix + ]; +} diff --git a/modules/platforms/nvidiaJetsonOrinNano.nix b/modules/platforms/nvidiaJetsonOrinNano.nix new file mode 100644 index 0000000..10c4b6e --- /dev/null +++ b/modules/platforms/nvidiaJetsonOrinNano.nix @@ -0,0 +1,19 @@ +{ config, lib, ... }: +let + platform = config.ctrl-os.platform; +in +{ + config = lib.mkIf (platform == "nvidia-jetson-orin-nano") { + + nixpkgs.hostPlatform = "aarch64-linux"; + + boot.initrd.availableKernelModules = [ + # Enable PCIe support at boot time + "phy_tegra194_p2u" + "pcie_tegra194" + # Enable USB support for USB Boot + "xhci-tegra" + "phy-tegra-xusb" + ]; + }; +} From 4cb2aed7371d7b4fce84742e57345f69385aa435 Mon Sep 17 00:00:00 2001 From: Martin Messer Date: Fri, 9 Jan 2026 13:19:11 +0100 Subject: [PATCH 02/14] packages: add packages definition and NVidia Jetson Orin installer --- packages/flakeModule.nix | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/packages/flakeModule.nix b/packages/flakeModule.nix index 64ed189..31fbe93 100644 --- a/packages/flakeModule.nix +++ b/packages/flakeModule.nix @@ -1,4 +1,9 @@ -{ withSystem, inputs, ... }: +{ + withSystem, + inputs, + self, + ... +}: { } // inputs.nixpkgs.lib.optionalAttrs @@ -18,8 +23,30 @@ }; perSystem = - { pkgs, ... }: + { pkgs, system, ... }: { - packages = import ./default.nix { inherit pkgs; }; + packages = (import ./default.nix { inherit pkgs; }) // { + jetsonOrinNanoInstaller = + (inputs.nixpkgs.lib.nixosSystem { + modules = [ + ( + { modulesPath, ... }: + { + imports = [ + "${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix" + self.nixosModules.platform + self.nixosModules.profiles + ]; + + ctrl-os.profiles.developer.enable = true; + ctrl-os.platform = "nvidia-jetson-orin-nano"; + nixpkgs.hostPlatform = "aarch64-linux"; + nixpkgs.buildPlatform = system; + system.stateVersion = "25.11"; + } + ) + ]; + }).config.system.build.isoImage; + }; }; } From 1fcaf107667b2af48fd781bc56cb5aed63074639 Mon Sep 17 00:00:00 2001 From: Martin Messer Date: Fri, 9 Jan 2026 14:53:10 +0100 Subject: [PATCH 03/14] flake: update dependencies --- flake.lock | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/flake.lock b/flake.lock index c3832e5..0c359d3 100644 --- a/flake.lock +++ b/flake.lock @@ -3,15 +3,15 @@ "flake-compat": { "flake": false, "locked": { - "lastModified": 1747046372, - "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", - "owner": "edolstra", + "lastModified": 1767039857, + "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=", + "owner": "NixOS", "repo": "flake-compat", - "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885", + "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab", "type": "github" }, "original": { - "owner": "edolstra", + "owner": "NixOS", "repo": "flake-compat", "type": "github" } @@ -21,11 +21,11 @@ "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1762980239, - "narHash": "sha256-8oNVE8TrD19ulHinjaqONf9QWCKK+w4url56cdStMpM=", + "lastModified": 1767609335, + "narHash": "sha256-feveD98mQpptwrAEggBQKJTYbvwwglSbOv53uCfH9PY=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "52a2caecc898d0b46b2b905f058ccc5081f842da", + "rev": "250481aafeb741edfe23d29195671c19b36b6dca", "type": "github" }, "original": { @@ -57,11 +57,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1763421233, - "narHash": "sha256-re7SYzc1gs7069DojQiW90fPjNfCUJ9+RUEplQPqxDs=", - "rev": "89c2b2330e733d6cdb5eae7b899326930c2c0648", + "lastModified": 1767767207, + "narHash": "sha256-LmdqDciUNW4a3tFH539SorGLD/5t8PFOXhEQlIxbtww=", + "rev": "5912c1772a44e31bf1c63c0390b90501e5026886", "type": "tarball", - "url": "https://releases.nixos.org/nixos/unstable/nixos-25.11pre897910.89c2b2330e73/nixexprs.tar.xz" + "url": "https://releases.nixos.org/nixos/unstable/nixos-26.05pre923638.5912c1772a44/nixexprs.tar.xz" }, "original": { "type": "tarball", @@ -70,11 +70,11 @@ }, "nixpkgs-lib": { "locked": { - "lastModified": 1761765539, - "narHash": "sha256-b0yj6kfvO8ApcSE+QmA6mUfu8IYG6/uU28OFn4PaC8M=", + "lastModified": 1765674936, + "narHash": "sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo=", "owner": "nix-community", "repo": "nixpkgs.lib", - "rev": "719359f4562934ae99f5443f20aa06c2ffff91fc", + "rev": "2075416fcb47225d9b68ac469a5c4801a9c4dd85", "type": "github" }, "original": { @@ -92,11 +92,11 @@ ] }, "locked": { - "lastModified": 1763319842, - "narHash": "sha256-YG19IyrTdnVn0l3DvcUYm85u3PaqBt6tI6VvolcuHnA=", + "lastModified": 1767281941, + "narHash": "sha256-6MkqajPICgugsuZ92OMoQcgSHnD6sJHwk8AxvMcIgTE=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "7275fa67fbbb75891c16d9dee7d88e58aea2d761", + "rev": "f0927703b7b1c8d97511c4116eb9b4ec6645a0fa", "type": "github" }, "original": { From b4dace2124ed9403a7c959b5e4fb3380bf772afd Mon Sep 17 00:00:00 2001 From: Martin Messer Date: Fri, 16 Jan 2026 15:18:32 +0100 Subject: [PATCH 04/14] github-workflow: add installer iso build process --- .github/workflows/test.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bab5a4e..4081f6e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -45,6 +45,15 @@ jobs: fi - name: Build the Modules for ${{ matrix.nixOpts.tag }} run: nix -L flake check ${{ matrix.nixOpts.flag }} + - name: Build the NixOS installer for Nvidia Jetson Orin Nano devices + run: nix -L build .#packages.x86_64-linux.jetsonOrinNanoInstaller + - name: Upload the installer as artifact + uses: actions/upload-artifact@v6 + with: + name: nvidia-jetson-orin-nano-nixos-${{ github.sha }} + path: result/iso/nixos-minimal-*.iso + retention-days: 7 + if-no-files-found: error - name: Export Nix Store if: always() run: | From 3d6c785be87064a58288ab1c7340c43339dcf3ad Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Thu, 22 Jan 2026 13:02:49 -0500 Subject: [PATCH 05/14] lib: Init with getVendorsModules and mapDirs Signed-off-by: Samuel Dionne-Riel --- lib/default.nix | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 lib/default.nix diff --git a/lib/default.nix b/lib/default.nix new file mode 100644 index 0000000..64e8ff3 --- /dev/null +++ b/lib/default.nix @@ -0,0 +1,47 @@ +# A `nixpkgs.lib` compatible lib must be provided. +{ lib }: + +let + self = { + /** + Applies the function `fn` on the direct children directories of `dir`. + */ + mapDirs = + fn: dir: + let + dirs = builtins.map (name: fn (dir + "/${name}")) ( + builtins.attrNames (lib.filterAttrs (_name: type: type == "directory") (builtins.readDir dir)) + ); + in + dirs; + + /** + Given a directory where children are structured by vendors and *thing*, + returns an attribute set with combined `"${vendor}-${thing}"` names, + and values representing that subdirectory. + */ + getVendorsModules = + dir: + builtins.listToAttrs ( + builtins.concatLists ( + self.mapDirs ( + vendorDir: + let + vendor = builtins.baseNameOf vendorDir; + in + self.mapDirs ( + thingDir: + let + thing = builtins.baseNameOf thingDir; + in + { + name = "${vendor}-${thing}"; + value = thingDir; + } + ) vendorDir + ) dir + ) + ); + }; +in +self From 912e2b26fce638751b4d0b50e3ee3fcfd76deaf7 Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Thu, 22 Jan 2026 12:48:53 -0500 Subject: [PATCH 06/14] treewide: Fix jetson-orin-nano-super name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The device name (even though the vendor does not seem to always spell it out), includes “Super”. I'm using the fact that the innate DeviceTree for the platform uses the model name: ``` NVIDIA Jetson Orin Nano Engineering Reference Developer Kit Super ``` The `compatible` is `nvidia,p3768-0000+p3767-0005-super`. For this reason, we shall always use “super”. Signed-off-by: Samuel Dionne-Riel --- modules/platform.nix | 4 ++-- .../nvidia/jetson-orin-nano-super/default.nix} | 2 +- packages/flakeModule.nix | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename modules/platforms/{nvidiaJetsonOrinNano.nix => devices/nvidia/jetson-orin-nano-super/default.nix} (83%) diff --git a/modules/platform.nix b/modules/platform.nix index b0ea86e..0779e9b 100644 --- a/modules/platform.nix +++ b/modules/platform.nix @@ -4,13 +4,13 @@ type = with lib.types; nullOr (enum [ - "nvidia-jetson-orin-nano" + "nvidia-jetson-orin-nano-super" ]); description = "The platform, we are running on."; default = null; }; imports = [ - ./platforms/nvidiaJetsonOrinNano.nix + ./platforms/devices/nvidia/jetson-orin-nano-super/default.nix ]; } diff --git a/modules/platforms/nvidiaJetsonOrinNano.nix b/modules/platforms/devices/nvidia/jetson-orin-nano-super/default.nix similarity index 83% rename from modules/platforms/nvidiaJetsonOrinNano.nix rename to modules/platforms/devices/nvidia/jetson-orin-nano-super/default.nix index 10c4b6e..3585579 100644 --- a/modules/platforms/nvidiaJetsonOrinNano.nix +++ b/modules/platforms/devices/nvidia/jetson-orin-nano-super/default.nix @@ -3,7 +3,7 @@ let platform = config.ctrl-os.platform; in { - config = lib.mkIf (platform == "nvidia-jetson-orin-nano") { + config = lib.mkIf (platform == "nvidia-jetson-orin-nano-super") { nixpkgs.hostPlatform = "aarch64-linux"; diff --git a/packages/flakeModule.nix b/packages/flakeModule.nix index 31fbe93..aa4c945 100644 --- a/packages/flakeModule.nix +++ b/packages/flakeModule.nix @@ -39,7 +39,7 @@ ]; ctrl-os.profiles.developer.enable = true; - ctrl-os.platform = "nvidia-jetson-orin-nano"; + ctrl-os.platform = "nvidia-jetson-orin-nano-super"; nixpkgs.hostPlatform = "aarch64-linux"; nixpkgs.buildPlatform = system; system.stateVersion = "25.11"; From 2e1c8f7c5cb27369b815cb3636a25df24f7546c3 Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Thu, 22 Jan 2026 12:51:20 -0500 Subject: [PATCH 07/14] modules/platform: Make generic and self-describing via structure Signed-off-by: Samuel Dionne-Riel --- modules/platform.nix | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/modules/platform.nix b/modules/platform.nix index 0779e9b..4f6cf84 100644 --- a/modules/platform.nix +++ b/modules/platform.nix @@ -1,16 +1,20 @@ { lib, ... }: + +let + inherit + (import ../lib { inherit lib; }) + getVendorsModules + ; + deviceModules = getVendorsModules ./platforms/devices; + devices = builtins.attrNames deviceModules; + deviceDirs = builtins.attrValues deviceModules; +in { options.ctrl-os.platform = lib.mkOption { - type = - with lib.types; - nullOr (enum [ - "nvidia-jetson-orin-nano-super" - ]); + type = with lib.types; nullOr (enum devices); description = "The platform, we are running on."; default = null; }; - imports = [ - ./platforms/devices/nvidia/jetson-orin-nano-super/default.nix - ]; + imports = deviceDirs; } From 68f22b8ccc6ed010887b5a1a9d61495bdb5eb782 Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Thu, 22 Jan 2026 18:46:28 -0500 Subject: [PATCH 08/14] modules/platform: Make platform module handle gating off modules This will ensure the `mkIf` conditional is always *coherent* with what it should be. Otherwise, copy/paste mistakes can become awkward to debug. Signed-off-by: Samuel Dionne-Riel --- modules/platform.nix | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/modules/platform.nix b/modules/platform.nix index 4f6cf84..58aa408 100644 --- a/modules/platform.nix +++ b/modules/platform.nix @@ -1,13 +1,13 @@ -{ lib, ... }: +{ config, lib, ... }@moduleArgs: let + platform = config.ctrl-os.platform; inherit (import ../lib { inherit lib; }) getVendorsModules ; deviceModules = getVendorsModules ./platforms/devices; devices = builtins.attrNames deviceModules; - deviceDirs = builtins.attrValues deviceModules; in { options.ctrl-os.platform = lib.mkOption { @@ -16,5 +16,35 @@ in default = null; }; - imports = deviceDirs; + imports = + builtins.attrValues + ( + builtins.mapAttrs + ( + device: dir: + let + cfgOrFn = import dir; + appliedConfig = + let config = cfgOrFn moduleArgs; in + if config ? config then + config + else + { inherit config; } + ; + cond = lib.mkIf (platform == device); + in + if builtins.isAttrs cfgOrFn then + { + config = cond ( + cfgOrFn + ); + } + else + appliedConfig // { + config = cond appliedConfig.config; + } + ) + deviceModules + ) + ; } From e787cbeb67742578e290a59cbbe1d41b0f5ff74b Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Thu, 22 Jan 2026 19:58:51 -0500 Subject: [PATCH 09/14] devices/nvidia/jetson-orin-nano-super: Remove gating from module Signed-off-by: Samuel Dionne-Riel --- .../nvidia/jetson-orin-nano-super/default.nix | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/modules/platforms/devices/nvidia/jetson-orin-nano-super/default.nix b/modules/platforms/devices/nvidia/jetson-orin-nano-super/default.nix index 3585579..8a00138 100644 --- a/modules/platforms/devices/nvidia/jetson-orin-nano-super/default.nix +++ b/modules/platforms/devices/nvidia/jetson-orin-nano-super/default.nix @@ -1,19 +1,14 @@ -{ config, lib, ... }: -let - platform = config.ctrl-os.platform; -in -{ - config = lib.mkIf (platform == "nvidia-jetson-orin-nano-super") { +{ lib, ... }: - nixpkgs.hostPlatform = "aarch64-linux"; +{ + nixpkgs.hostPlatform = "aarch64-linux"; - boot.initrd.availableKernelModules = [ - # Enable PCIe support at boot time - "phy_tegra194_p2u" - "pcie_tegra194" - # Enable USB support for USB Boot - "xhci-tegra" - "phy-tegra-xusb" - ]; - }; + boot.initrd.availableKernelModules = [ + # Enable PCIe support at boot time + "phy_tegra194_p2u" + "pcie_tegra194" + # Enable USB support for USB Boot + "xhci-tegra" + "phy-tegra-xusb" + ]; } From 2c0005770a31d3c039f6271473fe11b251b4d39e Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Fri, 23 Jan 2026 11:15:20 -0500 Subject: [PATCH 10/14] hardware: Reorganize modules directory structure This is the first part of a change set that mirrors a commit from Julian. This only *moves* the files and module itself around, the options names are changed in the follow-up commit. Co-authored-by: Julian Stecklina Signed-off-by: Samuel Dionne-Riel --- modules/default.nix | 2 +- modules/hardware/default.nix | 5 +++++ modules/{platform.nix => hardware/devices/default.nix} | 6 +++--- .../devices/nvidia/jetson-orin-nano-super/default.nix | 2 -- 4 files changed, 9 insertions(+), 6 deletions(-) create mode 100644 modules/hardware/default.nix rename modules/{platform.nix => hardware/devices/default.nix} (91%) rename modules/{platforms => hardware}/devices/nvidia/jetson-orin-nano-super/default.nix (94%) diff --git a/modules/default.nix b/modules/default.nix index 1b7dcb1..8f272ac 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -1,5 +1,5 @@ { - platform = import ./platform.nix; + hardware = import ./hardware; profiles = import ./profiles; vms = import ./vms.nix; } diff --git a/modules/hardware/default.nix b/modules/hardware/default.nix new file mode 100644 index 0000000..605f052 --- /dev/null +++ b/modules/hardware/default.nix @@ -0,0 +1,5 @@ +{ + imports = [ + ./devices + ]; +} diff --git a/modules/platform.nix b/modules/hardware/devices/default.nix similarity index 91% rename from modules/platform.nix rename to modules/hardware/devices/default.nix index 58aa408..79a0f89 100644 --- a/modules/platform.nix +++ b/modules/hardware/devices/default.nix @@ -3,10 +3,10 @@ let platform = config.ctrl-os.platform; inherit - (import ../lib { inherit lib; }) + (import ../../../lib { inherit lib; }) getVendorsModules - ; - deviceModules = getVendorsModules ./platforms/devices; + ; + deviceModules = getVendorsModules ./.; devices = builtins.attrNames deviceModules; in { diff --git a/modules/platforms/devices/nvidia/jetson-orin-nano-super/default.nix b/modules/hardware/devices/nvidia/jetson-orin-nano-super/default.nix similarity index 94% rename from modules/platforms/devices/nvidia/jetson-orin-nano-super/default.nix rename to modules/hardware/devices/nvidia/jetson-orin-nano-super/default.nix index 8a00138..a6b0412 100644 --- a/modules/platforms/devices/nvidia/jetson-orin-nano-super/default.nix +++ b/modules/hardware/devices/nvidia/jetson-orin-nano-super/default.nix @@ -1,5 +1,3 @@ -{ lib, ... }: - { nixpkgs.hostPlatform = "aarch64-linux"; From c694acf57fd0db77f56b4f44755639aa3abf8d4d Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Fri, 23 Jan 2026 11:24:36 -0500 Subject: [PATCH 11/14] hardware: Reorganize options structure This is the final part of a change set that mirrors a commit from Julian. This one renames the options from platform to hardware devices, better future-proofing the options. This also has the benefit of not re-using a term (platform) that has an existing meaning with Nixpkgs things (`stdenv.hostPlatform.system`), and should make it less confusing to discuss about. Co-authored-by: Julian Stecklina Signed-off-by: Samuel Dionne-Riel --- modules/hardware/devices/default.nix | 63 ++++++++++++---------------- 1 file changed, 27 insertions(+), 36 deletions(-) diff --git a/modules/hardware/devices/default.nix b/modules/hardware/devices/default.nix index 79a0f89..9edd234 100644 --- a/modules/hardware/devices/default.nix +++ b/modules/hardware/devices/default.nix @@ -1,50 +1,41 @@ { config, lib, ... }@moduleArgs: let - platform = config.ctrl-os.platform; - inherit - (import ../../../lib { inherit lib; }) + cfg = config.ctrl-os.hardware; + inherit (import ../../../lib { inherit lib; }) getVendorsModules ; deviceModules = getVendorsModules ./.; devices = builtins.attrNames deviceModules; in { - options.ctrl-os.platform = lib.mkOption { + options.ctrl-os.hardware.device = lib.mkOption { type = with lib.types; nullOr (enum devices); - description = "The platform, we are running on."; + description = "Selects a hardware device profile to use by device name."; default = null; }; - imports = - builtins.attrValues - ( - builtins.mapAttrs - ( - device: dir: - let - cfgOrFn = import dir; - appliedConfig = - let config = cfgOrFn moduleArgs; in - if config ? config then - config - else - { inherit config; } - ; - cond = lib.mkIf (platform == device); - in - if builtins.isAttrs cfgOrFn then - { - config = cond ( - cfgOrFn - ); - } - else - appliedConfig // { - config = cond appliedConfig.config; - } - ) - deviceModules - ) - ; + imports = builtins.attrValues ( + builtins.mapAttrs ( + device: dir: + let + cfgOrFn = import dir; + appliedConfig = + let + config = cfgOrFn moduleArgs; + in + if config ? config then config else { inherit config; }; + cond = lib.mkIf (cfg.device == device); + in + if builtins.isAttrs cfgOrFn then + { + config = cond (cfgOrFn); + } + else + appliedConfig + // { + config = cond appliedConfig.config; + } + ) deviceModules + ); } From 7cd639a9fe90bd57c8a103eb2beff10dc083ee73 Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Sun, 25 Jan 2026 17:24:20 -0500 Subject: [PATCH 12/14] jetsonOrinNanoInstaller: Move to new option structure --- packages/flakeModule.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/flakeModule.nix b/packages/flakeModule.nix index aa4c945..9685532 100644 --- a/packages/flakeModule.nix +++ b/packages/flakeModule.nix @@ -34,12 +34,12 @@ { imports = [ "${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix" - self.nixosModules.platform + self.nixosModules.hardware self.nixosModules.profiles ]; ctrl-os.profiles.developer.enable = true; - ctrl-os.platform = "nvidia-jetson-orin-nano-super"; + ctrl-os.hardware.device = "nvidia-jetson-orin-nano-super"; nixpkgs.hostPlatform = "aarch64-linux"; nixpkgs.buildPlatform = system; system.stateVersion = "25.11"; From c70387358c5f256b91093d5cb0d3094cb6572588 Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Thu, 22 Jan 2026 14:08:28 -0500 Subject: [PATCH 13/14] WIP: packages/hardware: Init hardware device installer outputs This is WIP because this is currently using the `legacyPackages` Flake output attribute, but I believe this is the wrong thing to do. These are not packages, they would not be added to a user's system. The `flakeModule` design seems to break down once you need something that isn't in the "well-known"[sic] outputs of Flakes. --- packages/flakeModule.nix | 5 + packages/hardware/default.nix | 166 ++++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 packages/hardware/default.nix diff --git a/packages/flakeModule.nix b/packages/flakeModule.nix index 9685532..4794802 100644 --- a/packages/flakeModule.nix +++ b/packages/flakeModule.nix @@ -25,6 +25,11 @@ perSystem = { pkgs, system, ... }: { + legacyPackages = { + hardware = import ./hardware { + inherit pkgs self; + }; + }; packages = (import ./default.nix { inherit pkgs; }) // { jetsonOrinNanoInstaller = (inputs.nixpkgs.lib.nixosSystem { diff --git a/packages/hardware/default.nix b/packages/hardware/default.nix new file mode 100644 index 0000000..2fe0285 --- /dev/null +++ b/packages/hardware/default.nix @@ -0,0 +1,166 @@ +{ self, pkgs }: + +let + inherit (pkgs) lib; + inherit (pkgs.stdenv.hostPlatform) system; + + # Evaluate a NixOS configuration without relying on the Flakes entrypoint. + evalConfig = + { + system ? null, + ... + }@config: + (import (pkgs.path + "/nixos/lib/eval-config.nix")) ( + config + // { + inherit system; + } + ); + + # Borrow an arbitrary NixOS eval for evaluating the final `options` with + # our `hardware` module imported. + inherit + (evalConfig { + modules = [ self.nixosModules.hardware ]; + # The system does not matter, we only need to evaluate up to the options. + inherit (pkgs.stdenv.hostPlatform) system; + }) + options + ; + + devices = + # Get the device profile option + options.ctrl-os.hardware.device + # Unwrap the nullOr + .type.functor.payload + # Dig into the `enum` + .elemType.functor.payload + # And get the values + .values; + + # Evaluate the CTRL-OS device modules for the given `device`. + # This returns the output from the `output` attribute path, with the evaluation + # merged into the attribute set. + # By default, `system.build.toplevel` is returned, which is the "system build". + evaluate = + device: + { + modules ? [ ], + config ? { }, + output ? [ + "system" + "build" + "toplevel" + ], + }: + + let + eval = evalConfig { + modules = modules ++ [ + ( + { config, ... }: + { + imports = [ + self.nixosModules.hardware + self.nixosModules.profiles + ]; + + # Enable the device-specific config. + ctrl-os.hardware.device = device; + ctrl-os.profiles.ctrl-os-system.enable = true; + + # Ensure this system build will use cross-compilation if relevant... + nixpkgs.buildPlatform = system; + # ... and tag the system build as such. + system.nixos.tags = [ + ( + if config.nixpkgs.hostPlatform.system == config.nixpkgs.buildPlatform.system then + "native" + else + "cross-from-${config.nixpkgs.buildPlatform.system}" + ) + ]; + } + ) + config + ]; + }; + in + (lib.getAttrFromPath output eval.config) // { inherit eval; }; + + # For a given `device`, evaluate the installer config from `path`, + # relative to the nixpkgs `nixos/modules/installer` path. + # The output is the (guessed) relevant build output. + # As with `evaluate`, the system config is added to the derivation + # attribute set as the `eval` attribute. + evaluateInstaller = + device: path: + let + installer = evaluate device { + config = + { modulesPath, ... }: + { + imports = [ + "${modulesPath}/installer/${path}" + ]; + + # This is only safe to do when generating images!!! + # `stateVersion` should not otherwise be set by an imported modules in a user's config. + system.stateVersion = pkgs.lib.trivial.release; + + # Make the installer generate the necessary configuration bits. + # FIXME: this is incomplete right now as the whole installer tooling doesn't know about + # adding CTRL-OS modules, and has no way to do that in any generic fashion. + system.nixos-generate-config.desktopConfiguration = + let + # Escape string values using JSON, as they are mostly compatible with Nix strings. + e = builtins.toJSON; + in + [ + '' + # + # WARNING: Using `nixos-generate-config` with CTRL-OS hardware modules is experimental. + # + # This generated configuration DOES NOT yet include the CTRL-OS configuration for the platform. + # You will first need to handle importing the CTRL-OS modules in your configuration. + # + /* + imports = [ + ctrl-os.nixosModules.hardware + ctrl-os.nixosModules.profiles + ]; + + ctrl-os.hardware.device = ${e device}; + ctrl-os.profiles.ctrl-os-system.enable = true; + + */ + '' + ]; + }; + }; + inherit (installer.eval.config.system) build; + in + (build.isoImage or build.sdImage + or (builtins.throw "Unable to guess the artifact type for installer path ${builtins.toJSON path}") + ) + // { + inherit (installer) eval; + }; +in +{ + devices.installers = lib.listToAttrs ( + lib.map ( + device: + let + mkInstaller = evaluateInstaller device; + in + { + name = device; + value = { + iso = mkInstaller "cd-dvd/installation-cd-minimal.nix"; + sd-image-new-kernel = mkInstaller "sd-card/sd-image-aarch64-new-kernel-no-zfs-installer.nix"; + }; + } + ) devices + ); +} From e035ec41295d212875c68d6bdd90be035de08815 Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Fri, 23 Jan 2026 11:17:05 -0500 Subject: [PATCH 14/14] flakeModule: Drop now-unneeded installer "packages" Signed-off-by: Samuel Dionne-Riel --- packages/flakeModule.nix | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/packages/flakeModule.nix b/packages/flakeModule.nix index 4794802..1cdf80e 100644 --- a/packages/flakeModule.nix +++ b/packages/flakeModule.nix @@ -23,35 +23,13 @@ }; perSystem = - { pkgs, system, ... }: + { pkgs, ... }: { legacyPackages = { hardware = import ./hardware { inherit pkgs self; }; }; - packages = (import ./default.nix { inherit pkgs; }) // { - jetsonOrinNanoInstaller = - (inputs.nixpkgs.lib.nixosSystem { - modules = [ - ( - { modulesPath, ... }: - { - imports = [ - "${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix" - self.nixosModules.hardware - self.nixosModules.profiles - ]; - - ctrl-os.profiles.developer.enable = true; - ctrl-os.hardware.device = "nvidia-jetson-orin-nano-super"; - nixpkgs.hostPlatform = "aarch64-linux"; - nixpkgs.buildPlatform = system; - system.stateVersion = "25.11"; - } - ) - ]; - }).config.system.build.isoImage; - }; + packages = import ./default.nix { inherit pkgs; }; }; }