diff --git a/device-pkgs/default.nix b/device-pkgs/default.nix index ec657a4..00a5c82 100644 --- a/device-pkgs/default.nix +++ b/device-pkgs/default.nix @@ -8,12 +8,7 @@ { lib , dtc , gcc -, makeInitrd , nvidia-jetpack -, openssl -, python3 -, runCommand -, writeScript , writeShellApplication }: @@ -25,12 +20,9 @@ let inherit (pkgs.nvidia-jetpack) chipId flashInitrd - l4tVersion mkFlashScript ; - inherit (cfg.flashScriptOverrides) flashArgs fuseArgs partitionTemplate; - # This produces a script where we have already called the ./flash.sh script # with `--no-flash` and produced a file under bootloader/flashcmd.txt. # This requires setting various BOARD* environment variables to the exact @@ -38,44 +30,14 @@ let # # The output of this should be something we can take anywhere and doesn't # require any additional signing or other dynamic behavior - mkFlashCmdScript = args: - let - variant = - if builtins.length cfg.firmware.variants != 1 - then throw "mkFlashCmdScript requires exactly one Jetson variant set in hardware.nvidia-jetson.firmware.variants" - else builtins.elemAt cfg.firmware.variants 0; - - # Use the flash-tools produced by mkFlashScript, we need whatever changes - # the script made, as well as the flashcmd.txt from it - flash-tools-flashcmd = runCommand "flash-tools-flashcmd" - { - # Needed for signing - inherit (cfg.firmware.secureBoot) requiredSystemFeatures; - } '' - export BOARDID=${variant.boardid} - export BOARDSKU=${variant.boardsku} - export FAB=${variant.fab} - export BOARDREV=${variant.boardrev} - ${lib.optionalString (variant.chipsku != null) '' - export CHIP_SKU=${variant.chipsku} - ''} - export CHIPREV=${variant.chiprev} - ${lib.optionalString (variant.ramcode != null) '' - export RAMCODE=${variant.ramcode} - ''} - - ${cfg.firmware.secureBoot.preSignCommands} - - ${mkFlashScript nvidia-jetpack.flash-tools (args // { flashArgs = [ "--no-root-check" "--no-flash" ] ++ (args.flashArgs or flashArgs); }) } - - cp -r ./ $out - ''; - in - import ./flashcmd-script.nix { - inherit lib; - inherit gcc dtc; - flash-tools = flash-tools-flashcmd; + mkFlashCmdScript = args: import ./flashcmd-script.nix { + inherit lib; + inherit gcc dtc; + flash-tools = nvidia-jetpack.flash-tools-flashcmd.override { + inherit mkFlashScript; + mkFlashScriptArgs = args; }; + }; # With either produce a standard flash script, which does variant detection, # or if there is only a single variant, will produce a script specialized to @@ -122,19 +84,7 @@ let text = '' ${mkRcmBootScript { kernelPath = "${config.system.build.kernel}/${config.system.boot.loader.kernelFile}"; - initrdPath = - let - signedFirmwareInitrd = makeInitrd { - contents = [{ object = signedFirmware; symlink = "/signed-firmware"; }]; - }; - in - # The linux kernel supports concatenated initrds where each initrd - # can be optionally compressed with any compression algorithm - # supported by the kernel (initrds don't need to match in - # compression algorithm). - runCommand "combined-initrd" { } '' - cat ${flashInitrd}/initrd ${signedFirmwareInitrd}/initrd > $out - ''; + initrdPath = "${flashInitrd}/initrd"; kernelCmdline = "initrd=initrd console=ttyTCU0,115200"; }} echo @@ -144,46 +94,13 @@ let meta.platforms = [ "x86_64-linux" ]; }; - signedFirmware = runCommand "signed-${hostName}-${l4tVersion}" - { - inherit (cfg.firmware.secureBoot) requiredSystemFeatures; - } - (mkFlashScript nvidia-jetpack.flash-tools { - flashCommands = cfg.firmware.secureBoot.preSignCommands + lib.concatMapStringsSep "\n" - (v: with v; '' - BOARDID=${boardid} BOARDSKU=${boardsku} FAB=${fab} BOARDREV=${boardrev} FUSELEVEL=${fuselevel} CHIPREV=${chiprev} ${lib.optionalString (chipsku != null) "CHIP_SKU=${chipsku}"} ${lib.optionalString (ramcode != null) "RAMCODE=${ramcode}"} ./flash.sh ${lib.optionalString (partitionTemplate != null) "-c flash.xml"} --no-root-check --no-flash --sign ${builtins.toString flashArgs} - - outdir=$out/${boardid}-${fab}-${boardsku}-${boardrev}-${if fuselevel == "fuselevel_production" then "1" else "0"}-${chiprev}-- - mkdir -p $outdir - - cp -v bootloader/signed/flash.idx $outdir/ - - # Copy files referenced by flash.idx - while IFS=", " read -r partnumber partloc start_location partsize partfile partattrs partsha; do - if [[ "$partfile" != "" ]]; then - if [[ -f "bootloader/signed/$partfile" ]]; then - cp -v "bootloader/signed/$partfile" $outdir/ - elif [[ -f "bootloader/$partfile" ]]; then - cp -v "bootloader/$partfile" $outdir/ - else - echo "Unable to find $partfile" - exit 1 - fi - fi - done < bootloader/signed/flash.idx - - rm -rf bootloader/signed - '') - cfg.firmware.variants; - }); - fuseScript = writeShellApplication { name = "fuse-${hostName}"; text = import ./flash-script.nix { inherit lib; inherit (nvidia-jetpack) flash-tools; flashCommands = '' - ./odmfuse.sh -i ${chipId} "$@" ${builtins.toString fuseArgs} + ./odmfuse.sh -i ${chipId} "$@" ${builtins.toString cfg.flashScriptOverrides.fuseArgs} ''; # Fuse script needs device tree files, which aren't already present for @@ -193,15 +110,4 @@ let meta.platforms = [ "x86_64-linux" ]; }; in -{ - inherit - flashScript - fuseScript - initrdFlashScript - mkFlashCmdScript - mkFlashScriptAuto - mkRcmBootScript - rcmBoot - signedFirmware - ; -} +{ inherit flashScript initrdFlashScript fuseScript rcmBoot; } diff --git a/device-pkgs/flash-tools-flashcmd.nix b/device-pkgs/flash-tools-flashcmd.nix new file mode 100644 index 0000000..a138d58 --- /dev/null +++ b/device-pkgs/flash-tools-flashcmd.nix @@ -0,0 +1,39 @@ +{ lib +, pkgs +, runCommand +, cfg +, flash-tools +, mkFlashScript +, mkFlashScriptArgs ? { } +}: + +let + variant = + if builtins.length cfg.firmware.variants != 1 + then throw "mkFlashCmdScript requires exactly one Jetson variant set in hardware.nvidia-jetson.firmware.variants" + else builtins.elemAt cfg.firmware.variants 0; +in +builtins.trace "HERE ${flash-tools.system}" +(runCommand "flash-tools-flashcmd" +{ + # Needed for signing + inherit (cfg.firmware.secureBoot) requiredSystemFeatures; +} '' + export BOARDID=${variant.boardid} + export BOARDSKU=${variant.boardsku} + export FAB=${variant.fab} + export BOARDREV=${variant.boardrev} + ${lib.optionalString (variant.chipsku != null) '' + export CHIP_SKU=${variant.chipsku} + ''} + export CHIPREV=${variant.chiprev} + ${lib.optionalString (variant.ramcode != null) '' + export RAMCODE=${variant.ramcode} + ''} + + ${cfg.firmware.secureBoot.preSignCommands pkgs} + + ${mkFlashScript flash-tools (mkFlashScriptArgs // { flashArgs = [ "--no-root-check" "--no-flash" ] ++ (mkFlashScriptArgs.flashArgs or cfg.flashScriptOverrides.flashArgs); }) } + + cp -r ./ $out +'') diff --git a/modules/flash-script.nix b/modules/flash-script.nix index fe19749..90ea67d 100644 --- a/modules/flash-script.nix +++ b/modules/flash-script.nix @@ -9,8 +9,6 @@ let types; cfg = config.hardware.nvidia-jetpack; - - flashTools = cfg.flasherPkgs.callPackages (import ../device-pkgs { inherit config pkgs; }) { }; in { imports = with lib; [ @@ -136,9 +134,14 @@ in }; preSignCommands = lib.mkOption { - type = types.lines; + type = types.oneOf [ types.lines (types.functionTo types.lines) ]; default = ""; - description = "Additional commands to run before performing operation that involve signing. Can be used to set up environment to interact with an external HSM."; + apply = val: if lib.isFunction val then val else _: val; + description = '' + Additional commands to run before performing operation that + involve signing. Can be used to set up environment to interact + with an external HSM. + ''; }; }; }; @@ -225,8 +228,9 @@ in }; preSignCommands = lib.mkOption { - type = types.lines; + type = types.oneOf [ types.lines (types.functionTo types.lines) ]; default = ""; + apply = val: if lib.isFunction val then val else _: val; description = "Additional commands to run before performing operation that involve signing. Can be used to set up environment to interact with an external HSM."; }; }; @@ -335,15 +339,13 @@ in config = { hardware.nvidia-jetpack.flashScript = lib.warn "hardware.nvidia-jetpack.flashScript is deprecated, use config.system.build.flashScript" config.system.build.flashScript; - hardware.nvidia-jetpack.devicePkgs = (lib.mapAttrs (_: lib.warn "hardware.nvidia-jetpack.devicePkgs is deprecated, use pkgs.nvidia-jetpack") pkgs.nvidia-jetpack) - // (lib.mapAttrs (name: lib.warn "hardware.nvidia-jetpack.devicePkgs.${name} is deprecated, use config.system.build.${name}") flashTools); + hardware.nvidia-jetpack.devicePkgs = (lib.mapAttrs (_: lib.warn "hardware.nvidia-jetpack.devicePkgs is deprecated, use pkgs.nvidia-jetpack") pkgs.nvidia-jetpack); system.build = { - jetsonDevicePkgs = (lib.mapAttrs (_: lib.warn "system.build.jetsonDevicePkgs is deprecated, use pkgs.nvidia-jetpack") pkgs.nvidia-jetpack) - // (lib.mapAttrs (name: lib.warn "system.build.jetsonDevicePkgs.${name} is deprecated, use config.system.build.${name}") flashTools); + jetsonDevicePkgs = (lib.mapAttrs (_: lib.warn "system.build.jetsonDevicePkgs is deprecated, use pkgs.nvidia-jetpack") pkgs.nvidia-jetpack); - inherit (pkgs.nvidia-jetpack) uefiCapsuleUpdate; - inherit (flashTools) flashScript initrdFlashScript fuseScript signedFirmware; + # Left here for compatibility + inherit (pkgs.nvidia-jetpack) uefiCapsuleUpdate flashScript initrdFlashScript fuseScript signedFirmware; }; hardware.nvidia-jetpack.flashScriptOverrides.flashArgs = lib.mkAfter ( diff --git a/overlay-with-config.nix b/overlay-with-config.nix index 530b3ab..5445006 100644 --- a/overlay-with-config.nix +++ b/overlay-with-config.nix @@ -1,10 +1,15 @@ # device-specific packages that are influenced by the nixos config config: + +let + inherit (config.networking) hostName; +in + final: prev: ( let cfg = config.hardware.nvidia-jetpack; - inherit (prev) lib; + inherit (final) lib; tosArgs = { inherit (final.nvidia-jetpack) socType; @@ -12,6 +17,8 @@ final: prev: ( opteePatches = cfg.firmware.optee.patches; extraMakeFlags = cfg.firmware.optee.extraMakeFlags; }; + + flashTools = cfg.flasherPkgs.callPackages (import ./device-pkgs { inherit config; pkgs = final; }) { }; in { nvidia-jetpack = prev.nvidia-jetpack.overrideScope (finalJetpack: prevJetpack: { @@ -72,7 +79,7 @@ final: prev: ( # known path so that the final initrd can be constructed from # outside the context of this nixos config (which has an # aarch64-linux package-set). - if ${lib.getExe finalJetpack.flashFromDevice} /signed-firmware ; then + if ${lib.getExe finalJetpack.flashFromDevice} ${finalJetpack.signedFirmware}; then echo "Flashing platform firmware successful. Rebooting now." sync reboot -f @@ -114,7 +121,9 @@ final: prev: ( final.pkgsBuildBuild.nvidia-jetpack.flash-tools # we need flash-tools for the buildPlatform { # TODO: Remove preSignCommands when we switch to using signedFirmware directly - flashCommands = cfg.firmware.secureBoot.preSignCommands + lib.concatMapStringsSep "\n" + flashCommands = '' + ${cfg.firmware.secureBoot.preSignCommands final} + '' + lib.concatMapStringsSep "\n" (v: with v; "BOARDID=${boardid} BOARDSKU=${boardsku} FAB=${fab} BOARDREV=${boardrev} FUSELEVEL=${fuselevel} CHIPREV=${chiprev} ${lib.optionalString (chipsku != null) "CHIP_SKU=${chipsku}"} ${lib.optionalString (ramcode != null) "RAMCODE=${ramcode}"} ./flash.sh ${lib.optionalString (cfg.flashScriptOverrides.partitionTemplate != null) "-c flash.xml"} --no-flash --bup --multi-spec ${builtins.toString cfg.flashScriptOverrides.flashArgs}" ) @@ -133,7 +142,7 @@ final: prev: ( inherit (cfg.firmware.uefi.capsuleAuthentication) requiredSystemFeatures; } ('' - ${cfg.firmware.uefi.capsuleAuthentication.preSignCommands} + ${cfg.firmware.uefi.capsuleAuthentication.preSignCommands final} bash ${finalJetpack.flash-tools}/generate_capsule/l4t_generate_soc_capsule.sh \ '' + (lib.optionalString cfg.firmware.uefi.capsuleAuthentication.enable '' --trusted-public-cert ${cfg.firmware.uefi.capsuleAuthentication.trustedPublicCertPemFile} \ @@ -144,6 +153,45 @@ final: prev: ( -o $out \ ${finalJetpack.socType} ''); - }); + + signedFirmware = final.runCommand "signed-${hostName}-${finalJetpack.l4tVersion}" + { inherit (cfg.firmware.secureBoot) requiredSystemFeatures; } + (finalJetpack.mkFlashScript finalJetpack.flash-tools { + flashCommands = '' + ${cfg.firmware.secureBoot.preSignCommands final} + '' + lib.concatMapStringsSep "\n" + (v: with v; '' + BOARDID=${boardid} BOARDSKU=${boardsku} FAB=${fab} BOARDREV=${boardrev} FUSELEVEL=${fuselevel} CHIPREV=${chiprev} ${lib.optionalString (chipsku != null) "CHIP_SKU=${chipsku}"} ${lib.optionalString (ramcode != null) "RAMCODE=${ramcode}"} ./flash.sh ${lib.optionalString (cfg.flashScriptOverrides.partitionTemplate != null) "-c flash.xml"} --no-root-check --no-flash --sign ${builtins.toString cfg.flashScriptOverrides.flashArgs} + + outdir=$out/${boardid}-${fab}-${boardsku}-${boardrev}-${if fuselevel == "fuselevel_production" then "1" else "0"}-${chiprev}-- + mkdir -p $outdir + + cp -v bootloader/signed/flash.idx $outdir/ + + # Copy files referenced by flash.idx + while IFS=", " read -r partnumber partloc start_location partsize partfile partattrs partsha; do + if [[ "$partfile" != "" ]]; then + if [[ -f "bootloader/signed/$partfile" ]]; then + cp -v "bootloader/signed/$partfile" $outdir/ + elif [[ -f "bootloader/$partfile" ]]; then + cp -v "bootloader/$partfile" $outdir/ + else + echo "Unable to find $partfile" + exit 1 + fi + fi + done < bootloader/signed/flash.idx + + rm -rf bootloader/signed + '') + cfg.firmware.variants; + }); + + # Use the flash-tools produced by mkFlashScript, we need whatever changes + # the script made, as well as the flashcmd.txt from it + flash-tools-flashcmd = finalJetpack.callPackage ./device-pkgs/flash-tools-flashcmd.nix { + inherit cfg; + }; + } // flashTools); } )