bruh
This commit is contained in:
@@ -123,7 +123,7 @@ in
|
|||||||
partitions = {
|
partitions = {
|
||||||
FIRMWARE = lib.mkIf cfg.enableFirmware {
|
FIRMWARE = lib.mkIf cfg.enableFirmware {
|
||||||
priority = 1;
|
priority = 1;
|
||||||
name = "FIRMWARE";
|
name = "${config.${namespace}.network.hostName}-FIRMWARE";
|
||||||
start = "1M";
|
start = "1M";
|
||||||
end = "1G";
|
end = "1G";
|
||||||
type = "0700";
|
type = "0700";
|
||||||
@@ -138,6 +138,7 @@ in
|
|||||||
priority = if cfg.enableFirmware then 2 else 1;
|
priority = if cfg.enableFirmware then 2 else 1;
|
||||||
type = "EF00";
|
type = "EF00";
|
||||||
size = "500M";
|
size = "500M";
|
||||||
|
name = "${config.${namespace}.network.hostName}-EFI";
|
||||||
content = {
|
content = {
|
||||||
type = "filesystem";
|
type = "filesystem";
|
||||||
format = "vfat";
|
format = "vfat";
|
||||||
|
|||||||
@@ -179,6 +179,6 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
hardware.raspberry-pi.config-generated = render-raspberrypi-config cfg.config;
|
${namespace}.hardware.raspberry-pi.config-generated = render-raspberrypi-config cfg.config;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -12,6 +12,110 @@ let
|
|||||||
applyOverlays = _final.callPackage ./apply-overlays-dtmerge.nix { };
|
applyOverlays = _final.callPackage ./apply-overlays-dtmerge.nix { };
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ubootBinName = "u-boot.bin";
|
||||||
|
|
||||||
|
deviceTree = ({ pkgs
|
||||||
|
, firmware
|
||||||
|
}: pkgs.replaceVarsWith {
|
||||||
|
src = ./generational/install-device-tree.sh;
|
||||||
|
isExecutable = true;
|
||||||
|
|
||||||
|
replacements = {
|
||||||
|
inherit (pkgs) bash;
|
||||||
|
path = pkgs.lib.makeBinPath [
|
||||||
|
pkgs.coreutils
|
||||||
|
];
|
||||||
|
|
||||||
|
inherit firmware;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
# installs raspberry's firmware independent of the nixos generations
|
||||||
|
# sometimes referred to as "boot code"
|
||||||
|
raspberryPiFirmware = ({ pkgs
|
||||||
|
, firmware
|
||||||
|
, configTxt
|
||||||
|
}: pkgs.replaceVarsWith {
|
||||||
|
src = ./generational/install-firmware.sh;
|
||||||
|
isExecutable = true;
|
||||||
|
|
||||||
|
replacements = {
|
||||||
|
inherit (pkgs) bash;
|
||||||
|
path = pkgs.lib.makeBinPath [
|
||||||
|
pkgs.coreutils
|
||||||
|
];
|
||||||
|
|
||||||
|
inherit firmware configTxt;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
# Builders used to write during system activation
|
||||||
|
firmwareBuilder = import ./firmware-builder.nix {
|
||||||
|
inherit pkgs;
|
||||||
|
configTxt = pkgs.writeTextFile {
|
||||||
|
name = "config.txt";
|
||||||
|
text = ''
|
||||||
|
# Do not edit!
|
||||||
|
# This configuration file is generated from NixOS configuration
|
||||||
|
# options `hardware.raspberry-pi.config`.
|
||||||
|
# Any manual changes will be overwritten on the next configuration
|
||||||
|
# switch.
|
||||||
|
${config.${namespace}.hardware.raspberry-pi.config-generated}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
firmware = pkgs.${namespace}.raspberrypifw;
|
||||||
|
};
|
||||||
|
ubootBuilder = import ./uboot-builder.nix {
|
||||||
|
inherit pkgs;
|
||||||
|
ubootPackage = pkgs.${namespace}.uboot-pi5;
|
||||||
|
firmwareBuilder = firmwarePopulateCmd;
|
||||||
|
extlinuxConfBuilder = config.boot.loader.generic-extlinux-compatible.populateCmd;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Builders exposed via populateCmd, which run on the build architecture
|
||||||
|
populateFirmwareBuilder = import ./firmware-builder.nix {
|
||||||
|
pkgs = pkgs.buildPackages;
|
||||||
|
configTxt = pkgs.writeTextFile {
|
||||||
|
name = "config.txt";
|
||||||
|
text = ''
|
||||||
|
# Do not edit!
|
||||||
|
# This configuration file is generated from NixOS configuration
|
||||||
|
# options `hardware.raspberry-pi.config`.
|
||||||
|
# Any manual changes will be overwritten on the next configuration
|
||||||
|
# switch.
|
||||||
|
${config.${namespace}.hardware.raspberry-pi.config-generated}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
firmware = pkgs.${namespace}.raspberrypifw;
|
||||||
|
};
|
||||||
|
|
||||||
|
populateUbootBuilder = import ./uboot-builder.nix {
|
||||||
|
inherit ubootBinName;
|
||||||
|
pkgs = pkgs.buildPackages;
|
||||||
|
ubootPackage = pkgs.${namespace}.uboot-pi5;
|
||||||
|
firmwareBuilder = firmwarePopulateCmd;
|
||||||
|
extlinuxConfBuilder = config.boot.loader.generic-extlinux-compatible.populateCmd;
|
||||||
|
};
|
||||||
|
|
||||||
|
firmwarePopulateCmd = "${populateFirmwareBuilder} ${firmwareBuilderArgs}";
|
||||||
|
firmwareBuilderArgs = lib.optionalString (!true) " -r";
|
||||||
|
|
||||||
|
# these will receive the top-level path as an argument when invoked as
|
||||||
|
# system.build.installBootloader
|
||||||
|
builder = {
|
||||||
|
# system.build.installBootLoader
|
||||||
|
uboot = "${ubootBuilder} -f /boot/firmware -b /boot -c";
|
||||||
|
};
|
||||||
|
|
||||||
|
# firmware: caller must provide `-c <nixos configuration>` and `-f <firmware target path>`
|
||||||
|
# boot: caller must provide `-c <nixos configuration>` and `-b <boot-dir>`
|
||||||
|
populateCmds = {
|
||||||
|
uboot = {
|
||||||
|
firmware = "${populateUbootBuilder}";
|
||||||
|
boot = "${populateUbootBuilder}";
|
||||||
|
};
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.${namespace}.hardware.raspberry-pi = {
|
options.${namespace}.hardware.raspberry-pi = {
|
||||||
@@ -38,6 +142,7 @@ in
|
|||||||
imports = [
|
imports = [
|
||||||
./audio.nix
|
./audio.nix
|
||||||
./bluetooth.nix
|
./bluetooth.nix
|
||||||
|
./config.nix
|
||||||
./i2c.nix
|
./i2c.nix
|
||||||
./leds.nix
|
./leds.nix
|
||||||
./modesetting.nix
|
./modesetting.nix
|
||||||
@@ -60,7 +165,10 @@ in
|
|||||||
"reset-raspberrypi" # required for vl805 firmware to load
|
"reset-raspberrypi" # required for vl805 firmware to load
|
||||||
]);
|
]);
|
||||||
loader = {
|
loader = {
|
||||||
generic-extlinux-compatible.enable = lib.mkDefault true;
|
generic-extlinux-compatible = {
|
||||||
|
enable = lib.mkDefault true;
|
||||||
|
useGenerationDeviceTree = false;
|
||||||
|
};
|
||||||
grub.enable = lib.mkForce false;
|
grub.enable = lib.mkForce false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -150,12 +258,21 @@ in
|
|||||||
i2c.enable = lib.mkDefault true;
|
i2c.enable = lib.mkDefault true;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Pi specific system tags
|
system = {
|
||||||
system.nixos.tags = [
|
build.installBootLoader = lib.mkOverride 60 (builder."uboot");
|
||||||
"raspberry-pi-${cfg.variant}"
|
boot = {
|
||||||
# config.boot.loader.raspberry-pi.bootloader
|
loader = {
|
||||||
config.boot.kernelPackages.kernel.version
|
id = lib.mkOverride 60 ("raspberrypi-uboot");
|
||||||
];
|
kernelFile = pkgs.stdenv.hostPlatform.linux-kernel.target;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
# Pi specific system tags
|
||||||
|
nixos.tags = [
|
||||||
|
"raspberry-pi-${cfg.variant}"
|
||||||
|
# config.boot.loader.raspberry-pi.bootloader
|
||||||
|
config.boot.kernelPackages.kernel.version
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
# Common programs
|
# Common programs
|
||||||
programs.kdeconnect.enable = lib.mkDefault false;
|
programs.kdeconnect.enable = lib.mkDefault false;
|
||||||
@@ -191,11 +308,6 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
nixpkgs.overlays = [ ] ++ (if cfg.variant == "5" then [
|
nixpkgs.overlays = [ ] ++ (if cfg.variant == "5" then [
|
||||||
(final: prev: {
|
|
||||||
ubootRaspberryPi5 = prev.uboot.ubootRaspberryPi4_64Bit.override {
|
|
||||||
defconfig = "rpi_5_defconfig";
|
|
||||||
};
|
|
||||||
})
|
|
||||||
(final: prev: {
|
(final: prev: {
|
||||||
# https://github.com/nvmd/nixos-raspberrypi/issues/64
|
# https://github.com/nvmd/nixos-raspberrypi/issues/64
|
||||||
# credit for the initial version of this snippet goes to @micahcc
|
# credit for the initial version of this snippet goes to @micahcc
|
||||||
|
|||||||
18
modules/nixos/hardware/raspberry-pi/firmware-builder.nix
Normal file
18
modules/nixos/hardware/raspberry-pi/firmware-builder.nix
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{ pkgs
|
||||||
|
, configTxt
|
||||||
|
, firmware ? pkgs.raspberrypifw
|
||||||
|
}:
|
||||||
|
|
||||||
|
pkgs.replaceVarsWith {
|
||||||
|
src = ./firmware-builder.sh;
|
||||||
|
isExecutable = true;
|
||||||
|
|
||||||
|
replacements = {
|
||||||
|
inherit (pkgs) bash;
|
||||||
|
path = pkgs.lib.makeBinPath [
|
||||||
|
pkgs.coreutils
|
||||||
|
];
|
||||||
|
|
||||||
|
inherit firmware configTxt;
|
||||||
|
};
|
||||||
|
}
|
||||||
92
modules/nixos/hardware/raspberry-pi/firmware-builder.sh
Normal file
92
modules/nixos/hardware/raspberry-pi/firmware-builder.sh
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
#! @bash@/bin/sh -e
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
|
|
||||||
|
export PATH=/empty:@path@
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "usage: $0 -c <path-to-default-configuration> [-d <firmware-dir>] [-r]" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
default= # Default configuration
|
||||||
|
target=/boot/firmware # Firmware target directory
|
||||||
|
|
||||||
|
while getopts "c:d:r" opt; do
|
||||||
|
case "$opt" in
|
||||||
|
c) default="$OPTARG" ;;
|
||||||
|
d) target="$OPTARG" ;;
|
||||||
|
r) useVendorDeviceTree=1 ;;
|
||||||
|
\?) usage ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Copy a file from the Nix store to $target.
|
||||||
|
declare -A filesCopied
|
||||||
|
|
||||||
|
copyForced() {
|
||||||
|
local src="$1"
|
||||||
|
local dst="$2"
|
||||||
|
cp $src $dst.tmp
|
||||||
|
mv $dst.tmp $dst
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add the firmware files
|
||||||
|
# fwdir=@firmware@/share/raspberrypi/boot/
|
||||||
|
SRC_FIRMWARE_DIR=@firmware@/share/raspberrypi/boot
|
||||||
|
dtb_path=$SRC_FIRMWARE_DIR
|
||||||
|
|
||||||
|
echo "copying firmware..."
|
||||||
|
|
||||||
|
# Device Tree
|
||||||
|
|
||||||
|
if [ -n "$useVendorDeviceTree" ]; then
|
||||||
|
echo -n "using vendor firmware from "
|
||||||
|
dtb_path=$SRC_FIRMWARE_DIR
|
||||||
|
else
|
||||||
|
echo -n "using default generation's kernel device tree binaries: "
|
||||||
|
dtb_path=$(readlink -f $default/dtbs)
|
||||||
|
fi
|
||||||
|
echo $dtb_path
|
||||||
|
|
||||||
|
DTBS=("$dtb_path"/*.dtb)
|
||||||
|
for dtb in "${DTBS[@]}"; do
|
||||||
|
# for dtb in $dtb_path/broadcom/*.dtb; do
|
||||||
|
dst="$target/$(basename $dtb)"
|
||||||
|
copyForced $dtb "$dst"
|
||||||
|
filesCopied[$dst]=1
|
||||||
|
done
|
||||||
|
|
||||||
|
SRC_OVERLAYS_DIR="$dtb_path/overlays"
|
||||||
|
SRC_OVERLAYS=("$SRC_OVERLAYS_DIR"/*)
|
||||||
|
mkdir -p $target/overlays
|
||||||
|
for ovr in "${SRC_OVERLAYS[@]}"; do
|
||||||
|
# for ovr in $dtb_path/overlays/*; do
|
||||||
|
dst="$target/overlays/$(basename $ovr)"
|
||||||
|
copyForced $ovr "$dst"
|
||||||
|
filesCopied[$dst]=1
|
||||||
|
done
|
||||||
|
|
||||||
|
# remove obsolete device tree files
|
||||||
|
for fn in $target/*.dtb $target/overlays/*; do
|
||||||
|
if ! test "${filesCopied[$fn]}" = 1; then
|
||||||
|
rm -vf -- "$fn"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
# Boot code
|
||||||
|
|
||||||
|
STARTFILES=("$SRC_FIRMWARE_DIR"/start*.elf)
|
||||||
|
BOOTCODE="$SRC_FIRMWARE_DIR/bootcode.bin"
|
||||||
|
FIXUPS=("$SRC_FIRMWARE_DIR"/fixup*.dat)
|
||||||
|
for SRC in "${STARTFILES[@]}" "$BOOTCODE" "${FIXUPS[@]}"; do
|
||||||
|
dst="$target/$(basename $SRC)"
|
||||||
|
copyForced "$SRC" "$dst"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "copying config.txt..."
|
||||||
|
# Add the config.txt
|
||||||
|
copyForced @configTxt@ $target/config.txt
|
||||||
|
|
||||||
|
echo "raspberry pi firmware installed"
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
#! @bash@/bin/sh -e
|
||||||
|
|
||||||
|
# shellcheck disable=SC3030,SC3043,SC3044,SC3054
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
|
|
||||||
|
export PATH=/empty:@path@
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "usage: $0 -c <path-to-configuration> [-d <destination-dir>] [-r]" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
generationPath= # Path to nixos configuration/generation
|
||||||
|
target=/boot/firmware # Device tree files target directory
|
||||||
|
|
||||||
|
while getopts "c:d:r" opt; do
|
||||||
|
case "$opt" in
|
||||||
|
c) generationPath="$OPTARG" ;;
|
||||||
|
d) target="$OPTARG" ;;
|
||||||
|
r) useVendorDeviceTree=1 ;;
|
||||||
|
\?) usage ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Copy a file from the Nix store to $target.
|
||||||
|
declare -A filesCopied
|
||||||
|
|
||||||
|
copyForced() {
|
||||||
|
local src="$1"
|
||||||
|
local dst="$2"
|
||||||
|
|
||||||
|
local dstTmp="$dst.tmp.$$"
|
||||||
|
|
||||||
|
cp "$src" "$dstTmp"
|
||||||
|
mv "$dstTmp" "$dst"
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "$0: $@"
|
||||||
|
echo -n "installing device tree files: "
|
||||||
|
|
||||||
|
# Device Tree
|
||||||
|
|
||||||
|
if [ -n "$useVendorDeviceTree" ]; then
|
||||||
|
echo -n "vendor firmware "
|
||||||
|
dtb_path=@firmware@/share/raspberrypi/boot
|
||||||
|
else
|
||||||
|
echo -n "generation's kernel's "
|
||||||
|
dtb_path=$(readlink -f "$generationPath/dtbs")
|
||||||
|
fi
|
||||||
|
echo "$dtb_path"
|
||||||
|
|
||||||
|
# firmware package has dtbs in its root,
|
||||||
|
# dtbs built with kernel are in broadcom/
|
||||||
|
DTBS=("$dtb_path"/*.dtb "$dtb_path"/broadcom/*.dtb)
|
||||||
|
for dtb in "${DTBS[@]}"; do
|
||||||
|
dst="$target/$(basename "$dtb")"
|
||||||
|
copyForced "$dtb" "$dst"
|
||||||
|
filesCopied[$dst]=1
|
||||||
|
done
|
||||||
|
|
||||||
|
SRC_OVERLAYS=("$dtb_path/overlays"/*)
|
||||||
|
mkdir -p "$target/overlays"
|
||||||
|
for ovr in "${SRC_OVERLAYS[@]}"; do
|
||||||
|
dst="$target/overlays/$(basename "$ovr")"
|
||||||
|
copyForced "$ovr" "$dst"
|
||||||
|
filesCopied[$dst]=1
|
||||||
|
done
|
||||||
|
|
||||||
|
# remove obsolete device tree files
|
||||||
|
for fn in $target/*.dtb $target/overlays/*; do
|
||||||
|
if ! test "${filesCopied[$fn]}" = 1; then
|
||||||
|
rm -vf -- "$fn"
|
||||||
|
fi
|
||||||
|
done
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
#! @bash@/bin/sh -e
|
||||||
|
|
||||||
|
# shellcheck disable=SC3030,SC3043,SC3044,SC3054
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
|
|
||||||
|
export PATH=/empty:@path@
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "usage: $0 -c <path-to-configuration> [-d <firmware-dir>]" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
generationPath= # Path to nixos configuration/generation
|
||||||
|
target=/boot/firmware # Firmware target directory
|
||||||
|
|
||||||
|
while getopts "c:d:" opt; do
|
||||||
|
case "$opt" in
|
||||||
|
c) generationPath="$OPTARG" ;;
|
||||||
|
d) target="$OPTARG" ;;
|
||||||
|
\?) usage ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Copy a file from the Nix store to $target.
|
||||||
|
declare -A filesCopied
|
||||||
|
|
||||||
|
copyForced() {
|
||||||
|
local src="$1"
|
||||||
|
local dst="$2"
|
||||||
|
|
||||||
|
local dstTmp="$dst.tmp.$$"
|
||||||
|
|
||||||
|
cp "$src" "$dstTmp"
|
||||||
|
mv "$dstTmp" "$dst"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add the firmware files
|
||||||
|
# fwdir=@firmware@/share/raspberrypi/boot/
|
||||||
|
SRC_FIRMWARE_DIR=@firmware@/share/raspberrypi/boot
|
||||||
|
|
||||||
|
echo "copying raspberry pi firmware..."
|
||||||
|
|
||||||
|
# Boot code
|
||||||
|
|
||||||
|
STARTFILES=("$SRC_FIRMWARE_DIR"/start*.elf)
|
||||||
|
BOOTCODE="$SRC_FIRMWARE_DIR/bootcode.bin"
|
||||||
|
FIXUPS=("$SRC_FIRMWARE_DIR"/fixup*.dat)
|
||||||
|
for SRC in "${STARTFILES[@]}" "$BOOTCODE" "${FIXUPS[@]}"; do
|
||||||
|
dst="$target/$(basename "$SRC")"
|
||||||
|
copyForced "$SRC" "$dst"
|
||||||
|
filesCopied[$dst]=1
|
||||||
|
done
|
||||||
|
|
||||||
|
# remove obsolete firmware files
|
||||||
|
for fn in $target/start*.elf $target/fixup*.dat; do
|
||||||
|
if ! test "${filesCopied[$fn]}" = 1; then
|
||||||
|
rm -vf -- "$fn"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "copying config.txt..."
|
||||||
|
# Add the config.txt
|
||||||
|
copyForced @configTxt@ "$target/config.txt"
|
||||||
|
|
||||||
|
echo "raspberry pi firmware installed"
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
#! @bash@/bin/sh -e
|
||||||
|
|
||||||
|
# shellcheck disable=SC3043,SC3044,SC3054
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
|
|
||||||
|
export PATH=/empty:@path@
|
||||||
|
|
||||||
|
# used to track copied generations to decide which are obsolete
|
||||||
|
# and need to be removed
|
||||||
|
declare -A activeGenerations
|
||||||
|
|
||||||
|
moveWBackup() {
|
||||||
|
local src="$1"
|
||||||
|
local dst="$2"
|
||||||
|
|
||||||
|
# Backup $dst if already exists
|
||||||
|
local dstBkp="$dst.bkp.$$"
|
||||||
|
if [ -e "$dst" ]; then
|
||||||
|
mv "$dst" "$dstBkp"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Move $src as "new" $dst
|
||||||
|
mv "$src" "$dst"
|
||||||
|
|
||||||
|
# Remove backup directory of the previous $dst
|
||||||
|
rm -rf "$dstBkp"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Copy generation's kernel, initrd, cmdline to `gensDir/generationName`.
|
||||||
|
addEntry() {
|
||||||
|
local generationPath="$1"
|
||||||
|
local generationName="$2"
|
||||||
|
local gensDir="$3"
|
||||||
|
|
||||||
|
local dst="$gensDir/$generationName"
|
||||||
|
|
||||||
|
echo "* nixos generation '$generationName' -> $dst"
|
||||||
|
# Don't copy the files if $dst already exists, unless it's the default
|
||||||
|
# configuration.
|
||||||
|
# This means that we have to create $dst atomically to prevent partially
|
||||||
|
# copied generations if this script is ever interrupted.
|
||||||
|
#
|
||||||
|
# For "default" generation: make backup and then replace with the new
|
||||||
|
# "default", minimizing the time when where isn't any "default" generation
|
||||||
|
# directory
|
||||||
|
if ! [ -e $dst ] || [ "$generationName" = "default" ]; then
|
||||||
|
local dstTmp="$dst.tmp.$$"
|
||||||
|
mkdir -p "$dstTmp" || true
|
||||||
|
|
||||||
|
@nixosGenBuilder@ -c "$generationPath" -n "$generationName" -d "$dstTmp"
|
||||||
|
|
||||||
|
# Move new generation on its place, backing up the previous version
|
||||||
|
# if it exists
|
||||||
|
# This may only happen when "$generationName" = "default"
|
||||||
|
moveWBackup "$dstTmp" "$dst"
|
||||||
|
fi
|
||||||
|
|
||||||
|
activeGenerations["$generationName"]=1
|
||||||
|
}
|
||||||
|
|
||||||
|
removeObsoleteGenerations() {
|
||||||
|
local path="$1"
|
||||||
|
|
||||||
|
echo "removing obsolete generations in $path..."
|
||||||
|
for gen in $path/*; do
|
||||||
|
if ! [ "${activeGenerations["$(basename "$gen")"]}" = 1 ]; then
|
||||||
|
echo "* $gen is obsolete"
|
||||||
|
rm -vrf "$gen"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
addAllEntries() {
|
||||||
|
local defaultGenerationPath="$1"
|
||||||
|
local outdir="$2"
|
||||||
|
local numGenerations="$3"
|
||||||
|
|
||||||
|
local gensDir="$outdir/@nixosGenerationsDir@"
|
||||||
|
mkdir -p "$gensDir" || true
|
||||||
|
|
||||||
|
# Add default generation
|
||||||
|
addEntry "$defaultGenerationPath" default "$gensDir"
|
||||||
|
|
||||||
|
if [ "$numGenerations" -gt 0 ]; then
|
||||||
|
# Add up to $numGenerations generations of the system profile, 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}-default" "$gensDir"
|
||||||
|
for specialisation in $(
|
||||||
|
ls /nix/var/nix/profiles/system-$generation-link/specialisation \
|
||||||
|
| sort -n -r); do
|
||||||
|
link=/nix/var/nix/profiles/system-$generation-link/specialisation/$specialisation
|
||||||
|
addEntry "$link" "${generation}-${specialisation}" "$gensDir"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
removeObsoleteGenerations "$gensDir"
|
||||||
|
}
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "usage: $0 -c <path-to-default-configuration> [-b <boot-dir>] [-g <num-generations>]" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
default= # Default configuration
|
||||||
|
numGenerations=0 # Number of other generations to keep (kernel, initrd, DTBs, overlays)
|
||||||
|
|
||||||
|
echo "$0: $@"
|
||||||
|
while getopts "c:b:g:f:" opt; do
|
||||||
|
case "$opt" in
|
||||||
|
c) default="$OPTARG" ;;
|
||||||
|
b) boottarget="$OPTARG" ;;
|
||||||
|
g) numGenerations="$OPTARG" ;;
|
||||||
|
f) fwtarget="$OPTARG" ;;
|
||||||
|
\?) usage ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$boottarget" ] && [ -z "$fwtarget" ]; then
|
||||||
|
echo "Error: at least one of \`-b <boot-dir>\` and \`-f <firmware-dir>\` must be set"
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$fwtarget" ]; then
|
||||||
|
echo "installing nixos-generation-independent firmware..."
|
||||||
|
@installFirmwareBuilder@ -c "$default" -d "$fwtarget"
|
||||||
|
|
||||||
|
echo "installing nixos generations..."
|
||||||
|
addAllEntries "$default" "$fwtarget" "$numGenerations"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$boottarget" ]; then
|
||||||
|
echo "'-b $boottarget' isn't used when loading the kernel directly with \`kernel\`: "\
|
||||||
|
"kernels are copied directly to <firmware-dir>"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "generational bootloader installed"
|
||||||
23
modules/nixos/hardware/raspberry-pi/uboot-builder.nix
Normal file
23
modules/nixos/hardware/raspberry-pi/uboot-builder.nix
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{ pkgs
|
||||||
|
, ubootPackage
|
||||||
|
, ubootBinName ? "u-boot.bin"
|
||||||
|
, extlinuxConfBuilder
|
||||||
|
, firmwareBuilder
|
||||||
|
}:
|
||||||
|
|
||||||
|
pkgs.replaceVarsWith {
|
||||||
|
src = ./uboot-builder.sh;
|
||||||
|
isExecutable = true;
|
||||||
|
|
||||||
|
replacements = {
|
||||||
|
inherit (pkgs) bash;
|
||||||
|
path = pkgs.lib.makeBinPath [
|
||||||
|
pkgs.coreutils
|
||||||
|
];
|
||||||
|
|
||||||
|
uboot = ubootPackage;
|
||||||
|
inherit ubootBinName;
|
||||||
|
inherit extlinuxConfBuilder;
|
||||||
|
inherit firmwareBuilder;
|
||||||
|
};
|
||||||
|
}
|
||||||
67
modules/nixos/hardware/raspberry-pi/uboot-builder.sh
Normal file
67
modules/nixos/hardware/raspberry-pi/uboot-builder.sh
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#! @bash@/bin/sh -e
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
|
|
||||||
|
export PATH=/empty:@path@
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "usage: $0 -f <firmware-dir> -b <boot-dir> -c <path-to-default-configuration>" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
default= # Default configuration, needed for extlinux
|
||||||
|
# fwtarget=/boot/firmware # firmware target directory
|
||||||
|
# boottarget=/boot # boot configuration target directory
|
||||||
|
|
||||||
|
echo "uboot-builder: $@"
|
||||||
|
while getopts "c:b:f:" opt; do
|
||||||
|
case "$opt" in
|
||||||
|
c) default="$OPTARG" ;;
|
||||||
|
b) boottarget="$OPTARG" ;;
|
||||||
|
f) fwtarget="$OPTARG" ;;
|
||||||
|
\?) usage ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$boottarget" ] && [ -z "$fwtarget" ]; then
|
||||||
|
echo "Error: at least one of \`-b <boot-dir>\` and \`-f <firmware-dir>\` must be set"
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
# # process arguments for this builder, then pass the remainder to extlinux'
|
||||||
|
# while getopts ":f:" opt; do
|
||||||
|
# case "$opt" in
|
||||||
|
# f) target="$OPTARG" ;;
|
||||||
|
# *) ;;
|
||||||
|
# esac
|
||||||
|
# done
|
||||||
|
# shift $((OPTIND-2))
|
||||||
|
# extlinuxBuilderExtraArgs="$@"
|
||||||
|
|
||||||
|
copyForced() {
|
||||||
|
local src="$1"
|
||||||
|
local dst="$2"
|
||||||
|
cp $src $dst.tmp
|
||||||
|
mv $dst.tmp $dst
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -n "$fwtarget" ]; then
|
||||||
|
@firmwareBuilder@ -c $default -d $fwtarget
|
||||||
|
|
||||||
|
echo "copying u-boot binary..."
|
||||||
|
copyForced @uboot@/u-boot.bin $fwtarget/@ubootBinName@
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$boottarget" ]; then
|
||||||
|
echo "generating extlinux configuration..."
|
||||||
|
@extlinuxConfBuilder@ -c $default -d $boottarget
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg=""
|
||||||
|
if [ -n "$fwtarget" ]; then
|
||||||
|
msg="uboot"
|
||||||
|
fi
|
||||||
|
if [ -n "$boottarget" ]; then
|
||||||
|
msg="$msg+extlinux"
|
||||||
|
fi
|
||||||
|
echo "$msg bootloader installed"
|
||||||
@@ -31,7 +31,7 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
llama-cpp = {
|
llama-cpp = {
|
||||||
enable = true;
|
enable = false;
|
||||||
port = 8127;
|
port = 8127;
|
||||||
host = "0.0.0.0";
|
host = "0.0.0.0";
|
||||||
openFirewall = cfg.openFirewall;
|
openFirewall = cfg.openFirewall;
|
||||||
|
|||||||
@@ -25,21 +25,26 @@ let
|
|||||||
name = "steam";
|
name = "steam";
|
||||||
prep-cmd = [
|
prep-cmd = [
|
||||||
{
|
{
|
||||||
|
do = "${pkgs.cosmic-randr}/bin/cosmic-randr mode HDMI-A-1 1280 800";
|
||||||
|
undo = "${pkgs.cosmic-randr}/bin/cosmic-randr mode HDMI-A-1 1920 1080";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
do = "${pkgs.util-linux}/bin/setsid ${pkgs.steam}/bin/steam steam://open/bigpicture";
|
||||||
undo = "${pkgs.util-linux}/bin/setsid ${pkgs.steam}/bin/steam steam://close/bigpicture";
|
undo = "${pkgs.util-linux}/bin/setsid ${pkgs.steam}/bin/steam steam://close/bigpicture";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
detached = [
|
# detached = [
|
||||||
"${pkgs.util-linux}/bin/setsid ${pkgs.steam}/bin/steam steam://open/bigpicture"
|
# "${pkgs.steam}/bin/steam steam://open/bigpicture"
|
||||||
];
|
# ];
|
||||||
exclude-global-prep-cmd = "false";
|
exclude-global-prep-cmd = "false";
|
||||||
auto-detach = "true";
|
auto-detach = "true";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
name = "1440p Desktop";
|
name = "800p Desktop";
|
||||||
prep-cmd = [
|
prep-cmd = [
|
||||||
{
|
{
|
||||||
do = "''${pkgs.kdePackages.libkscreen}/bin/kscreen-doctor output.DP-4.mode.2560x1440@60";
|
do = "${pkgs.cosmic-randr}/bin/cosmic-randr mode HDMI-A-1 1280 800";
|
||||||
undo = "''${pkgs.kdePackages.libkscreen}/bin/kscreen-doctor output.DP-4.mode.3440x1440@60";
|
undo = "${pkgs.cosmic-randr}/bin/cosmic-randr mode HDMI-A-1 1920 1080";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
exclude-global-prep-cmd = "false";
|
exclude-global-prep-cmd = "false";
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ let
|
|||||||
nixpkgs = inputs.nixpkgs;
|
nixpkgs = inputs.nixpkgs;
|
||||||
inherit self;
|
inherit self;
|
||||||
};
|
};
|
||||||
|
ubootPackages = final.callPackage ../../packages/uboot { };
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
${namespace} = prev.${namespace} // {
|
${namespace} = prev.${namespace} // {
|
||||||
@@ -33,5 +34,7 @@ in
|
|||||||
# RC
|
# RC
|
||||||
linuxPackages_cachyos-rc-lto = cachyosPackages.cachyos-rc-lto;
|
linuxPackages_cachyos-rc-lto = cachyosPackages.cachyos-rc-lto;
|
||||||
linuxPackages_cachyos-rc-lto-znver4 = cachyosPackages.cachyos-rc-lto-znver4;
|
linuxPackages_cachyos-rc-lto-znver4 = cachyosPackages.cachyos-rc-lto-znver4;
|
||||||
|
|
||||||
|
uboot-pi5 = ubootPackages.ubootRaspberryPi5;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
ubootRaspberryPi5 = buildUBoot {
|
ubootRaspberryPi5 = buildUBoot {
|
||||||
defconfig = "rpi_5_defconfig";
|
defconfig = "rpi_arm64_defconfig";
|
||||||
extraMeta.platforms = [ "aarch64-linux" ];
|
extraMeta.platforms = [ "aarch64-linux" ];
|
||||||
filesToInstall = [ "u-boot.bin" ];
|
filesToInstall = [ "u-boot.bin" ];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,46 +12,46 @@ in
|
|||||||
supportedFilesystems = lib.mkForce [ ];
|
supportedFilesystems = lib.mkForce [ ];
|
||||||
};
|
};
|
||||||
|
|
||||||
# hardware.raspberry-pi.config = {
|
${namespace}.hardware.raspberry-pi.config = {
|
||||||
# all = {
|
all = {
|
||||||
# # [all] conditional filter, https://www.raspberrypi.com/documentation/computers/config_txt.html#conditional-filters
|
# [all] conditional filter, https://www.raspberrypi.com/documentation/computers/config_txt.html#conditional-filters
|
||||||
|
|
||||||
# options = {
|
options = {
|
||||||
# # https://www.raspberrypi.com/documentation/computers/config_txt.html#enable_uart
|
# https://www.raspberrypi.com/documentation/computers/config_txt.html#enable_uart
|
||||||
# # in conjunction with `console=serial0,115200` in kernel command line (`cmdline.txt`)
|
# in conjunction with `console=serial0,115200` in kernel command line (`cmdline.txt`)
|
||||||
# # creates a serial console, accessible using GPIOs 14 and 15 (pins
|
# creates a serial console, accessible using GPIOs 14 and 15 (pins
|
||||||
# # 8 and 10 on the 40-pin header)
|
# 8 and 10 on the 40-pin header)
|
||||||
# enable_uart = {
|
enable_uart = {
|
||||||
# enable = true;
|
enable = true;
|
||||||
# value = true;
|
value = true;
|
||||||
# };
|
};
|
||||||
# # https://www.raspberrypi.com/documentation/computers/config_txt.html#uart_2ndstage
|
# https://www.raspberrypi.com/documentation/computers/config_txt.html#uart_2ndstage
|
||||||
# # enable debug logging to the UART, also automatically enables
|
# enable debug logging to the UART, also automatically enables
|
||||||
# # UART logging in `start.elf`
|
# UART logging in `start.elf`
|
||||||
# uart_2ndstage = {
|
uart_2ndstage = {
|
||||||
# enable = true;
|
enable = true;
|
||||||
# value = true;
|
value = true;
|
||||||
# };
|
};
|
||||||
# };
|
};
|
||||||
|
|
||||||
# # Base DTB parameters
|
# Base DTB parameters
|
||||||
# # https://github.com/raspberrypi/linux/blob/a1d3defcca200077e1e382fe049ca613d16efd2b/arch/arm/boot/dts/overlays/README#L132
|
# https://github.com/raspberrypi/linux/blob/a1d3defcca200077e1e382fe049ca613d16efd2b/arch/arm/boot/dts/overlays/README#L132
|
||||||
# base-dt-params = {
|
base-dt-params = {
|
||||||
|
|
||||||
# # https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#enable-pcie
|
# https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#enable-pcie
|
||||||
# pciex1 = {
|
pciex1 = {
|
||||||
# enable = true;
|
enable = true;
|
||||||
# value = "on";
|
value = "on";
|
||||||
# };
|
};
|
||||||
# # PCIe Gen 3.0
|
# PCIe Gen 3.0
|
||||||
# # https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#pcie-gen-3-0
|
# https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#pcie-gen-3-0
|
||||||
# pciex1_gen = {
|
pciex1_gen = {
|
||||||
# enable = true;
|
enable = true;
|
||||||
# value = "3";
|
value = "3";
|
||||||
# };
|
};
|
||||||
|
|
||||||
# };
|
};
|
||||||
|
|
||||||
# };
|
};
|
||||||
# };
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user