diff --git a/modules/nixos/hardware/raspberry-pi/default.nix b/modules/nixos/hardware/raspberry-pi/default.nix index 712031e..04f712a 100644 --- a/modules/nixos/hardware/raspberry-pi/default.nix +++ b/modules/nixos/hardware/raspberry-pi/default.nix @@ -66,6 +66,7 @@ let }; firmware = pkgs.${namespace}.raspberrypifw; }; + ubootBuilder = import ./uboot-builder.nix { inherit pkgs; ubootPackage = (if (cfg.variant == "5") then pkgs.${namespace}.uboot-pi5 else pkgs.${namespace}.uboot-pi4); @@ -73,6 +74,12 @@ let extlinuxConfBuilder = config.boot.loader.generic-extlinux-compatible.populateCmd; }; + uefiBuilder = import ./uefi-builder.nix{ + inherit pkgs; + uefiPackage = (if (cfg.variant == "5") then pkgs.${namespace}.uefi-rpi5 else pkgs.${namespace}.uefi-rpi4); + firmwareBuilder = firmwarePopulateCmd; + }; + # Builders exposed via populateCmd, which run on the build architecture populateFirmwareBuilder = import ./firmware-builder.nix { pkgs = pkgs.buildPackages; @@ -106,6 +113,7 @@ let builder = { # system.build.installBootLoader uboot = "${ubootBuilder} -f /boot/firmware -b /boot -c"; + uefi = "${uefiBuilder} -f /boot/firmware -b /boot -c"; }; # firmware: caller must provide `-c ` and `-f ` @@ -128,6 +136,14 @@ in ]; description = "Raspberry Pi variant (4 or 5)"; }; + + bootType = lib.mkOption { + type = lib.types.enum [ + "uefi" + "uboot" + ]; + default = "uboot"; + }; apply-overlays-dtmerge = { enable = lib.mkEnableOption "" // { @@ -166,9 +182,10 @@ in ]); loader = { generic-extlinux-compatible = { - enable = lib.mkDefault true; - useGenerationDeviceTree = lib.mkOverride 60 true; + enable = lib.mkDefault (if cfg.bootType == "uefi" then false else true); + useGenerationDeviceTree = lib.mkOverride 60 (if cfg.bootType == "uefi" then false else true); }; + systemd-boot.enable = (if cfg.bootType == "uefi" then true else false); grub.enable = lib.mkForce false; }; }; @@ -259,10 +276,10 @@ in }; system = { - build.installBootLoader = lib.mkOverride 60 (builder."uboot"); + build.installBootLoader = lib.mkOverride 60 (if cfg.bootType == "uefi" then (builder."uefi") else (builder."uboot")); # todo boot = { loader = { - id = lib.mkOverride 60 ("raspberrypi-uboot"); + id = lib.mkOverride 60 (if cfg.bootType == "uefi" then "raspberrypi-uefi" else "raspberrypi-uboot"); # todo kernelFile = pkgs.stdenv.hostPlatform.linux-kernel.target; }; }; diff --git a/modules/nixos/hardware/raspberry-pi/uefi-builder.nix b/modules/nixos/hardware/raspberry-pi/uefi-builder.nix new file mode 100644 index 0000000..0badac0 --- /dev/null +++ b/modules/nixos/hardware/raspberry-pi/uefi-builder.nix @@ -0,0 +1,19 @@ +{ pkgs +, uefiPackage +, firmwareBuilder +}: + +pkgs.replaceVarsWith { + src = ./uefi-builder.sh; + isExecutable = true; + + replacements = { + inherit (pkgs) bash; + path = pkgs.lib.makeBinPath [ + pkgs.coreutils + ]; + + uefi = uefiPackage; + inherit firmwareBuilder; + }; +} \ No newline at end of file diff --git a/modules/nixos/hardware/raspberry-pi/uefi-builder.sh b/modules/nixos/hardware/raspberry-pi/uefi-builder.sh new file mode 100644 index 0000000..bc2fa54 --- /dev/null +++ b/modules/nixos/hardware/raspberry-pi/uefi-builder.sh @@ -0,0 +1,47 @@ +#! @bash@/bin/sh -e + +shopt -s nullglob + +export PATH=/empty:@path@ + +usage() { + echo "usage: $0 -f -b -c " >&2 + exit 1 +} + +default= # Default configuration, needed for extlinux +# fwtarget=/boot/firmware # firmware target directory +# boottarget=/boot # boot configuration target directory + +echo "uefi-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 \` and \`-f \` must be set" + usage +fi + +copyForced() { + local src="$1" + local dst="$2" + cp -r $src $dst.tmp + mv $dst.tmp $dst +} + +if [ -n "$fwtarget" ]; then + @firmwareBuilder@ -c $default -d $fwtarget + + echo "copying uefi firmware..." + for file in @uefi@; do + copyForced @uefi@/file $fwtarget/ + done +fi + +echo "uefi bootloader installed" \ No newline at end of file diff --git a/packages/raspberrypi/uefi-rpi4/default.nix b/packages/raspberrypi/uefi-rpi4/default.nix new file mode 100644 index 0000000..3fe87e7 --- /dev/null +++ b/packages/raspberrypi/uefi-rpi4/default.nix @@ -0,0 +1,38 @@ +{ + lib, + stdenvNoCC, + fetchzip, +}: + +stdenvNoCC.mkDerivation rec { + pname = "uefi-rpi4"; + version = "1.50"; + + src= fetchzip { + url = "https://github.com/pftf/RPi4/releases/download/v${version}/RPi4_UEFI_Firmware_v${version}.zip"; + stripRoot = false; + hash = "sha256-g8046/Ox0hZgvU6u3ZfC6HMqoTME0Y7NsZD6NvUsp7w="; + }; + + sourceRoot = "."; + + dontBuild = true; + # Firmware blobs do not need fixing and should not be modified + dontFixup = true; + + installPhase = '' + runHook preInstall + mkdir -p "$out/firmware" + + cp -rv "${src}" "$out/firmware" + + runHook postInstall + ''; + + meta = with lib; { + description = "RPI4 UEFI firmware"; + homepage = "https://github.com/pftf/RPi4"; + platforms = platforms.linux; + maintainers = with maintainers; [ ]; + }; +} \ No newline at end of file diff --git a/packages/raspberrypi/uefi-rpi5/default.nix b/packages/raspberrypi/uefi-rpi5/default.nix new file mode 100644 index 0000000..08ab676 --- /dev/null +++ b/packages/raspberrypi/uefi-rpi5/default.nix @@ -0,0 +1,38 @@ +{ + lib, + stdenvNoCC, + fetchzip, +}: + +stdenvNoCC.mkDerivation rec { + pname = "uefi-rpi5"; + version = "0.3"; + + src= fetchzip { + url = "https://github.com/worproject/rpi5-uefi/releases/download/v${version}/RPi5_UEFI_Release_v${version}.zip"; + stripRoot = false; + hash = "sha256-bjEvq7KlEFANnFVL0LyexXEeoXj7rHGnwQpq09PhIb0="; + }; + + sourceRoot = "."; + + dontBuild = true; + # Firmware blobs do not need fixing and should not be modified + dontFixup = true; + + installPhase = '' + runHook preInstall + mkdir -p "$out/firmware" + + cp -rv "${src}" "$out/firmware" + + runHook postInstall + ''; + + meta = with lib; { + description = "RPI5 UEFI firmware"; + homepage = "https://github.com/pftf/RPi4"; + platforms = platforms.linux; + maintainers = with maintainers; [ ]; + }; +} \ No newline at end of file