From 2abf8951efed6294018a4b714ab5aa75be13721b Mon Sep 17 00:00:00 2001 From: Jacob Birkett Date: Sat, 8 Feb 2025 03:10:18 -0800 Subject: [PATCH] nix: format treewide --- flake.nix | 41 ++-- overlays/default.nix | 79 +++----- overlays/libcamera.nix | 14 +- overlays/rpicam-apps.nix | 15 +- rpi/config.nix | 226 +++++++++++---------- rpi/default.nix | 413 ++++++++++++++++++++------------------- sd-image/default.nix | 86 ++++---- sd-image/sd-image.nix | 125 ++++++------ 8 files changed, 493 insertions(+), 506 deletions(-) diff --git a/flake.nix b/flake.nix index 9953c5e..baf554a 100644 --- a/flake.nix +++ b/flake.nix @@ -37,7 +37,8 @@ }; libcamera-src = { flake = false; - url = "github:raspberrypi/libcamera/69a894c4adad524d3063dd027f5c4774485cf9db"; # v0.3.1+rpt20240906 + url = + "github:raspberrypi/libcamera/69a894c4adad524d3063dd027f5c4774485cf9db"; # v0.3.1+rpt20240906 }; libpisp-src = { flake = false; @@ -51,11 +52,11 @@ system = "aarch64-linux"; overlays = with self.overlays; [ core libcamera ]; }; - in - { + in { overlays = { core = import ./overlays (builtins.removeAttrs srcs [ "self" ]); - libcamera = import ./overlays/libcamera.nix (builtins.removeAttrs srcs [ "self" ]); + libcamera = import ./overlays/libcamera.nix + (builtins.removeAttrs srcs [ "self" ]); }; nixosModules = { raspberry-pi = import ./rpi { @@ -68,32 +69,34 @@ nixosConfigurations = { rpi-example = srcs.nixpkgs.lib.nixosSystem { system = "aarch64-linux"; - modules = [ self.nixosModules.raspberry-pi self.nixosModules.sd-image ./example ]; + modules = [ + self.nixosModules.raspberry-pi + self.nixosModules.sd-image + ./example + ]; }; }; checks.aarch64-linux = self.packages.aarch64-linux; packages.aarch64-linux = with pinned.lib; let - kernels = - foldlAttrs f { } pinned.rpi-kernels; + kernels = foldlAttrs f { } pinned.rpi-kernels; f = acc: kernel-version: board-attr-set: - foldlAttrs - (acc: board-version: drv: acc // { + foldlAttrs (acc: board-version: drv: + acc // { "linux-${kernel-version}-${board-version}" = drv; - }) - acc - board-attr-set; - in - { - example-sd-image = self.nixosConfigurations.rpi-example.config.system.build.sdImage; + }) acc board-attr-set; + in { + example-sd-image = + self.nixosConfigurations.rpi-example.config.system.build.sdImage; firmware = pinned.raspberrypifw; libcamera = pinned.libcamera; wireless-firmware = pinned.raspberrypiWirelessFirmware; uboot-rpi-arm64 = pinned.uboot-rpi-arm64; } // kernels; - formatter = - srcs.nixpkgs.lib.genAttrs - [ "aarch64-linux" "aarch64-darwin" "x86_64-linux"] - (system: srcs.nixpkgs.legacyPackages.${system}.nixfmt-classic); + formatter = srcs.nixpkgs.lib.genAttrs [ + "aarch64-linux" + "aarch64-darwin" + "x86_64-linux" + ] (system: srcs.nixpkgs.legacyPackages.${system}.nixfmt-classic); }; } diff --git a/overlays/default.nix b/overlays/default.nix index 1ad69a6..a0dac9d 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -1,12 +1,5 @@ -{ u-boot-src -, rpi-linux-stable-src -, rpi-linux-6_6_67-src -, rpi-linux-6_12_11-src -, rpi-firmware-src -, rpi-firmware-nonfree-src -, rpi-bluez-firmware-src -, ... -}: +{ u-boot-src, rpi-linux-stable-src, rpi-linux-6_6_67-src, rpi-linux-6_12_11-src +, rpi-firmware-src, rpi-firmware-nonfree-src, rpi-bluez-firmware-src, ... }: final: prev: let versions = { @@ -14,15 +7,14 @@ let v6_6_67.src = rpi-linux-6_6_67-src; v6_12_11 = { src = rpi-linux-6_12_11-src; - patches = [ - { - name = "remove-readme-target.patch"; - patch = final.fetchpatch { - url = "https://github.com/raspberrypi/linux/commit/3c0fd51d184f1748b83d28e1113265425c19bcb5.patch"; - hash = "sha256-v7uZOmPCUp2i7NGVgjqnQYe6dEBD+aATuP/oRs9jfuk="; - }; - } - ]; + patches = [{ + name = "remove-readme-target.patch"; + patch = final.fetchpatch { + url = + "https://github.com/raspberrypi/linux/commit/3c0fd51d184f1748b83d28e1113265425c19bcb5.patch"; + hash = "sha256-v7uZOmPCUp2i7NGVgjqnQYe6dEBD+aATuP/oRs9jfuk="; + }; + }]; }; }; boards = [ "bcm2711" "bcm2712" ]; @@ -32,8 +24,7 @@ let let kernel = builtins.getAttr version versions; version-slug = builtins.replaceStrings [ "v" "_" ] [ "" "." ] version; - in - { + in { "${version}"."${board}" = (final.buildLinux { modDirVersion = version-slug; version = version-slug; @@ -61,22 +52,18 @@ let KUNIT = no; }; features.efiBootStub = false; - kernelPatches = - if kernel ? "patches" then kernel.patches else [ ]; - }).overrideAttrs - (oldAttrs: { - postConfigure = '' - # The v7 defconfig has this set to '-v7' which screws up our modDirVersion. - sed -i $buildRoot/.config -e 's/^CONFIG_LOCALVERSION=.*/CONFIG_LOCALVERSION=""/' - sed -i $buildRoot/include/config/auto.conf -e 's/^CONFIG_LOCALVERSION=.*/CONFIG_LOCALVERSION=""/' - ''; - }); + kernelPatches = if kernel ? "patches" then kernel.patches else [ ]; + }).overrideAttrs (oldAttrs: { + postConfigure = '' + # The v7 defconfig has this set to '-v7' which screws up our modDirVersion. + sed -i $buildRoot/.config -e 's/^CONFIG_LOCALVERSION=.*/CONFIG_LOCALVERSION=""/' + sed -i $buildRoot/include/config/auto.conf -e 's/^CONFIG_LOCALVERSION=.*/CONFIG_LOCALVERSION=""/' + ''; + }); }; - rpi-kernels = builtins.foldl' - (b: a: final.lib.recursiveUpdate b (rpi-kernel a)) - { }; -in -{ + rpi-kernels = + builtins.foldl' (b: a: final.lib.recursiveUpdate b (rpi-kernel a)) { }; +in { # disable firmware compression so that brcm firmware can be found at # the path expected by raspberry pi firmware/device tree compressFirmwareXz = x: x; @@ -105,22 +92,20 @@ in # default to latest firmware raspberrypiWirelessFirmware = final.callPackage - ( - import ./raspberrypi-wireless-firmware.nix { - bluez-firmware = rpi-bluez-firmware-src; - firmware-nonfree = rpi-firmware-nonfree-src; - } - ) - { }; - raspberrypifw = prev.raspberrypifw.overrideAttrs (oldfw: { src = rpi-firmware-src; }); + (import ./raspberrypi-wireless-firmware.nix { + bluez-firmware = rpi-bluez-firmware-src; + firmware-nonfree = rpi-firmware-nonfree-src; + }) { }; + raspberrypifw = + prev.raspberrypifw.overrideAttrs (oldfw: { src = rpi-firmware-src; }); } // { # rpi kernels and firmware are available at # `pkgs.rpi-kernels..'. # # For example: `pkgs.rpi-kernels.v6_6_67.bcm2712' - rpi-kernels = rpi-kernels ( - final.lib.cartesianProduct - { board = boards; version = (builtins.attrNames versions); } - ); + rpi-kernels = rpi-kernels (final.lib.cartesianProduct { + board = boards; + version = (builtins.attrNames versions); + }); } diff --git a/overlays/libcamera.nix b/overlays/libcamera.nix index 878fb28..3c72680 100644 --- a/overlays/libcamera.nix +++ b/overlays/libcamera.nix @@ -1,8 +1,4 @@ -{ rpicam-apps-src -, libcamera-src -, libpisp-src -, ... -}: +{ rpicam-apps-src, libcamera-src, libpisp-src, ... }: final: prev: { # A recent known working version of rpicam-apps libcamera-apps = @@ -27,12 +23,8 @@ final: prev: { libpisp openssl libtiff - (python3.withPackages (ps: with ps; [ - python3-gnutls - pybind11 - pyyaml - ply - ])) + (python3.withPackages + (ps: with ps; [ python3-gnutls pybind11 pyyaml ply ])) libglibutil gst_all_1.gst-plugins-base ]); diff --git a/overlays/rpicam-apps.nix b/overlays/rpicam-apps.nix index 13e3d2d..7ffa609 100644 --- a/overlays/rpicam-apps.nix +++ b/overlays/rpicam-apps.nix @@ -1,4 +1,4 @@ -{ rpicam-apps-src, lib, pkgs, stdenv }: +{ rpicam-apps-src, lib, pkgs, stdenv, }: stdenv.mkDerivation { pname = "libcamera-apps"; @@ -7,7 +7,18 @@ stdenv.mkDerivation { src = rpicam-apps-src; nativeBuildInputs = with pkgs; [ meson pkg-config ]; - buildInputs = with pkgs; [ libjpeg libtiff libcamera libepoxy boost libexif libpng ffmpeg libdrm ninja ]; + buildInputs = with pkgs; [ + libjpeg + libtiff + libcamera + libepoxy + boost + libexif + libpng + ffmpeg + libdrm + ninja + ]; mesonFlags = [ "-Denable_qt=disabled" "-Denable_opencv=disabled" diff --git a/rpi/config.nix b/rpi/config.nix index f48ba60..0d8a5f4 100644 --- a/rpi/config.nix +++ b/rpi/config.nix @@ -1,128 +1,121 @@ { lib, config, pkgs, ... }: let cfg = config.hardware.raspberry-pi; - render-raspberrypi-config = - let - render-options = opts: - lib.strings.concatStringsSep "\n" (render-dt-kvs opts); - render-dt-param = x: "dtparam=" + x; - render-dt-kv = k: v: - if isNull v.value then - k - else - let vstr = toString v.value; in "${k}=${vstr}"; - render-dt-kvs = x: - lib.attrsets.mapAttrsToList render-dt-kv - (lib.filterAttrs (k: v: v.enable) x); - render-dt-overlay = { overlay, args }: - "dtoverlay=" + overlay + "\n" - + lib.strings.concatMapStringsSep "\n" render-dt-param args + "\n" - + "dtoverlay="; - render-base-dt-params = params: - lib.strings.concatMapStringsSep "\n" render-dt-param - (render-dt-kvs params); - render-dt-overlays = overlays: - lib.strings.concatMapStringsSep "\n" render-dt-overlay - (lib.attrsets.mapAttrsToList - (k: v: { - overlay = k; - args = render-dt-kvs v.params; - }) - (lib.filterAttrs (k: v: v.enable) overlays)); - render-config-section = k: - { options, base-dt-params, dt-overlays }: - let - all-config = lib.concatStringsSep "\n" (lib.filter (x: x != "") [ - (render-options options) - (render-base-dt-params base-dt-params) - (render-dt-overlays dt-overlays) - ]); - in - '' - [${k}] - ${all-config} - ''; - in - conf: - lib.strings.concatStringsSep "\n" - (lib.attrsets.mapAttrsToList render-config-section conf); -in -{ + render-raspberrypi-config = let + render-options = opts: + lib.strings.concatStringsSep "\n" (render-dt-kvs opts); + render-dt-param = x: "dtparam=" + x; + render-dt-kv = k: v: + if isNull v.value then + k + else + let vstr = toString v.value; in "${k}=${vstr}"; + render-dt-kvs = x: + lib.attrsets.mapAttrsToList render-dt-kv + (lib.filterAttrs (k: v: v.enable) x); + render-dt-overlay = { overlay, args }: + "dtoverlay=" + overlay + "\n" + + lib.strings.concatMapStringsSep "\n" render-dt-param args + "\n" + + "dtoverlay="; + render-base-dt-params = params: + lib.strings.concatMapStringsSep "\n" render-dt-param + (render-dt-kvs params); + render-dt-overlays = overlays: + lib.strings.concatMapStringsSep "\n" render-dt-overlay + (lib.attrsets.mapAttrsToList (k: v: { + overlay = k; + args = render-dt-kvs v.params; + }) (lib.filterAttrs (k: v: v.enable) overlays)); + render-config-section = k: + { options, base-dt-params, dt-overlays, }: + let + all-config = lib.concatStringsSep "\n" (lib.filter (x: x != "") [ + (render-options options) + (render-base-dt-params base-dt-params) + (render-dt-overlays dt-overlays) + ]); + in '' + [${k}] + ${all-config} + ''; + in conf: + lib.strings.concatStringsSep "\n" + (lib.attrsets.mapAttrsToList render-config-section conf); +in { options = { hardware.raspberry-pi = { - config = - let - rpi-config-param = { - options = { - enable = lib.mkEnableOption "attr"; - value = - lib.mkOption { type = with lib.types; oneOf [ int str bool ]; }; - }; + config = let + rpi-config-param = { + options = { + enable = lib.mkEnableOption "attr"; + value = + lib.mkOption { type = with lib.types; oneOf [ int str bool ]; }; }; - dt-param = { - options = { - enable = lib.mkEnableOption "attr"; - value = lib.mkOption { - type = with lib.types; nullOr (oneOf [ int str bool ]); - default = null; - }; - }; - }; - dt-overlay = { - options = { - enable = lib.mkEnableOption "overlay"; - params = lib.mkOption { - type = with lib.types; attrsOf (submodule dt-param); - }; - }; - }; - raspberry-pi-config-options = { - options = { - options = lib.mkOption { - type = with lib.types; attrsOf (submodule rpi-config-param); - default = { }; - example = { - enable_gic = { - enable = true; - value = true; - }; - arm_boost = { - enable = true; - value = true; - }; - }; - }; - base-dt-params = lib.mkOption { - type = with lib.types; attrsOf (submodule dt-param); - default = { }; - example = { - i2c = { - enable = true; - value = "on"; - }; - audio = { - enable = true; - value = "on"; - }; - }; - description = "parameters to pass to the base dtb"; - }; - dt-overlays = lib.mkOption { - type = with lib.types; attrsOf (submodule dt-overlay); - default = { }; - example = { vc4-kms-v3d = { cma-256 = { enable = true; }; }; }; - description = "dtb overlays to apply"; - }; - }; - }; - in - lib.mkOption { - type = with lib.types; attrsOf (submodule raspberry-pi-config-options); }; + dt-param = { + options = { + enable = lib.mkEnableOption "attr"; + value = lib.mkOption { + type = with lib.types; nullOr (oneOf [ int str bool ]); + default = null; + }; + }; + }; + dt-overlay = { + options = { + enable = lib.mkEnableOption "overlay"; + params = lib.mkOption { + type = with lib.types; attrsOf (submodule dt-param); + }; + }; + }; + raspberry-pi-config-options = { + options = { + options = lib.mkOption { + type = with lib.types; attrsOf (submodule rpi-config-param); + default = { }; + example = { + enable_gic = { + enable = true; + value = true; + }; + arm_boost = { + enable = true; + value = true; + }; + }; + }; + base-dt-params = lib.mkOption { + type = with lib.types; attrsOf (submodule dt-param); + default = { }; + example = { + i2c = { + enable = true; + value = "on"; + }; + audio = { + enable = true; + value = "on"; + }; + }; + description = "parameters to pass to the base dtb"; + }; + dt-overlays = lib.mkOption { + type = with lib.types; attrsOf (submodule dt-overlay); + default = { }; + example = { vc4-kms-v3d = { cma-256 = { enable = true; }; }; }; + description = "dtb overlays to apply"; + }; + }; + }; + in lib.mkOption { + type = with lib.types; attrsOf (submodule raspberry-pi-config-options); + }; config-generated = lib.mkOption { type = lib.types.str; - description = "the config text generated by raspberrypi.hardware.config"; + description = + "the config text generated by raspberrypi.hardware.config"; readOnly = true; }; @@ -139,6 +132,7 @@ in }; }; config = { - hardware.raspberry-pi.config-generated = render-raspberrypi-config cfg.config; + hardware.raspberry-pi.config-generated = + render-raspberrypi-config cfg.config; }; } diff --git a/rpi/default.nix b/rpi/default.nix index dc207eb..2ccb58a 100644 --- a/rpi/default.nix +++ b/rpi/default.nix @@ -1,4 +1,4 @@ -{ pinned, core-overlay, libcamera-overlay }: +{ pinned, core-overlay, libcamera-overlay, }: { lib, pkgs, config, ... }: let @@ -6,9 +6,9 @@ let version = cfg.kernel-version; board = cfg.board; kernel = config.system.build.kernel; - initrd = "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}"; -in -{ + initrd = + "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}"; +in { imports = [ ./config.nix ./i2c.nix ]; options = with lib; { @@ -82,146 +82,148 @@ in config = { systemd.services = { - "raspberry-pi-firmware-migrate" = - { - description = "update the firmware partition"; - wantedBy = if cfg.firmware-migration-service.enable then [ "multi-user.target" ] else [ ]; - serviceConfig = - let - firmware-path = "/boot/firmware"; - kernel-params = pkgs.writeTextFile { - name = "cmdline.txt"; - text = '' - ${lib.strings.concatStringsSep " " config.boot.kernelParams} - ''; - }; - in - { - Type = "oneshot"; - MountImages = - "/dev/disk/by-label/${cfg.firmware-partition-label}:${firmware-path}"; - StateDirectory = "raspberrypi-firmware"; - ExecStart = pkgs.writeShellScript "migrate-rpi-firmware" '' - shopt -s nullglob + "raspberry-pi-firmware-migrate" = { + description = "update the firmware partition"; + wantedBy = if cfg.firmware-migration-service.enable then + [ "multi-user.target" ] + else + [ ]; + serviceConfig = let + firmware-path = "/boot/firmware"; + kernel-params = pkgs.writeTextFile { + name = "cmdline.txt"; + text = '' + ${lib.strings.concatStringsSep " " config.boot.kernelParams} + ''; + }; + in { + Type = "oneshot"; + MountImages = + "/dev/disk/by-label/${cfg.firmware-partition-label}:${firmware-path}"; + StateDirectory = "raspberrypi-firmware"; + ExecStart = pkgs.writeShellScript "migrate-rpi-firmware" '' + shopt -s nullglob - TARGET_FIRMWARE_DIR="${firmware-path}" - TARGET_OVERLAYS_DIR="$TARGET_FIRMWARE_DIR/overlays" - TMPFILE="$TARGET_FIRMWARE_DIR/tmp" - KERNEL="${kernel}/${config.system.boot.loader.kernelFile}" - SHOULD_UBOOT=${if cfg.uboot.enable then "1" else "0"} - SRC_FIRMWARE_DIR="${pkgs.raspberrypifw}/share/raspberrypi/boot" - STARTFILES=("$SRC_FIRMWARE_DIR"/start*.elf) - DTBS=("$SRC_FIRMWARE_DIR"/*.dtb) - BOOTCODE="$SRC_FIRMWARE_DIR/bootcode.bin" - FIXUPS=("$SRC_FIRMWARE_DIR"/fixup*.dat) - SRC_OVERLAYS_DIR="$SRC_FIRMWARE_DIR/overlays" - SRC_OVERLAYS=("$SRC_OVERLAYS_DIR"/*) - CONFIG="${config.hardware.raspberry-pi.config-output}" + TARGET_FIRMWARE_DIR="${firmware-path}" + TARGET_OVERLAYS_DIR="$TARGET_FIRMWARE_DIR/overlays" + TMPFILE="$TARGET_FIRMWARE_DIR/tmp" + KERNEL="${kernel}/${config.system.boot.loader.kernelFile}" + SHOULD_UBOOT=${if cfg.uboot.enable then "1" else "0"} + SRC_FIRMWARE_DIR="${pkgs.raspberrypifw}/share/raspberrypi/boot" + STARTFILES=("$SRC_FIRMWARE_DIR"/start*.elf) + DTBS=("$SRC_FIRMWARE_DIR"/*.dtb) + BOOTCODE="$SRC_FIRMWARE_DIR/bootcode.bin" + FIXUPS=("$SRC_FIRMWARE_DIR"/fixup*.dat) + SRC_OVERLAYS_DIR="$SRC_FIRMWARE_DIR/overlays" + SRC_OVERLAYS=("$SRC_OVERLAYS_DIR"/*) + CONFIG="${config.hardware.raspberry-pi.config-output}" - ${lib.strings.optionalString cfg.uboot.enable '' - UBOOT="${cfg.uboot.package}/u-boot.bin" + ${lib.strings.optionalString cfg.uboot.enable '' + UBOOT="${cfg.uboot.package}/u-boot.bin" - migrate_uboot() { - echo "migrating uboot" - touch "$STATE_DIRECTORY/uboot-migration-in-progress" - cp "$UBOOT" "$TMPFILE" - mv -T "$TMPFILE" "$TARGET_FIRMWARE_DIR/u-boot-rpi-arm64.bin" - echo "${builtins.toString cfg.uboot.package}" > "$STATE_DIRECTORY/uboot-version" - rm "$STATE_DIRECTORY/uboot-migration-in-progress" - } - ''} + migrate_uboot() { + echo "migrating uboot" + touch "$STATE_DIRECTORY/uboot-migration-in-progress" + cp "$UBOOT" "$TMPFILE" + mv -T "$TMPFILE" "$TARGET_FIRMWARE_DIR/u-boot-rpi-arm64.bin" + echo "${ + builtins.toString cfg.uboot.package + }" > "$STATE_DIRECTORY/uboot-version" + rm "$STATE_DIRECTORY/uboot-migration-in-progress" + } + ''} - migrate_kernel() { - echo "migrating kernel" - touch "$STATE_DIRECTORY/kernel-migration-in-progress" - cp "$KERNEL" "$TMPFILE" - mv -T "$TMPFILE" "$TARGET_FIRMWARE_DIR/kernel.img" - cp "${initrd}" "$TMPFILE" - mv -T "$TMPFILE" "$TARGET_FIRMWARE_DIR/initrd" - echo "${ - builtins.toString kernel - }" > "$STATE_DIRECTORY/kernel-version" - rm "$STATE_DIRECTORY/kernel-migration-in-progress" - } + migrate_kernel() { + echo "migrating kernel" + touch "$STATE_DIRECTORY/kernel-migration-in-progress" + cp "$KERNEL" "$TMPFILE" + mv -T "$TMPFILE" "$TARGET_FIRMWARE_DIR/kernel.img" + cp "${initrd}" "$TMPFILE" + mv -T "$TMPFILE" "$TARGET_FIRMWARE_DIR/initrd" + echo "${ + builtins.toString kernel + }" > "$STATE_DIRECTORY/kernel-version" + rm "$STATE_DIRECTORY/kernel-migration-in-progress" + } - migrate_cmdline() { - echo "migrating cmdline" - touch "$STATE_DIRECTORY/cmdline-migration-in-progress" - cp "${kernel-params}" "$TMPFILE" - mv -T "$TMPFILE" "$TARGET_FIRMWARE_DIR/cmdline.txt" - echo "${ - builtins.toString kernel-params - }" > "$STATE_DIRECTORY/cmdline-version" - rm "$STATE_DIRECTORY/cmdline-migration-in-progress" - } + migrate_cmdline() { + echo "migrating cmdline" + touch "$STATE_DIRECTORY/cmdline-migration-in-progress" + cp "${kernel-params}" "$TMPFILE" + mv -T "$TMPFILE" "$TARGET_FIRMWARE_DIR/cmdline.txt" + echo "${ + builtins.toString kernel-params + }" > "$STATE_DIRECTORY/cmdline-version" + rm "$STATE_DIRECTORY/cmdline-migration-in-progress" + } - migrate_config() { - echo "migrating config.txt" - touch "$STATE_DIRECTORY/config-migration-in-progress" - cp "$CONFIG" "$TMPFILE" - mv -T "$TMPFILE" "$TARGET_FIRMWARE_DIR/config.txt" - echo "${config.hardware.raspberry-pi.config-output}" > "$STATE_DIRECTORY/config-version" - rm "$STATE_DIRECTORY/config-migration-in-progress" - } + migrate_config() { + echo "migrating config.txt" + touch "$STATE_DIRECTORY/config-migration-in-progress" + cp "$CONFIG" "$TMPFILE" + mv -T "$TMPFILE" "$TARGET_FIRMWARE_DIR/config.txt" + echo "${config.hardware.raspberry-pi.config-output}" > "$STATE_DIRECTORY/config-version" + rm "$STATE_DIRECTORY/config-migration-in-progress" + } - migrate_firmware() { - echo "migrating raspberrypi firmware" - touch "$STATE_DIRECTORY/firmware-migration-in-progress" - for SRC in "''${STARTFILES[@]}" "''${DTBS[@]}" "$BOOTCODE" "''${FIXUPS[@]}" - do - cp "$SRC" "$TMPFILE" - mv -T "$TMPFILE" "$TARGET_FIRMWARE_DIR/$(basename "$SRC")" - done + migrate_firmware() { + echo "migrating raspberrypi firmware" + touch "$STATE_DIRECTORY/firmware-migration-in-progress" + for SRC in "''${STARTFILES[@]}" "''${DTBS[@]}" "$BOOTCODE" "''${FIXUPS[@]}" + do + cp "$SRC" "$TMPFILE" + mv -T "$TMPFILE" "$TARGET_FIRMWARE_DIR/$(basename "$SRC")" + done - if [[ ! -d "$TARGET_OVERLAYS_DIR" ]]; then - mkdir "$TARGET_OVERLAYS_DIR" - fi + if [[ ! -d "$TARGET_OVERLAYS_DIR" ]]; then + mkdir "$TARGET_OVERLAYS_DIR" + fi - for SRC in "''${SRC_OVERLAYS[@]}" - do - cp "$SRC" "$TMPFILE" - mv -T "$TMPFILE" "$TARGET_OVERLAYS_DIR/$(basename "$SRC")" - done - echo "${ - builtins.toString pkgs.raspberrypifw - }" > "$STATE_DIRECTORY/firmware-version" - rm "$STATE_DIRECTORY/firmware-migration-in-progress" - } + for SRC in "''${SRC_OVERLAYS[@]}" + do + cp "$SRC" "$TMPFILE" + mv -T "$TMPFILE" "$TARGET_OVERLAYS_DIR/$(basename "$SRC")" + done + echo "${ + builtins.toString pkgs.raspberrypifw + }" > "$STATE_DIRECTORY/firmware-version" + rm "$STATE_DIRECTORY/firmware-migration-in-progress" + } - ${lib.strings.optionalString cfg.uboot.enable '' - if [[ "$SHOULD_UBOOT" -eq 1 ]] && [[ -f "$STATE_DIRECTORY/uboot-migration-in-progress" || ! -f "$STATE_DIRECTORY/uboot-version" || $(< "$STATE_DIRECTORY/uboot-version") != ${ - builtins.toString cfg.uboot.package - } ]]; then - migrate_uboot - fi - ''} + ${lib.strings.optionalString cfg.uboot.enable '' + if [[ "$SHOULD_UBOOT" -eq 1 ]] && [[ -f "$STATE_DIRECTORY/uboot-migration-in-progress" || ! -f "$STATE_DIRECTORY/uboot-version" || $(< "$STATE_DIRECTORY/uboot-version") != ${ + builtins.toString cfg.uboot.package + } ]]; then + migrate_uboot + fi + ''} - if [[ "$SHOULD_UBOOT" -ne 1 ]] && [[ ! -f "$STATE_DIRECTORY/kernel-version" || $(< "$STATE_DIRECTORY/kernel-version") != ${ - builtins.toString kernel - } ]]; then - migrate_kernel - fi + if [[ "$SHOULD_UBOOT" -ne 1 ]] && [[ ! -f "$STATE_DIRECTORY/kernel-version" || $(< "$STATE_DIRECTORY/kernel-version") != ${ + builtins.toString kernel + } ]]; then + migrate_kernel + fi - if [[ "$SHOULD_UBOOT" -ne 1 ]] && [[ ! -f "$STATE_DIRECTORY/cmdline-version" || $(< "$STATE_DIRECTORY/cmdline-version") != ${ - builtins.toString kernel-params - } ]]; then - migrate_cmdline - fi + if [[ "$SHOULD_UBOOT" -ne 1 ]] && [[ ! -f "$STATE_DIRECTORY/cmdline-version" || $(< "$STATE_DIRECTORY/cmdline-version") != ${ + builtins.toString kernel-params + } ]]; then + migrate_cmdline + fi - if [[ -f "$STATE_DIRECTORY/config-migration-in-progress" || ! -f "$STATE_DIRECTORY/config-version" || $(< "$STATE_DIRECTORY/config-version") != ${ - builtins.toString config.hardware.raspberry-pi.config-output - } ]]; then - migrate_config - fi + if [[ -f "$STATE_DIRECTORY/config-migration-in-progress" || ! -f "$STATE_DIRECTORY/config-version" || $(< "$STATE_DIRECTORY/config-version") != ${ + builtins.toString config.hardware.raspberry-pi.config-output + } ]]; then + migrate_config + fi - if [[ -f "$STATE_DIRECTORY/firmware-migration-in-progress" || ! -f "$STATE_DIRECTORY/firmware-version" || $(< "$STATE_DIRECTORY/firmware-version") != ${ - builtins.toString pkgs.raspberrypifw - } ]]; then - migrate_firmware - fi - ''; - }; + if [[ -f "$STATE_DIRECTORY/firmware-migration-in-progress" || ! -f "$STATE_DIRECTORY/firmware-version" || $(< "$STATE_DIRECTORY/firmware-version") != ${ + builtins.toString pkgs.raspberrypifw + } ]]; then + migrate_firmware + fi + ''; }; + }; }; # Default config.txt on Raspberry Pi OS: @@ -249,7 +251,8 @@ in # linux kernel. kernel = { enable = true; - value = if cfg.uboot.enable then "u-boot-rpi-arm64.bin" else "kernel.img"; + value = + if cfg.uboot.enable then "u-boot-rpi-arm64.bin" else "kernel.img"; }; ramfsfile = { enable = !cfg.uboot.enable; @@ -294,37 +297,39 @@ in }; nixpkgs = { - overlays = - let - rpi-overlays = [ core-overlay ] - ++ (if config.raspberry-pi-nix.libcamera-overlay.enable - then [ libcamera-overlay ] else [ ]); - rpi-overlay = lib.composeManyExtensions rpi-overlays; - pin-prev-overlay = overlay: pinned-prev: final: prev: - let - # apply the overlay to pinned-prev and fix that so no references to the actual final - # and prev appear in applied-overlay - applied-overlay = - lib.fix (final: pinned-prev // overlay final pinned-prev); - # We only want to set keys that appear in the overlay, so restrict applied-overlay to - # these keys - restricted-overlay = lib.getAttrs (builtins.attrNames (overlay { } { })) applied-overlay; - in - prev // restricted-overlay; - in - if cfg.pin-inputs.enable - then [ (pin-prev-overlay rpi-overlay pinned) ] - else [ rpi-overlay ]; + overlays = let + rpi-overlays = [ core-overlay ] + ++ (if config.raspberry-pi-nix.libcamera-overlay.enable then + [ libcamera-overlay ] + else + [ ]); + rpi-overlay = lib.composeManyExtensions rpi-overlays; + pin-prev-overlay = overlay: pinned-prev: final: prev: + let + # apply the overlay to pinned-prev and fix that so no references to the actual final + # and prev appear in applied-overlay + applied-overlay = + lib.fix (final: pinned-prev // overlay final pinned-prev); + # We only want to set keys that appear in the overlay, so restrict applied-overlay to + # these keys + restricted-overlay = + lib.getAttrs (builtins.attrNames (overlay { } { })) + applied-overlay; + in prev // restricted-overlay; + in if cfg.pin-inputs.enable then + [ (pin-prev-overlay rpi-overlay pinned) ] + else + [ rpi-overlay ]; }; boot = { - kernelParams = - if cfg.uboot.enable then [ ] - else [ - "console=tty1" - # https://github.com/raspberrypi/firmware/issues/1539#issuecomment-784498108 - "console=serial0,115200n8" - "init=/sbin/init" - ]; + kernelParams = if cfg.uboot.enable then + [ ] + else [ + "console=tty1" + # https://github.com/raspberrypi/firmware/issues/1539#issuecomment-784498108 + "console=serial0,115200n8" + "init=/sbin/init" + ]; initrd = { availableKernelModules = [ "usbhid" @@ -334,7 +339,8 @@ in "reset-raspberrypi" # required for vl805 firmware to load ]; }; - kernelPackages = pkgs.linuxPackagesFor pkgs.rpi-kernels."${version}"."${board}"; + kernelPackages = + pkgs.linuxPackagesFor pkgs.rpi-kernels."${version}"."${board}"; loader = { grub.enable = lib.mkDefault false; initScript.enable = !cfg.uboot.enable; @@ -348,55 +354,56 @@ in }; hardware.enableRedistributableFirmware = true; - users.groups = builtins.listToAttrs (map (k: { name = k; value = { }; }) - [ "input" "sudo" "plugdev" "games" "netdev" "gpio" "i2c" "spi" ]); + users.groups = builtins.listToAttrs (map (k: { + name = k; + value = { }; + }) [ "input" "sudo" "plugdev" "games" "netdev" "gpio" "i2c" "spi" ]); services = { - udev.extraRules = - let shell = "${pkgs.bash}/bin/bash"; - in '' - # https://raw.githubusercontent.com/RPi-Distro/raspberrypi-sys-mods/master/etc.armhf/udev/rules.d/99-com.rules - SUBSYSTEM=="input", GROUP="input", MODE="0660" - SUBSYSTEM=="i2c-dev", GROUP="i2c", MODE="0660" - SUBSYSTEM=="spidev", GROUP="spi", MODE="0660" - SUBSYSTEM=="*gpiomem*", GROUP="gpio", MODE="0660" - SUBSYSTEM=="rpivid-*", GROUP="video", MODE="0660" + udev.extraRules = let shell = "${pkgs.bash}/bin/bash"; + in '' + # https://raw.githubusercontent.com/RPi-Distro/raspberrypi-sys-mods/master/etc.armhf/udev/rules.d/99-com.rules + SUBSYSTEM=="input", GROUP="input", MODE="0660" + SUBSYSTEM=="i2c-dev", GROUP="i2c", MODE="0660" + SUBSYSTEM=="spidev", GROUP="spi", MODE="0660" + SUBSYSTEM=="*gpiomem*", GROUP="gpio", MODE="0660" + SUBSYSTEM=="rpivid-*", GROUP="video", MODE="0660" - KERNEL=="vcsm-cma", GROUP="video", MODE="0660" - SUBSYSTEM=="dma_heap", GROUP="video", MODE="0660" + KERNEL=="vcsm-cma", GROUP="video", MODE="0660" + SUBSYSTEM=="dma_heap", GROUP="video", MODE="0660" - SUBSYSTEM=="gpio", GROUP="gpio", MODE="0660" - SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="${shell} -c 'chgrp -R gpio /sys/class/gpio && chmod -R g=u /sys/class/gpio'" - SUBSYSTEM=="gpio", ACTION=="add", PROGRAM="${shell} -c 'chgrp -R gpio /sys%p && chmod -R g=u /sys%p'" + SUBSYSTEM=="gpio", GROUP="gpio", MODE="0660" + SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="${shell} -c 'chgrp -R gpio /sys/class/gpio && chmod -R g=u /sys/class/gpio'" + SUBSYSTEM=="gpio", ACTION=="add", PROGRAM="${shell} -c 'chgrp -R gpio /sys%p && chmod -R g=u /sys%p'" - # PWM export results in a "change" action on the pwmchip device (not "add" of a new device), so match actions other than "remove". - SUBSYSTEM=="pwm", ACTION!="remove", PROGRAM="${shell} -c 'chgrp -R gpio /sys%p && chmod -R g=u /sys%p'" + # PWM export results in a "change" action on the pwmchip device (not "add" of a new device), so match actions other than "remove". + SUBSYSTEM=="pwm", ACTION!="remove", PROGRAM="${shell} -c 'chgrp -R gpio /sys%p && chmod -R g=u /sys%p'" - KERNEL=="ttyAMA[0-9]*|ttyS[0-9]*", PROGRAM="${shell} -c '\ - ALIASES=/proc/device-tree/aliases; \ - TTYNODE=$$(readlink /sys/class/tty/%k/device/of_node | sed 's/base/:/' | cut -d: -f2); \ - if [ -e $$ALIASES/bluetooth ] && [ $$TTYNODE/bluetooth = $$(strings $$ALIASES/bluetooth) ]; then \ - echo 1; \ - elif [ -e $$ALIASES/console ]; then \ - if [ $$TTYNODE = $$(strings $$ALIASES/console) ]; then \ - echo 0;\ - else \ - exit 1; \ - fi \ - elif [ $$TTYNODE = $$(strings $$ALIASES/serial0) ]; then \ - echo 0; \ - elif [ $$TTYNODE = $$(strings $$ALIASES/serial1) ]; then \ - echo 1; \ - else \ - exit 1; \ - fi \ - '", SYMLINK+="serial%c" + KERNEL=="ttyAMA[0-9]*|ttyS[0-9]*", PROGRAM="${shell} -c '\ + ALIASES=/proc/device-tree/aliases; \ + TTYNODE=$$(readlink /sys/class/tty/%k/device/of_node | sed 's/base/:/' | cut -d: -f2); \ + if [ -e $$ALIASES/bluetooth ] && [ $$TTYNODE/bluetooth = $$(strings $$ALIASES/bluetooth) ]; then \ + echo 1; \ + elif [ -e $$ALIASES/console ]; then \ + if [ $$TTYNODE = $$(strings $$ALIASES/console) ]; then \ + echo 0;\ + else \ + exit 1; \ + fi \ + elif [ $$TTYNODE = $$(strings $$ALIASES/serial0) ]; then \ + echo 0; \ + elif [ $$TTYNODE = $$(strings $$ALIASES/serial1) ]; then \ + echo 1; \ + else \ + exit 1; \ + fi \ + '", SYMLINK+="serial%c" - ACTION=="add", SUBSYSTEM=="vtconsole", KERNEL=="vtcon1", RUN+="${shell} -c '\ - if echo RPi-Sense FB | cmp -s /sys/class/graphics/fb0/name; then \ - echo 0 > /sys$devpath/bind; \ - fi; \ - '" - ''; + ACTION=="add", SUBSYSTEM=="vtconsole", KERNEL=="vtcon1", RUN+="${shell} -c '\ + if echo RPi-Sense FB | cmp -s /sys/class/graphics/fb0/name; then \ + echo 0 > /sys$devpath/bind; \ + fi; \ + '" + ''; }; }; diff --git a/sd-image/default.nix b/sd-image/default.nix index b845de3..bb85ede 100644 --- a/sd-image/default.nix +++ b/sd-image/default.nix @@ -13,57 +13,53 @@ # table, so the partition table id is a 1-indexed hex # number. So, we drop the hex prefix and stick on a "02" to # refer to the root partition. - "root=PARTUUID=${lib.strings.removePrefix "0x" config.sdImage.firmwarePartitionID}-02" + "root=PARTUUID=${ + lib.strings.removePrefix "0x" config.sdImage.firmwarePartitionID + }-02" "rootfstype=ext4" "fsck.repair=yes" "rootwait" ]; - sdImage = - let - kernel-params = pkgs.writeTextFile { - name = "cmdline.txt"; - text = '' - ${lib.strings.concatStringsSep " " config.boot.kernelParams} - ''; - }; - cfg = config.raspberry-pi-nix; - version = cfg.kernel-version; - board = cfg.board; - kernel = "${config.system.build.kernel}/${config.system.boot.loader.kernelFile}"; - initrd = "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}"; - populate-kernel = - if cfg.uboot.enable - then '' - cp ${cfg.uboot.package}/u-boot.bin firmware/u-boot-rpi-arm64.bin - '' - else '' - cp "${kernel}" firmware/kernel.img - cp "${initrd}" firmware/initrd - cp "${kernel-params}" firmware/cmdline.txt - ''; - in - { - populateFirmwareCommands = '' - ${populate-kernel} - cp -r ${pkgs.raspberrypifw}/share/raspberrypi/boot/{start*.elf,*.dtb,bootcode.bin,fixup*.dat,overlays} firmware - cp ${config.hardware.raspberry-pi.config-output} firmware/config.txt + sdImage = let + kernel-params = pkgs.writeTextFile { + name = "cmdline.txt"; + text = '' + ${lib.strings.concatStringsSep " " config.boot.kernelParams} ''; - populateRootCommands = - if cfg.uboot.enable - then '' - mkdir -p ./files/boot - ${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot - '' - else '' - mkdir -p ./files/sbin - content="$( - echo "#!${pkgs.bash}/bin/bash" - echo "exec ${config.system.build.toplevel}/init" - )" - echo "$content" > ./files/sbin/init - chmod 744 ./files/sbin/init - ''; }; + cfg = config.raspberry-pi-nix; + version = cfg.kernel-version; + board = cfg.board; + kernel = + "${config.system.build.kernel}/${config.system.boot.loader.kernelFile}"; + initrd = + "${config.system.build.initialRamdisk}/${config.system.boot.loader.initrdFile}"; + populate-kernel = if cfg.uboot.enable then '' + cp ${cfg.uboot.package}/u-boot.bin firmware/u-boot-rpi-arm64.bin + '' else '' + cp "${kernel}" firmware/kernel.img + cp "${initrd}" firmware/initrd + cp "${kernel-params}" firmware/cmdline.txt + ''; + in { + populateFirmwareCommands = '' + ${populate-kernel} + cp -r ${pkgs.raspberrypifw}/share/raspberrypi/boot/{start*.elf,*.dtb,bootcode.bin,fixup*.dat,overlays} firmware + cp ${config.hardware.raspberry-pi.config-output} firmware/config.txt + ''; + populateRootCommands = if cfg.uboot.enable then '' + mkdir -p ./files/boot + ${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot + '' else '' + mkdir -p ./files/sbin + content="$( + echo "#!${pkgs.bash}/bin/bash" + echo "exec ${config.system.build.toplevel}/init" + )" + echo "$content" > ./files/sbin/init + chmod 744 ./files/sbin/init + ''; + }; }; } diff --git a/sd-image/sd-image.nix b/sd-image/sd-image.nix index 60eedfc..6e68bae 100644 --- a/sd-image/sd-image.nix +++ b/sd-image/sd-image.nix @@ -30,8 +30,7 @@ let } // optionalAttrs (config.sdImage.rootPartitionUUID != null) { uuid = config.sdImage.rootPartitionUUID; }); -in -{ +in { imports = [ ]; options.sdImage = { @@ -153,7 +152,8 @@ in config = { fileSystems = { "/boot/firmware" = { - device = "/dev/disk/by-label/${config.raspberry-pi-nix.firmware-partition-label}"; + device = + "/dev/disk/by-label/${config.raspberry-pi-nix.firmware-partition-label}"; fsType = "vfat"; }; "/" = { @@ -164,81 +164,80 @@ in sdImage.storePaths = [ config.system.build.toplevel ]; - system.build.sdImage = pkgs.callPackage - ({ stdenv, dosfstools, e2fsprogs, mtools, libfaketime, util-linux, zstd }: - stdenv.mkDerivation { - name = config.sdImage.imageName; + system.build.sdImage = pkgs.callPackage ({ stdenv, dosfstools, e2fsprogs + , mtools, libfaketime, util-linux, zstd, }: + stdenv.mkDerivation { + name = config.sdImage.imageName; - nativeBuildInputs = - [ dosfstools e2fsprogs mtools libfaketime util-linux zstd ]; + nativeBuildInputs = + [ dosfstools e2fsprogs mtools libfaketime util-linux zstd ]; - inherit (config.sdImage) compressImage; + inherit (config.sdImage) compressImage; - buildCommand = '' - mkdir -p $out/nix-support $out/sd-image - export img=$out/sd-image/${config.sdImage.imageName} + buildCommand = '' + mkdir -p $out/nix-support $out/sd-image + export img=$out/sd-image/${config.sdImage.imageName} - echo "${pkgs.stdenv.buildPlatform.system}" > $out/nix-support/system - if test -n "$compressImage"; then - echo "file sd-image $img.zst" >> $out/nix-support/hydra-build-products - else - echo "file sd-image $img" >> $out/nix-support/hydra-build-products - fi + echo "${pkgs.stdenv.buildPlatform.system}" > $out/nix-support/system + if test -n "$compressImage"; then + echo "file sd-image $img.zst" >> $out/nix-support/hydra-build-products + else + echo "file sd-image $img" >> $out/nix-support/hydra-build-products + fi - echo "Decompressing rootfs image" - zstd -d --no-progress "${rootfsImage}" -o ./root-fs.img + echo "Decompressing rootfs image" + zstd -d --no-progress "${rootfsImage}" -o ./root-fs.img - # Gap in front of the first partition, in MiB - gap=${toString config.sdImage.firmwarePartitionOffset} + # Gap in front of the first partition, in MiB + gap=${toString config.sdImage.firmwarePartitionOffset} - # Create the image file sized to fit /boot/firmware and /, plus slack for the gap. - rootSizeBlocks=$(du -B 512 --apparent-size ./root-fs.img | awk '{ print $1 }') - firmwareSizeBlocks=$((${ - toString config.sdImage.firmwareSize - } * 1024 * 1024 / 512)) - imageSize=$((rootSizeBlocks * 512 + firmwareSizeBlocks * 512 + gap * 1024 * 1024)) - truncate -s $imageSize $img + # Create the image file sized to fit /boot/firmware and /, plus slack for the gap. + rootSizeBlocks=$(du -B 512 --apparent-size ./root-fs.img | awk '{ print $1 }') + firmwareSizeBlocks=$((${ + toString config.sdImage.firmwareSize + } * 1024 * 1024 / 512)) + imageSize=$((rootSizeBlocks * 512 + firmwareSizeBlocks * 512 + gap * 1024 * 1024)) + truncate -s $imageSize $img - # type=b is 'W95 FAT32', type=83 is 'Linux'. - # The "bootable" partition is where u-boot will look file for the bootloader - # information (dtbs, extlinux.conf file). - sfdisk $img <