How to update firmware on steam deck?

hiii everyone, absolute noob here… :face_exhaling:

previously, i used jovian-nixos (flake) to update the steam deck firmware…

flake.nix

{
  inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
  inputs.jovian-nixos.url = "github:jovian-experiments/jovian-nixos";
  inputs.jovian-nixos.inputs.nixpkgs.follows = "nixpkgs";

  outputs = inputs: {
    nixosConfigurations.HOST = inputs.nixpkgs.lib.nixosSystem {
      # specialArgs.inputs = inputs; # inherit inputs -- i need this sometimes!
      modules = [
        ./configuration.nix
        inputs.jovian-nixos.nixosModules.default
      ];
    };
  };
}

…then these two become available…

jovian.devices.steamdeck.autoUpdate
jovian.devices.steamdeck.enableFwupdBiosUpdates

…where (afaik) the steamdeck-firmware package has a jupiter-biosupdate command, which i can (supposedly) use (with sudo) to do the firmware update thing. they also create a systemd service, but i prefer to do things manually

…however, those two options are a part of a flake the rest of which i dont need, cos to make it work, i have to download and install the flake in its entirety, eventually disabling 99% of it anyway.

but thats silly! what i need is just the fwupd part (or however it does it) from it, so that i could type in a command and update my steam deck’s firmware…

…but it is a NIGHTMARE! :sob: :sob:

it appears to me that i have to build (?) or import (?) a module/package/whatever thingie, cos it looks like a complete package, right..?

i have no idee how to do it via flakes at the moment, so im doing it the dirty (imperative) way (or is it?):

okay, so i git clone the repo and copy just the jupiter-hw-support directory to where my configuration.nix is, so that i can use a relative path in imports, right..? so that that directory becomes an extension of my configuration, right..? ultimately making those two options and the command available on my system, right..?

configuration.nix

# ...

  imports = [
    ./hardware-configuration.nix
    ./jupiter-hw-support
  ];

# ...

but thats not right! a wild anonymous lambda has appeared!

