From cb8f383995a98768f53194361bc88506ee07c73e Mon Sep 17 00:00:00 2001 From: Josh Buker Date: Mon, 26 Jan 2026 15:32:14 -0800 Subject: [PATCH 01/12] Add ODroid M1 Based on @KhashayarDanesh's work in #1269, which is also based on the work of @sstent and @povik. Closes #1269 --- README.md | 1 + flake.nix | 1 + hardkernel/odroid-m1/default.nix | 31 ++++++++ hardkernel/odroid-m1/kboot-conf/default.nix | 73 ++++++++++++++++++ .../kboot-conf/generate-kboot-conf.sh | 76 +++++++++++++++++++ 5 files changed, 182 insertions(+) create mode 100644 hardkernel/odroid-m1/default.nix create mode 100644 hardkernel/odroid-m1/kboot-conf/default.nix create mode 100644 hardkernel/odroid-m1/kboot-conf/generate-kboot-conf.sh diff --git a/README.md b/README.md index 4c9bcb8..4f7d2e2 100644 --- a/README.md +++ b/README.md @@ -400,6 +400,7 @@ See code for all available configurations. | [Hardkernel Odroid HC4](hardkernel/odroid-hc4/default.nix) | `` | `hardkernel-odroid-hc4` | | [Hardkernel Odroid H3](hardkernel/odroid-h3/default.nix) | `` | `hardkernel-odroid-h3` | | [Hardkernel Odroid H4](hardkernel/odroid-h4/default.nix) | `` | `hardkernel-odroid-h4` | +| [Hardkernel Odroid M1](hardkernel/odroid-m1/default.nix) | `` | `hardkernel-odroid-m1` | | [Olimex TERES-I](olimex/teres_i) | `` | `olimex-teres_i` | | [Omen 14-fb0798ng](omen/14-fb0798ng) | `` | `omen-14-fb0798ng` | | [Omen 15-ce002ns](omen/15-ce002ns) | `` | `omen-15-ce002ns` | diff --git a/flake.nix b/flake.nix index eade087..46f0e54 100644 --- a/flake.nix +++ b/flake.nix @@ -374,6 +374,7 @@ hardkernel-odroid-hc4 = import ./hardkernel/odroid-hc4; hardkernel-odroid-h3 = import ./hardkernel/odroid-h3; hardkernel-odroid-h4 = import ./hardkernel/odroid-h4; + hardkernel-odroid-m1 = import ./hardkernel/odroid-m1; omen-14-fb0798ng = import ./omen/14-fb0798ng; omen-15-ce002ns = import ./omen/15-ce002ns; omen-15-en0010ca = import ./omen/15-en0010ca; diff --git a/hardkernel/odroid-m1/default.nix b/hardkernel/odroid-m1/default.nix new file mode 100644 index 0000000..067c50a --- /dev/null +++ b/hardkernel/odroid-m1/default.nix @@ -0,0 +1,31 @@ +# Based on kboot-conf by original authors povik and sstent. +# I'm just porting things over. the original work can be viewed at: +# https://github.com/sstent/nixos-on-odroid-m1 +# https://github.com/povik/nixos-on-odroid-n2 +{ config, pkgs, lib, ... }: + +{ + imports = [ + ./kboot-conf + ]; + + #boot.loader.grub.enable = false; + boot.loader.kboot-conf.enable = true; + # Use kernel >6.6 The devicetree is missing from kernel versions older than this. + boot.kernelPackages = lib.mkIf (lib.versionOlder pkgs.linux.version "6.6") (lib.mkDefault pkgs.linuxPackages_latest); + boot.supportedFilesystems = lib.mkForce ["btrfs" "cifs" "f2fs" "jfs" "ntfs" "reiserfs" "vfat" "xfs"]; + # I'm not completely sure if some of these could be omitted, + # but want to make sure disk access works + boot.initrd.availableKernelModules = [ + "nvme" + "nvme-core" + "phy-rockchip-naneng-combphy" + "phy-rockchip-snps-pcie3" + ]; + + # Petitboot uses this port and baud rate on the boards serial port, + # it's probably good to keep the options same for the running + # kernel for serial console access to work well + boot.kernelParams = ["console=ttyS2,1500000"]; + hardware.deviceTree.name = "rockchip/rk3568-odroid-m1.dtb"; +} diff --git a/hardkernel/odroid-m1/kboot-conf/default.nix b/hardkernel/odroid-m1/kboot-conf/default.nix new file mode 100644 index 0000000..9d714a0 --- /dev/null +++ b/hardkernel/odroid-m1/kboot-conf/default.nix @@ -0,0 +1,73 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.boot.loader.kboot-conf; + + # The builder used to write during system activation + builder = pkgs.replaceVarsWith { + src = ./generate-kboot-conf.sh; + replacements = { + bash = pkgs.bash; + path = lib.makeBinPath [ + pkgs.coreutils + pkgs.gnused + pkgs.gnugrep + ]; + }; + name = "system-activation-generate-kboot-conf"; + isExecutable = true; + }; + # The builder exposed in populateCmd, which runs when building the sdImage + populateBuilder = pkgs.buildPackages.replaceVarsWith { + src = ./generate-kboot-conf.sh; + replacements = { + bash = pkgs.buildPackages.bash; + path = lib.makeBinPath [ + pkgs.buildPackages.coreutils + pkgs.buildPackages.gnused + pkgs.buildPackages.gnugrep + ]; + }; + name = "build-image-generate-kboot-conf"; + isExecutable = true; + }; +in +{ + options = { + boot.loader.kboot-conf = { + enable = lib.mkOption { + default = false; + type = lib.types.bool; + description = '' + Whether to create petitboot-compatible /kboot.conf + ''; + }; + configurationLimit = lib.mkOption { + default = 10; + example = 5; + type = lib.types.int; + description = '' + Maximum number of configurations in the generated kboot.conf. + ''; + }; + populateCmd = lib.mkOption { + type = lib.types.str; + readOnly = true; + description = '' + Contains the builder command used to populate an image, + honoring all options except the -c <path-to-default-configuration> + argument. + Useful to have for sdImage.populateRootCommands + ''; + }; + }; + }; + config = let + args = "-g ${toString cfg.configurationLimit} -n ${config.hardware.deviceTree.name}"; + in + lib.mkIf cfg.enable { + system.build.installBootLoader = lib.mkForce "${builder} ${args} -c"; + system.boot.loader.id = "kboot-conf"; + boot.loader.kboot-conf.populateCmd = "${populateBuilder} ${args}"; + }; +} diff --git a/hardkernel/odroid-m1/kboot-conf/generate-kboot-conf.sh b/hardkernel/odroid-m1/kboot-conf/generate-kboot-conf.sh new file mode 100644 index 0000000..b1f9ad7 --- /dev/null +++ b/hardkernel/odroid-m1/kboot-conf/generate-kboot-conf.sh @@ -0,0 +1,76 @@ +#! @bash@/bin/bash -e + +shopt -s nullglob + +export PATH="/empty:@path@" + +usage() { + echo "usage: $0 -c -n [-g ] [-d ]" >&2 + exit 1 +} + +target=/kboot.conf +default= # Default configuration +numGenerations=0 # Number of other generations to include in the menu + +while getopts "t:c:d:g:n:" opt; do + case "$opt" in + c) default="$OPTARG" ;; + g) numGenerations="$OPTARG" ;; + d) target="$OPTARG" ;; + n) dtbName="$OPTARG" ;; + \?) usage ;; + esac +done + +[ "$default" = "" -o "$dtbName" = "" ] && usage + +tmp=$target.tmp + +# Echo out an kboot.conf menu entry +addEntry() { + local path=$(readlink -f "$1") + local tag="$2" # Generation number or 'default' + + if ! test -e $path/kernel -a -e $path/initrd; then + return + fi + + timestampEpoch=$(stat -L -c '%Z' $path) + timestamp=$(date "+%Y-%m-%d %H:%M" -d @$timestampEpoch) + nixosLabel="$(cat $path/nixos-version)" + extraParams="$(cat $path/kernel-params)" + + local kernel=$(readlink -f "$path/kernel") + local initrd=$(readlink -f "$path/initrd") + local dtbs=$(readlink -f "$path/dtbs") + + local id="nixos-$tag--$nixosLabel" + + if [ "$tag" = "default" ]; then + echo "default=$id" + fi + + echo -n "$id='" + echo -n "$kernel initrd=$initrd dtb=$dtbs/$dtbName " + echo -n "systemConfig=$path init=$path/init $extraParams" + echo "'" +} + +echo "# Auto-generated by generate-kboot-conf.sh, do not edit" > $tmp +addEntry $default default >> $tmp + +if [ "$numGenerations" -gt 0 ]; then + # Add up to $numGenerations generations of the system profile to the menu, + # in reverse (most recent to least recent) order. + for generation in $( + (cd /nix/var/nix/profiles && ls -d system-*-link) \ + | sed 's/system-\([0-9]\+\)-link/\1/' \ + | sort -n -r \ + | head -n $numGenerations); do + link=/nix/var/nix/profiles/system-$generation-link + addEntry $link $generation + done >> $tmp +fi + +mv -f $tmp $target From 1e1205f6f7664cd900d4f3946570a5f9ee979fbc Mon Sep 17 00:00:00 2001 From: Josh Buker Date: Wed, 28 Jan 2026 22:53:01 -0800 Subject: [PATCH 02/12] Rename kboot-conf to petitboot and simplify a few things --- hardkernel/odroid-m1/default.nix | 35 +++++---- hardkernel/odroid-m1/kboot-conf/default.nix | 73 ------------------ hardkernel/odroid-m1/petitboot/default.nix | 75 +++++++++++++++++++ .../install-petitboot.sh} | 2 +- 4 files changed, 96 insertions(+), 89 deletions(-) delete mode 100644 hardkernel/odroid-m1/kboot-conf/default.nix create mode 100644 hardkernel/odroid-m1/petitboot/default.nix rename hardkernel/odroid-m1/{kboot-conf/generate-kboot-conf.sh => petitboot/install-petitboot.sh} (96%) diff --git a/hardkernel/odroid-m1/default.nix b/hardkernel/odroid-m1/default.nix index 067c50a..bde34d4 100644 --- a/hardkernel/odroid-m1/default.nix +++ b/hardkernel/odroid-m1/default.nix @@ -1,31 +1,36 @@ -# Based on kboot-conf by original authors povik and sstent. -# I'm just porting things over. the original work can be viewed at: -# https://github.com/sstent/nixos-on-odroid-m1 -# https://github.com/povik/nixos-on-odroid-n2 { config, pkgs, lib, ... }: { imports = [ - ./kboot-conf + ./petitboot ]; - #boot.loader.grub.enable = false; - boot.loader.kboot-conf.enable = true; + boot.loader.petitboot.enable = lib.mkForce true; + + # Fails to rebuild unless grub is explicitly disabled + boot.loader.grub.enable = lib.mkForce false; + + # TODO: Can this be removed? Presumably anything built with 25.11 / unstable + # or later will be on a kernel >6.6 # Use kernel >6.6 The devicetree is missing from kernel versions older than this. boot.kernelPackages = lib.mkIf (lib.versionOlder pkgs.linux.version "6.6") (lib.mkDefault pkgs.linuxPackages_latest); + + # TODO: Debug why removing this breaks booting from petitboot boot.supportedFilesystems = lib.mkForce ["btrfs" "cifs" "f2fs" "jfs" "ntfs" "reiserfs" "vfat" "xfs"]; - # I'm not completely sure if some of these could be omitted, - # but want to make sure disk access works + + # TODO: Some of these could potentially be omitted, check which ones are + # actually necessary for disk access to function boot.initrd.availableKernelModules = [ + # Only nvme emitted when using nixos-generate-config on my odroid-m1 "nvme" - "nvme-core" - "phy-rockchip-naneng-combphy" - "phy-rockchip-snps-pcie3" + # "nvme-core" + # "phy-rockchip-naneng-combphy" + # "phy-rockchip-snps-pcie3" ]; - # Petitboot uses this port and baud rate on the boards serial port, - # it's probably good to keep the options same for the running - # kernel for serial console access to work well + # Petitboot uses this port and baud rate on the board's serial port. It's + # probably good to keep the options same for the running kernel for serial + # console access to work well. boot.kernelParams = ["console=ttyS2,1500000"]; hardware.deviceTree.name = "rockchip/rk3568-odroid-m1.dtb"; } diff --git a/hardkernel/odroid-m1/kboot-conf/default.nix b/hardkernel/odroid-m1/kboot-conf/default.nix deleted file mode 100644 index 9d714a0..0000000 --- a/hardkernel/odroid-m1/kboot-conf/default.nix +++ /dev/null @@ -1,73 +0,0 @@ -{ config, lib, pkgs, ... }: - -let - cfg = config.boot.loader.kboot-conf; - - # The builder used to write during system activation - builder = pkgs.replaceVarsWith { - src = ./generate-kboot-conf.sh; - replacements = { - bash = pkgs.bash; - path = lib.makeBinPath [ - pkgs.coreutils - pkgs.gnused - pkgs.gnugrep - ]; - }; - name = "system-activation-generate-kboot-conf"; - isExecutable = true; - }; - # The builder exposed in populateCmd, which runs when building the sdImage - populateBuilder = pkgs.buildPackages.replaceVarsWith { - src = ./generate-kboot-conf.sh; - replacements = { - bash = pkgs.buildPackages.bash; - path = lib.makeBinPath [ - pkgs.buildPackages.coreutils - pkgs.buildPackages.gnused - pkgs.buildPackages.gnugrep - ]; - }; - name = "build-image-generate-kboot-conf"; - isExecutable = true; - }; -in -{ - options = { - boot.loader.kboot-conf = { - enable = lib.mkOption { - default = false; - type = lib.types.bool; - description = '' - Whether to create petitboot-compatible /kboot.conf - ''; - }; - configurationLimit = lib.mkOption { - default = 10; - example = 5; - type = lib.types.int; - description = '' - Maximum number of configurations in the generated kboot.conf. - ''; - }; - populateCmd = lib.mkOption { - type = lib.types.str; - readOnly = true; - description = '' - Contains the builder command used to populate an image, - honoring all options except the -c <path-to-default-configuration> - argument. - Useful to have for sdImage.populateRootCommands - ''; - }; - }; - }; - config = let - args = "-g ${toString cfg.configurationLimit} -n ${config.hardware.deviceTree.name}"; - in - lib.mkIf cfg.enable { - system.build.installBootLoader = lib.mkForce "${builder} ${args} -c"; - system.boot.loader.id = "kboot-conf"; - boot.loader.kboot-conf.populateCmd = "${populateBuilder} ${args}"; - }; -} diff --git a/hardkernel/odroid-m1/petitboot/default.nix b/hardkernel/odroid-m1/petitboot/default.nix new file mode 100644 index 0000000..48c395a --- /dev/null +++ b/hardkernel/odroid-m1/petitboot/default.nix @@ -0,0 +1,75 @@ +{ + config, + lib, + pkgs, + ... +}: + +let + cfg = config.boot.loader.petitboot; + args = "-g ${toString cfg.configurationLimit} -n ${config.hardware.deviceTree.name}"; + + # The installer used when running nixos-rebuild switch or similar + installer = pkgs.replaceVarsWith { + src = ./install-petitboot.sh; + replacements = { + bash = pkgs.bash; + path = lib.makeBinPath [ + pkgs.coreutils + pkgs.gnused + pkgs.gnugrep + ]; + }; + name = "install-petitboot"; + isExecutable = true; + }; + # The installer used to write to SD card images + sdImageInstaller = pkgs.buildPackages.replaceVarsWith { + src = ./install-petitboot.sh; + replacements = { + bash = pkgs.buildPackages.bash; + path = lib.makeBinPath [ + pkgs.buildPackages.coreutils + pkgs.buildPackages.gnused + pkgs.buildPackages.gnugrep + ]; + }; + name = "install-petitboot-sd-image"; + isExecutable = true; + }; +in +{ + options = { + boot.loader.petitboot = { + enable = lib.mkOption { + default = false; + type = lib.types.bool; + description = '' + Whether to enable the Petitboot bootloader. + ''; + }; + + configurationLimit = lib.mkOption { + default = 10; + example = 5; + type = lib.types.int; + description = '' + Maximum number of configurations to display when booting. + ''; + }; + }; + }; + + config = lib.mkMerge[ + (lib.mkIf config.boot.loader.petitboot.enable { + system.build.installBootLoader = lib.mkForce "${installer} ${args} -c"; + system.boot.loader.id = "petitboot"; + }) + + (lib.mkIf config.boot.loader.petitboot.enable && options ? sdImage { + sdImage.populateRootCommands = lib.mkForce '' + ${sdImageInstaller} ${args} -c ${config.system.build.toplevel} -d ./files/kboot.conf + '' + }) + ]; +} diff --git a/hardkernel/odroid-m1/kboot-conf/generate-kboot-conf.sh b/hardkernel/odroid-m1/petitboot/install-petitboot.sh similarity index 96% rename from hardkernel/odroid-m1/kboot-conf/generate-kboot-conf.sh rename to hardkernel/odroid-m1/petitboot/install-petitboot.sh index b1f9ad7..86a0011 100644 --- a/hardkernel/odroid-m1/kboot-conf/generate-kboot-conf.sh +++ b/hardkernel/odroid-m1/petitboot/install-petitboot.sh @@ -57,7 +57,7 @@ addEntry() { echo "'" } -echo "# Auto-generated by generate-kboot-conf.sh, do not edit" > $tmp +echo "# Auto-generated by install-petitboot.sh, do not edit or remove" > $tmp addEntry $default default >> $tmp if [ "$numGenerations" -gt 0 ]; then From 8c162f25a7b0f813954d576c88e861d1aaf57de1 Mon Sep 17 00:00:00 2001 From: Josh Buker Date: Wed, 28 Jan 2026 22:56:22 -0800 Subject: [PATCH 03/12] Fix missing parenthesis --- hardkernel/odroid-m1/petitboot/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardkernel/odroid-m1/petitboot/default.nix b/hardkernel/odroid-m1/petitboot/default.nix index 48c395a..38b2f9e 100644 --- a/hardkernel/odroid-m1/petitboot/default.nix +++ b/hardkernel/odroid-m1/petitboot/default.nix @@ -66,7 +66,7 @@ in system.boot.loader.id = "petitboot"; }) - (lib.mkIf config.boot.loader.petitboot.enable && options ? sdImage { + (lib.mkIf (config.boot.loader.petitboot.enable && options ? sdImage) { sdImage.populateRootCommands = lib.mkForce '' ${sdImageInstaller} ${args} -c ${config.system.build.toplevel} -d ./files/kboot.conf '' From a92d980a1865e90e6830f0260d0c8d4a3b80d5c1 Mon Sep 17 00:00:00 2001 From: Josh Buker Date: Wed, 28 Jan 2026 22:57:11 -0800 Subject: [PATCH 04/12] Fix missing curly brace --- hardkernel/odroid-m1/petitboot/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardkernel/odroid-m1/petitboot/default.nix b/hardkernel/odroid-m1/petitboot/default.nix index 38b2f9e..ab37b1f 100644 --- a/hardkernel/odroid-m1/petitboot/default.nix +++ b/hardkernel/odroid-m1/petitboot/default.nix @@ -69,7 +69,7 @@ in (lib.mkIf (config.boot.loader.petitboot.enable && options ? sdImage) { sdImage.populateRootCommands = lib.mkForce '' ${sdImageInstaller} ${args} -c ${config.system.build.toplevel} -d ./files/kboot.conf - '' + ''; }) ]; } From c281bd071aa68dc67abb6e0c6db561362a0edf49 Mon Sep 17 00:00:00 2001 From: Josh Buker Date: Wed, 28 Jan 2026 22:59:36 -0800 Subject: [PATCH 05/12] Try rawdogging sdImage and see if it breaks nixos-rebuild switch --- hardkernel/odroid-m1/petitboot/default.nix | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/hardkernel/odroid-m1/petitboot/default.nix b/hardkernel/odroid-m1/petitboot/default.nix index ab37b1f..38ff43e 100644 --- a/hardkernel/odroid-m1/petitboot/default.nix +++ b/hardkernel/odroid-m1/petitboot/default.nix @@ -60,16 +60,11 @@ in }; }; - config = lib.mkMerge[ - (lib.mkIf config.boot.loader.petitboot.enable { - system.build.installBootLoader = lib.mkForce "${installer} ${args} -c"; - system.boot.loader.id = "petitboot"; - }) - - (lib.mkIf (config.boot.loader.petitboot.enable && options ? sdImage) { - sdImage.populateRootCommands = lib.mkForce '' - ${sdImageInstaller} ${args} -c ${config.system.build.toplevel} -d ./files/kboot.conf - ''; - }) - ]; + config = lib.mkIf config.boot.loader.petitboot.enable { + system.build.installBootLoader = lib.mkForce "${installer} ${args} -c"; + system.boot.loader.id = "petitboot"; + sdImage.populateRootCommands = lib.mkForce '' + ${sdImageInstaller} ${args} -c ${config.system.build.toplevel} -d ./files/kboot.conf + ''; + }; } From d6aea43451f0c381cdb4efdad2328006c1ae459e Mon Sep 17 00:00:00 2001 From: Josh Buker Date: Wed, 28 Jan 2026 23:09:47 -0800 Subject: [PATCH 06/12] Unfortunately, that does break nixos-rebuild switch --- hardkernel/odroid-m1/petitboot/default.nix | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/hardkernel/odroid-m1/petitboot/default.nix b/hardkernel/odroid-m1/petitboot/default.nix index 38ff43e..6de0093 100644 --- a/hardkernel/odroid-m1/petitboot/default.nix +++ b/hardkernel/odroid-m1/petitboot/default.nix @@ -57,14 +57,21 @@ in Maximum number of configurations to display when booting. ''; }; + + populateCmd = lib.mkOption { + type = lib.types.str; + readOnly = true; + description = '' + Contains the script used to populate petitboot when building an image. + Primarily used for sdImage.populateRootCommands. + ''; + }; }; }; - config = lib.mkIf config.boot.loader.petitboot.enable { + config = lib.mkIf cfg.enable { system.build.installBootLoader = lib.mkForce "${installer} ${args} -c"; system.boot.loader.id = "petitboot"; - sdImage.populateRootCommands = lib.mkForce '' - ${sdImageInstaller} ${args} -c ${config.system.build.toplevel} -d ./files/kboot.conf - ''; + cfg.populateCmd = "${sdImageInstaller} ${args}"; }; } From 719a89028dbf07cd432e867bf14810e2b23cb1ce Mon Sep 17 00:00:00 2001 From: Josh Buker Date: Wed, 28 Jan 2026 23:15:11 -0800 Subject: [PATCH 07/12] Apparently aliases are read-only --- hardkernel/odroid-m1/petitboot/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardkernel/odroid-m1/petitboot/default.nix b/hardkernel/odroid-m1/petitboot/default.nix index 6de0093..f4a7535 100644 --- a/hardkernel/odroid-m1/petitboot/default.nix +++ b/hardkernel/odroid-m1/petitboot/default.nix @@ -72,6 +72,6 @@ in config = lib.mkIf cfg.enable { system.build.installBootLoader = lib.mkForce "${installer} ${args} -c"; system.boot.loader.id = "petitboot"; - cfg.populateCmd = "${sdImageInstaller} ${args}"; + boot.loader.petitboot.populateCmd = "${sdImageInstaller} ${args}"; }; } From 53702e58b4c879f395dff190b3a4301dc3104883 Mon Sep 17 00:00:00 2001 From: Josh Buker Date: Wed, 28 Jan 2026 23:18:19 -0800 Subject: [PATCH 08/12] Appease nixfmt --- hardkernel/odroid-m1/default.nix | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/hardkernel/odroid-m1/default.nix b/hardkernel/odroid-m1/default.nix index bde34d4..f5977b5 100644 --- a/hardkernel/odroid-m1/default.nix +++ b/hardkernel/odroid-m1/default.nix @@ -16,7 +16,16 @@ boot.kernelPackages = lib.mkIf (lib.versionOlder pkgs.linux.version "6.6") (lib.mkDefault pkgs.linuxPackages_latest); # TODO: Debug why removing this breaks booting from petitboot - boot.supportedFilesystems = lib.mkForce ["btrfs" "cifs" "f2fs" "jfs" "ntfs" "reiserfs" "vfat" "xfs"]; + boot.supportedFilesystems = lib.mkForce [ + "btrfs" + "cifs" + "f2fs" + "jfs" + "ntfs" + "reiserfs" + "vfat" + "xfs" + ]; # TODO: Some of these could potentially be omitted, check which ones are # actually necessary for disk access to function @@ -31,6 +40,6 @@ # Petitboot uses this port and baud rate on the board's serial port. It's # probably good to keep the options same for the running kernel for serial # console access to work well. - boot.kernelParams = ["console=ttyS2,1500000"]; + boot.kernelParams = [ "console=ttyS2,1500000" ]; hardware.deviceTree.name = "rockchip/rk3568-odroid-m1.dtb"; } From 0cb7e0bcab6946fb42e11dbcffc882af8c25b767 Mon Sep 17 00:00:00 2001 From: Josh Buker Date: Wed, 28 Jan 2026 23:25:11 -0800 Subject: [PATCH 09/12] Try removing kernelPackages and supportedFilesystems overrides --- hardkernel/odroid-m1/default.nix | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/hardkernel/odroid-m1/default.nix b/hardkernel/odroid-m1/default.nix index f5977b5..e055b93 100644 --- a/hardkernel/odroid-m1/default.nix +++ b/hardkernel/odroid-m1/default.nix @@ -13,19 +13,19 @@ # TODO: Can this be removed? Presumably anything built with 25.11 / unstable # or later will be on a kernel >6.6 # Use kernel >6.6 The devicetree is missing from kernel versions older than this. - boot.kernelPackages = lib.mkIf (lib.versionOlder pkgs.linux.version "6.6") (lib.mkDefault pkgs.linuxPackages_latest); + # boot.kernelPackages = lib.mkIf (lib.versionOlder pkgs.linux.version "6.6") (lib.mkDefault pkgs.linuxPackages_latest); # TODO: Debug why removing this breaks booting from petitboot - boot.supportedFilesystems = lib.mkForce [ - "btrfs" - "cifs" - "f2fs" - "jfs" - "ntfs" - "reiserfs" - "vfat" - "xfs" - ]; + # boot.supportedFilesystems = lib.mkForce [ + # "btrfs" + # "cifs" + # "f2fs" + # "jfs" + # "ntfs" + # "reiserfs" + # "vfat" + # "xfs" + # ]; # TODO: Some of these could potentially be omitted, check which ones are # actually necessary for disk access to function From d2907ab4462ee840ac2ddd070f40c48555c2dc2f Mon Sep 17 00:00:00 2001 From: Josh Buker Date: Thu, 29 Jan 2026 00:06:32 -0800 Subject: [PATCH 10/12] Remove unnecessary configuration for odroid-m1 --- hardkernel/odroid-m1/default.nix | 36 ++++++++++---------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/hardkernel/odroid-m1/default.nix b/hardkernel/odroid-m1/default.nix index e055b93..e3db31e 100644 --- a/hardkernel/odroid-m1/default.nix +++ b/hardkernel/odroid-m1/default.nix @@ -1,40 +1,23 @@ -{ config, pkgs, lib, ... }: +{ + config, + pkgs, + lib, + ... +}: { imports = [ ./petitboot ]; + # Enable petitboot support. boot.loader.petitboot.enable = lib.mkForce true; - # Fails to rebuild unless grub is explicitly disabled + # `nixos-rebuild` fails unless grub is explicitly disabled. boot.loader.grub.enable = lib.mkForce false; - # TODO: Can this be removed? Presumably anything built with 25.11 / unstable - # or later will be on a kernel >6.6 - # Use kernel >6.6 The devicetree is missing from kernel versions older than this. - # boot.kernelPackages = lib.mkIf (lib.versionOlder pkgs.linux.version "6.6") (lib.mkDefault pkgs.linuxPackages_latest); - - # TODO: Debug why removing this breaks booting from petitboot - # boot.supportedFilesystems = lib.mkForce [ - # "btrfs" - # "cifs" - # "f2fs" - # "jfs" - # "ntfs" - # "reiserfs" - # "vfat" - # "xfs" - # ]; - - # TODO: Some of these could potentially be omitted, check which ones are - # actually necessary for disk access to function boot.initrd.availableKernelModules = [ - # Only nvme emitted when using nixos-generate-config on my odroid-m1 "nvme" - # "nvme-core" - # "phy-rockchip-naneng-combphy" - # "phy-rockchip-snps-pcie3" ]; # Petitboot uses this port and baud rate on the board's serial port. It's @@ -42,4 +25,7 @@ # console access to work well. boot.kernelParams = [ "console=ttyS2,1500000" ]; hardware.deviceTree.name = "rockchip/rk3568-odroid-m1.dtb"; + # FIXME: The serial terminal does seem to throw random errors still, but that + # doesn't appear to crash anything. May need adjusted if you're + # actually using the GPIO. } From 21deaf7ac994cf87d2a70f8616f8fe846809c2eb Mon Sep 17 00:00:00 2001 From: Josh Buker Date: Mon, 9 Feb 2026 15:51:54 -0800 Subject: [PATCH 11/12] Add README.md to ODroid M1 per feedback --- hardkernel/odroid-m1/README.md | 208 +++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 hardkernel/odroid-m1/README.md diff --git a/hardkernel/odroid-m1/README.md b/hardkernel/odroid-m1/README.md new file mode 100644 index 0000000..e841cfe --- /dev/null +++ b/hardkernel/odroid-m1/README.md @@ -0,0 +1,208 @@ +# ODroid M1 + +Hardware support for the Hardkernel ODroid M1: https://www.hardkernel.com/shop/odroid-m1-with-8gbyte-ram/ + +## Initial Installation + +This is for creating the initial image used to install to the SD Card or NVM Drive. + +Example `flake.nix`: + +```nix +{ + description = "SD Card Image Generator for ODroid M1"; + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + nixos-hardware.url = "github:nixos/nixos-hardware/master"; + }; + outputs = { self, nixpkgs, nixos-hardware }: rec { + nixosConfigurations.m1 = nixpkgs.lib.nixosSystem { + modules = [ + "${nixpkgs}/nixos/modules/installer/sd-card/sd-image-aarch64.nix" + nixos-hardware.nixosModules.hardkernel-odroid-m1 + ./sdimageconfiguration.nix + { + nixpkgs.config.allowUnsupportedSystem = true; + nixpkgs.hostPlatform.system = "aarch64-linux"; + nixpkgs.buildPlatform.system = "x86_64-linux"; # If you build on x86 otherwise change this. + } + ]; + }; + images.m1 = nixosConfigurations.m1.config.system.build.sdImage; + }; +} +``` + +For building the initial sd card image, you can use this example (tweaked for your preferences) `sdimageconfiguration.nix`: + +```nix +{ config, pkgs, lib, ... }: + +{ + system.stateVersion = lib.mkDefault "25.11"; + nixpkgs.hostPlatform.system = "aarch64-linux"; + + sdImage = { + # Skip compression, we'll want the img uncompressed for flashing anyway + compressImage = false; + # The system will not boot if this is missing + populateRootCommands = '' + ${config.boot.loader.petitboot.populateCmd} -c ${config.system.build.toplevel} -d ./files/kboot.conf + ''; + }; + + services.openssh = { + enable = true; + settings = { + # Highly recommended: Set Password Authentication to false if you have authorized keys you can use. This is an insecure default + PasswordAuthentication = true; + PermitRootLogin = "no"; + AllowUsers = [ "odroid" ]; + }; + }; + + # You will almost certainly want Git to pull in your configuration repository + environment.systemPackages = [ + pkgs.git + ]; + + users.users.odroid = { + isNormalUser = true; + description = "Default User"; + extraGroups = [ "networkmanager" "wheel" ]; + packages = []; + # Highly recommended: Change this default password using `sudo passwd` after logging in + initialPassword = lib.mkForce "odroid"; + # You can find this from https://github.com/username.keys for example + openssh.authorizedKeys.keys = []; + }; +} +``` + +Put both of these files into a Git repo, and build with: + +```sh +nix build .#images.m1 +``` + +## Ongoing updates + +To your NixOS server flake, you'll want to ensure that the host is set to aarch64-linux. + +An example flake: + +```nix +{ + description = "My NixOS configuration flake"; + + inputs = { + # Nixpkgs - Stable 25.11 release + nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11"; + # Home Manager - Stable 25.11 release + home-manager.url = "github:nix-community/home-manager/release-25.11"; + home-manager.inputs.nixpkgs.follows = "nixpkgs"; + # NixOS Hardware + nixos-hardware.url = "github:nixos/nixos-hardware/master"; + }; + + outputs = { + self, + nixpkgs, + home-manager, + nixos-hardware, + ... + }@inputs: + + let + mkSystem = hostname: systemArchitecture: # hostname: is a positional argument + nixpkgs.lib.nixosSystem { + system = systemArchitecture; + + specialArgs = { inherit inputs; }; + + modules = [ + ./hosts/${hostname}/configuration.nix + + home-manager.nixosModules.home-manager + { + home-manager.useGlobalPkgs = true; + home-manager.useUserPackages = true; + home-manager.backupFileExtension = "backup"; + } + ]; + }; + + hosts = [ + { hostname = "other-example"; systemArchitecture = "x86_64-linux"; } + { hostname = "odroid-m1-example"; systemArchitecture = "aarch64-linux"; } + ]; + in + { + # This is what creates the NixOS configurations for each host + nixosConfigurations = builtins.listToAttrs ( + # Iterator - nixConfigurations. = + map (host: { + name = host.hostname; + value = mkSystem host.hostname host.systemArchitecture; + }) + # Array to iterate over + hosts + ); + }; +} +``` + +And the related `configuration.nix`: + +```nix +{ config, pkgs, inputs, ... }: + +{ + imports = + [ + inputs.nixos-hardware.nixosModules.hardkernel-odroid-m1 + ./hardware-configuration.nix + ../../modules/nix + ../../users + ]; + + networking.hostName = "odroid-m1-example"; # Define your hostname. +} +``` + +And `hardware-configuration.nix`: + +```nix +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "nvme" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/44444444-4444-4444-8888-888888888888"; + fsType = "ext4"; + }; + + swapDevices = [ ]; + + nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux"; +} +``` + +You can generate these default files (with a few warnings) by running the following command on the odroid after initial boot: + +```sh +nixos-generate-config +``` + +It will save a configuration.nix and hardware-configuration.nix to `/etc/nixos`. Critically, you will need to add `inputs.nixos-hardware.nixosModules.hardkernel-odroid-m1` to the imports in `configuration.nix` for it to work. From 001bac71322e182497ccf2c1d192e8858b8325b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Sun, 15 Feb 2026 16:25:49 +0100 Subject: [PATCH 12/12] odroid-m1: simplify README Remove opinionated configuration that doesn't belong in a hardware module README: home-manager setup, user/SSH configuration, example hardware-configuration.nix, and an overly complex multi-host flake pattern. Keep only the ODroid M1-specific information: how to build the SD card image with the required petitboot populateRootCommands, and how to set up the flake for ongoing nixos-rebuild switch. --- hardkernel/odroid-m1/README.md | 186 +++++++-------------------------- 1 file changed, 39 insertions(+), 147 deletions(-) diff --git a/hardkernel/odroid-m1/README.md b/hardkernel/odroid-m1/README.md index e841cfe..cb94bd9 100644 --- a/hardkernel/odroid-m1/README.md +++ b/hardkernel/odroid-m1/README.md @@ -2,15 +2,13 @@ Hardware support for the Hardkernel ODroid M1: https://www.hardkernel.com/shop/odroid-m1-with-8gbyte-ram/ -## Initial Installation +## Building an SD Card Image -This is for creating the initial image used to install to the SD Card or NVM Drive. - -Example `flake.nix`: +To create an initial SD card image for installation: ```nix +# flake.nix { - description = "SD Card Image Generator for ODroid M1"; inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; nixos-hardware.url = "github:nixos/nixos-hardware/master"; @@ -20,11 +18,11 @@ Example `flake.nix`: modules = [ "${nixpkgs}/nixos/modules/installer/sd-card/sd-image-aarch64.nix" nixos-hardware.nixosModules.hardkernel-odroid-m1 - ./sdimageconfiguration.nix + ./sdimage.nix { - nixpkgs.config.allowUnsupportedSystem = true; nixpkgs.hostPlatform.system = "aarch64-linux"; - nixpkgs.buildPlatform.system = "x86_64-linux"; # If you build on x86 otherwise change this. + # Uncomment if cross-compiling from x86_64: + # nixpkgs.buildPlatform.system = "x86_64-linux"; } ]; }; @@ -33,176 +31,70 @@ Example `flake.nix`: } ``` -For building the initial sd card image, you can use this example (tweaked for your preferences) `sdimageconfiguration.nix`: - ```nix -{ config, pkgs, lib, ... }: - +# sdimage.nix +{ config, ... }: { - system.stateVersion = lib.mkDefault "25.11"; - nixpkgs.hostPlatform.system = "aarch64-linux"; + imports = [ ./common.nix ]; sdImage = { - # Skip compression, we'll want the img uncompressed for flashing anyway compressImage = false; - # The system will not boot if this is missing + # Required for the system to boot populateRootCommands = '' ${config.boot.loader.petitboot.populateCmd} -c ${config.system.build.toplevel} -d ./files/kboot.conf ''; }; +} +``` - services.openssh = { - enable = true; - settings = { - # Highly recommended: Set Password Authentication to false if you have authorized keys you can use. This is an insecure default - PasswordAuthentication = true; - PermitRootLogin = "no"; - AllowUsers = [ "odroid" ]; - }; - }; +```nix +# common.nix +{ pkgs, ... }: +{ + services.openssh.enable = true; - # You will almost certainly want Git to pull in your configuration repository - environment.systemPackages = [ - pkgs.git - ]; + environment.systemPackages = [ pkgs.git ]; users.users.odroid = { isNormalUser = true; - description = "Default User"; - extraGroups = [ "networkmanager" "wheel" ]; - packages = []; - # Highly recommended: Change this default password using `sudo passwd` after logging in - initialPassword = lib.mkForce "odroid"; - # You can find this from https://github.com/username.keys for example - openssh.authorizedKeys.keys = []; + extraGroups = [ "wheel" ]; + initialPassword = "odroid"; + # openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAA..." ]; }; } ``` -Put both of these files into a Git repo, and build with: +Build with: ```sh nix build .#images.m1 ``` -## Ongoing updates +## Ongoing Configuration -To your NixOS server flake, you'll want to ensure that the host is set to aarch64-linux. - -An example flake: +After booting the SD card image, run `nixos-generate-config` to generate +`hardware-configuration.nix` for your system. Then set up your configuration +flake: ```nix +# flake.nix { - description = "My NixOS configuration flake"; - inputs = { - # Nixpkgs - Stable 25.11 release - nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11"; - # Home Manager - Stable 25.11 release - home-manager.url = "github:nix-community/home-manager/release-25.11"; - home-manager.inputs.nixpkgs.follows = "nixpkgs"; - # NixOS Hardware + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; nixos-hardware.url = "github:nixos/nixos-hardware/master"; }; - - outputs = { - self, - nixpkgs, - home-manager, - nixos-hardware, - ... - }@inputs: - - let - mkSystem = hostname: systemArchitecture: # hostname: is a positional argument - nixpkgs.lib.nixosSystem { - system = systemArchitecture; - - specialArgs = { inherit inputs; }; - - modules = [ - ./hosts/${hostname}/configuration.nix - - home-manager.nixosModules.home-manager - { - home-manager.useGlobalPkgs = true; - home-manager.useUserPackages = true; - home-manager.backupFileExtension = "backup"; - } - ]; - }; - - hosts = [ - { hostname = "other-example"; systemArchitecture = "x86_64-linux"; } - { hostname = "odroid-m1-example"; systemArchitecture = "aarch64-linux"; } - ]; - in - { - # This is what creates the NixOS configurations for each host - nixosConfigurations = builtins.listToAttrs ( - # Iterator - nixConfigurations. = - map (host: { - name = host.hostname; - value = mkSystem host.hostname host.systemArchitecture; - }) - # Array to iterate over - hosts - ); + outputs = { nixpkgs, nixos-hardware, ... }: { + nixosConfigurations.m1 = nixpkgs.lib.nixosSystem { + modules = [ + nixos-hardware.nixosModules.hardkernel-odroid-m1 + ./common.nix + ./configuration.nix + ./hardware-configuration.nix + ]; + }; }; } ``` -And the related `configuration.nix`: - -```nix -{ config, pkgs, inputs, ... }: - -{ - imports = - [ - inputs.nixos-hardware.nixosModules.hardkernel-odroid-m1 - ./hardware-configuration.nix - ../../modules/nix - ../../users - ]; - - networking.hostName = "odroid-m1-example"; # Define your hostname. -} -``` - -And `hardware-configuration.nix`: - -```nix -# Do not modify this file! It was generated by ‘nixos-generate-config’ -# and may be overwritten by future invocations. Please make changes -# to /etc/nixos/configuration.nix instead. -{ config, lib, pkgs, modulesPath, ... }: - -{ - imports = - [ (modulesPath + "/installer/scan/not-detected.nix") - ]; - - boot.initrd.availableKernelModules = [ "nvme" ]; - boot.initrd.kernelModules = [ ]; - boot.kernelModules = [ ]; - boot.extraModulePackages = [ ]; - - fileSystems."/" = - { device = "/dev/disk/by-uuid/44444444-4444-4444-8888-888888888888"; - fsType = "ext4"; - }; - - swapDevices = [ ]; - - nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux"; -} -``` - -You can generate these default files (with a few warnings) by running the following command on the odroid after initial boot: - -```sh -nixos-generate-config -``` - -It will save a configuration.nix and hardware-configuration.nix to `/etc/nixos`. Critically, you will need to add `inputs.nixos-hardware.nixosModules.hardkernel-odroid-m1` to the imports in `configuration.nix` for it to work. +The module configures petitboot as the boot loader, so `nixos-rebuild switch` +works as usual.