Cleanup firmware in nixosConfigurations

I am generating a nixOS image using a flake with nixosConfigurations.

The flake is very simple, I am not setting any special options.

The folder result/firmware seems to contain heaps of firmware files the I don’t need.

How can I clean up that folder? I did not find an easy way to override the config.system.build.toplevel derivation.

I tried overriding the firmware and linux-firmware package like this:

      overlays = {
        nixpkgs.overlays = [
          zimt.overlays.default
          backtracking.overlays.default
          (final: prev: {
            linux-firmware = (pkgs.callPackage ../../../packages/firmware/default.nix {});
          })
        ];
      };

But the files are still there.

What am I missing?

Those are likely installed by hardware.enableRedistributableFirmware.

I’d set that to false (it’s not enabled by default, but it’s part of the default generated config).

If you want to then re-enable specific firmware files you’d need to use pkgs.buildEnv or pkgs.symlinkJoin to extract the specific sub-set of pkgs.linux-firmware; there are no options you could change with .override to only build a subset.

I’d also recommend using the hardware.firmware option instead of nixpkgs.overlays, just to be explicit about what you’re doing; an overlay to override a package an option happens to use is so spaghetti. But I know people use overlays as a cure-all. If all you have is a hammer, everything’s a nail…

Okay, I’ll give it a shot, thanks!

Yet, out of curiousity, how could I achieve what I want leaving enableRedistributableFirmware on?

How could I make this piece work?

      overlays = {
        nixpkgs.overlays = [
          (final: prev: {
            linux-firmware = (pkgs.callPackage ../../../packages/firmware/default.nix {});
          })
        ];
      };

I mean, all that option does is add a bunch of packages to hardware.firmware: nixpkgs/nixos/modules/hardware/all-firmware.nix at 2c3e5ec5df46d3aeee2a1da0bfedd74e21f4bf3a · NixOS/nixpkgs · GitHub

If you wanted to, you could replace the packages added to the list with empty mock packages to make them do nothing. So something like this:

final: prev: let
  mock-firmware = pkgs.runCommand "mock-firmware" ''
    mkdir -p $out/lib/firmware
  '';
in 
  pkgs.lib.listToAttrs (map (name: {
    inherit name;
    value = mock-firmware;
  }) [
    "linux-firmware"
    "intel2200BGFirmware"
    "rtl8192su-firmware"
    "rt5677-firmware"
    "rtl8761b-firmware"
    "zd1211fw"
    "alsa-firmware"
    "sof-firmware"
    "libreelec-dvb-firmware"
    "raspberrypiWirelessFirmware"
    # Remember to update this list when
    # any packages are added; no, we cannot
    # use the value of `hardware.firmware` since
    # the overlay applies to attributes, and `pname`
    # doesn't necessarily match the attribute name
  ])

But that’s ridiculously stupid. Just make the list empty to begin with, either by disabling all the options that add packages to it, or with lib.mkForce [ ].


If you’re asking how you’d replace the firmware packages with one you wrote, you can do this:

{
  hardware = {
    enableRedistributableFirmware = false;
    firmware = [
      (pkgs.callPackage ../../../packages/firmware/default.nix { })
    ];
  };
}

… or this, if you don’t want to merge the list of firmwares; I don’t recommend it, the above is much cleaner in case you have another module that wants to add firmware. It’s better to know where your firmware packages are coming from and why they’re there:

{
  hardware.firmware = lib.mkForce [
    (pkgs.callPackage ../../../packages/firmware/default.nix { })
  ];
}

I don’t think this is correct, by the way, I doubt any of your overlays are working. Show your flake.nix if you want help with that.