error:
       … while calling the 'seq' builtin
         at /nix/store/xh9wfbn9d64hmavam66yhl5vmkp0wi87-source/lib/modules.nix:361:18:
          360|         options = checked options;
          361|         config = checked (removeAttrs config [ "_module" ]);
             |                  ^
          362|         _module = checked (config._module);

       … while evaluating an expression to select '_module.check' on it
         at /nix/store/xh9wfbn9d64hmavam66yhl5vmkp0wi87-source/lib/modules.nix:297:12:
          296|       checkUnmatched =
          297|         if config._module.check && config._module.freeformType == null && merged.unmatchedDefns != [ ] then
             |            ^
          298|           let

       (stack trace truncated; use '--show-trace' to show the full trace)

       error: function 'anonymous lambda' called with unexpected arguments 'config', 'options', 'specialArgs', 'modulesPath', '_class' and '_prefix'
       at /nix/store/9k9kjrbqq3fprfknlblh2wagd9qq0v3z-source/jupiter-hw-support/default.nix:1:1:
            1| { lib
             | ^
            2| , stdenv

yeah, i also tried ./jupiter-hw-support/default.nix, and… nix… (haha get it? nothing happened, i got properly lambda’d…)

in utter disbelief of/from my belief that this would work, i started searching for other ways:

Updating the firmware works with fwupd.

ooh! well, thats easy. i think i can–

fwupdmgr update
Devices with no available firmware updates:
 • System Firmware
 • TS256GMTE300S
 • UEFI Device Firmware
 • UEFI Device Firmware
No updatable devices

oh… right. uhm. cheers, archwiki.

edit: valve is frequent with firmware, plus its been years since ive used steamos. it just has to have some pending…

and then i found that steam deck isnt even supported:

alrightie, then. seems like there is no other way… time to face unspeakable horrors:

so… this is how and when this feature was implemented… woah… that is crazy… :face_with_spiral_eyes:

oh? let’s check it out, then, cheers! :smiley: :+1:

o-oh. okay. huh. wha..? thats a bit complicated! :anxious_face_with_sweat:

edit: this bit is from the steamdeck-bios-fwupd package btw. yeah, i dont like when a module isnt the same name as the package… like… yknow?

i was hoping i could just… put something in services.fwupd.* options and make it see that there are, in fact, updates that, i guess, just have no remotes to download from. but there are none that jovian-nixos uses! yeah, it doesnt use services.fwupd.* at all (as far as i have gathered without a github account which doesnt allow me to search for a specific match in the code…). what does it even do, then, and how..?

is it… this one? i think it is, yeah! alright. so… what now..? i am so lost… :confounded_face:

…i just want the jupiter-biosupdate command from that flake to update the firmware of my steam deck (lcd btw), without anything else… please no steam, steamos or kernel packages that i have to compile for hours on end (even with cachix) that i am unable to prevent by disabling (even if everything is false)…

…is there, by any chance, a way to point to a specific directory to “flake it” from via my flake.nix, so that i just get the firmware updater, and/or is there a way to do the imports thingie properly, so that the mysterious lambda becomes friends with me, or maybe there is a completely different method that im (obviously) unaware of..?

edit: oh, it just occurred to me… its but an idea… cant i use a relative path to jupiter-hw-support from my flake modules? oh, wait. thats stupid. it needs flake.nix and flake.lock in the directory, which are unique, riiight… but maybe i can do something like that via nixosModules..? like, for example, i have seen people change the .default end part of it or something…

…i have no idea what im talking about btw, though i think i get it, correct me if im wrong: so, .default and/or default.nix are the mitochondria (powerhouse) of the flake, so-called packages are flake-equivalent of pkgs. (which become available immediately with inputs.<flake>.url), so-called modules are flake-equivalent of nixos options (which come by default with ...?), and finally nixosModules is what glues them together, right? or maybe the latter two are interchangeable, idk. so i think this gluing is the problem, yeah? can you separate a specific package somehow..? UGH! here i am again asking a question i think i’ve already asked and was answered to but i still dont understand…

so, what is available, then? well,

nix flake metadata

(also known as the deprecated nix flake info)

...
├───jovian-nixos: github:jovian-experiments/jovian-nixos/544a1396c5a75fe832ae7a2a097bb760701ccd50
│   Last modified: 2026-01-14 16:17:07
│   ├───nix-github-actions: github:zhaofengli/nix-github-actions/e418aeb728b6aa5ca8c5c71974e7159c2df1d8cf
│   │   Last modified: 2024-10-23 17:31:40
│   │   └───nixpkgs follows input 'jovian-nixos/nixpkgs'
│   └───nixpkgs follows input 'nixpkgs'
...

yeah… i cant bang two rocks together out of this one, i dont think. bloody hell, i have to have the entire flake, dont i? wow…

anyway, i tried summoning more lambdas:

configuration.nix

  # ...
  environment.systemPackages = [
    # ...
    # inputs.jovian-nixos.packages.${pkgs.stdenv.hostPlatform.system}.default # INCORRECT BUZZER SOUND!
    # inputs.jovian-nixos.packages.${pkgs.stdenv.hostPlatform.system}.jupiter-hw-support # WHAT WERE YOU THINKING?!
    # inputs.jovian-nixos.packages.${pkgs.stdenv.hostPlatform.system}.steamdeck-firmware # MISSION FAILED!
    # ...
  ];
  # ...

…there is no packages defined (not my problem, because it works with everything else). does this mean that it is (aggressively) a modules thingie, then, no “package sets”..? congrats me, yay!!

also, bit of a rant (you love it), but last year i tried this, i only needed the .${pkgs.system}. part in the middle, now it has been “replaced” with .${pkgs.stdenv.hostPlatform.system}., WHY?! that looks unfriendly to me. what do we even need that one for anyway? according to me, a human, an intuitive format should be like inputs.<flake>.pkgs.<package>, where inputs. should be optional, unless you want verbosity (or you are a nerd who does something crazy with it). everything else, as always, should be sorted out somewhere else in the depths of the flake/package/modules themselves, far away from the “final configuration” where you JUST want something to SIMPLY install! similarly, i dont like .override at all - it should be just pkgs.<package> = { <attr> = <value>; } without any additional () brackets… but im just a nobody who doesnt really code, so i dont know if this is difficult or not…

edit2: alright, at the moment, i have two choices here: A) “just @#$% install the @#$% flake, mate!” or B) dual boot with steamos (actually, DONT! it wipes the efi/esp/boot partitions on every update, so install on an external drive!)… both of which sound… not great. welp, im not gonna fallback to any of these just yet, but it sure is tempting! maybe i just cant accept the fact that its just simply impossible and i must go through 5 hours of 100% loaded cpu everytime that flake updates (its not the only one i have) just to have a command..?

edit3: yeah, it appears i am still on F7A0131,

cos the service in question (that i forgot to disable) failed (again) when i tried updating my firmware manually (yes, i have installed the flake…)…

jupiter-biosupdate: Auto-update to F7A0133 was attempted within the last 24 hours, skipping for now

no, no and NO, i will NOT wait “24 hours”, you stupid clanker, that is insufferable, cos it will turn into weeks, into months, cos i just lost all motivation right here… cheers. :melting_face:

i dont know when’s the next time im going to try this again. and i think “flashing” the .fd file is going to be a torturous one if im gonna mess it up (i will). siiigh. do i need it anyway, actually?

Added 'Memory Power Down' option.

oh. wait, thats useful, actually, if its what i think it is. i often have to reset the nvram, cos i get blank screens sometimes, so i do heaps of shutdowns and reboots (up to a 100 per day, thats right, i am on my 2500th generation this year btw).

edit4: sorry, had to change the (topmost) links to/for the options, cos… its actually insanely hard to find them… yep.

MANY thanks in advance!!! CHEERS! :sweat_smile: :sob:

p.s. i really hope im not repeating myself, but this is objectively the most difficult flake i have ever seen. I AM TERRIBLY SORRY! but the instructions are impossibly incomprehensible!!! i had to figure out how to add it as a flake, cos they suggest an overlay! :melting_face:

p.p.s. sorry this is my first time using “permanent links”, i hope it is alright..? there was no button for “temporary links”, so… yknow… unclear interface (of github) and whatnot, yeah?

1 Like