Including channels and configuration.nix in a sd-image

Hi folks, I’ve been experimenting with building an sd-image for my raspberry pi v1. I’m using the following configuration.nix after some trial and error:

Summary
{
  imports = [
    <nixpkgs/nixos/modules/profiles/minimal.nix>
    <nixpkgs/nixos/modules/installer/sd-card/sd-image.nix>
  ];

  nixpkgs.overlays = [
    (self: super: {
      # btrfs-progs by default builds with Python bindings. There's a
      # long-standing issue where python bindings fail to
      # cross-compile because the build system's headers are used
      # instead (and I'm building on x86_64 which has long ints of
      # 64bits, but armv6l has long ints of 32bits and that causes
      # mayhem). Simply disable python bindings. A braver soul would
      # find a way to fix Python's build system I guess.
      btrfs-progs = super.btrfs-progs.overrideAttrs (old: old // {
        configureFlags = [ "--disable-python" ];
        installFlags = [];
      });
    })
    # https://github.com/NixOS/nixpkgs/issues/126755#issuecomment-869149243
    (self: super: {
      makeModulesClosure = x:
        super.makeModulesClosure (x // { allowMissing = true; });
    })
  ];

  boot.loader.grub.enable = false;
  boot.loader.generic-extlinux-compatible.enable = true;

  boot.consoleLogLevel = lib.mkDefault 7;
  boot.kernelPackages = pkgs.linuxKernel.packages.linux_rpi1;

  networking.useDHCP = true;

  sdImage = {
    populateFirmwareCommands = let
      configTxt = pkgs.writeText "config.txt" ''
        # Prevent the firmware from smashing the framebuffer setup done by the mainline kernel
        # when attempting to show low-voltage or overtemperature warnings.
        avoid_warnings=1
        [pi0]
        kernel=u-boot-rpi0.bin
        [pi1]
        kernel=u-boot-rpi1.bin
      '';
      in ''
        (cd ${pkgs.raspberrypifw}/share/raspberrypi/boot && cp bootcode.bin fixup*.dat start*.elf $NIX_BUILD_TOP/firmware/)
        cp ${pkgs.ubootRaspberryPiZero}/u-boot.bin firmware/u-boot-rpi0.bin
        cp ${pkgs.ubootRaspberryPi}/u-boot.bin firmware/u-boot-rpi1.bin
        cp ${configTxt} firmware/config.txt
      '';
    populateRootCommands = ''
      mkdir -p ./files/boot
      ${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot
    '';
  };

  nixpkgs.crossSystem.system = "armv6l-linux";

  services.openssh.enable = true;

  # put your own configuration here, for example ssh keys:
  users.extraUsers.root.openssh.authorizedKeys.keys = [
     "REDACTED"
  ];

  system.stateVersion = "22.05";
}

Now I’m running into a bit of an issue: the Pi boots just fine, I can ssh to it. I tried running nix-shell -p hello and it failed as the channels were not present, so I ran nix-channel --update. After that, nix-shell -p hello seems to works, but it wants to rebuild the entire universe (a newer linux, clang, etc.). That will take ages on the Pi.

My issue: the sd-image includes no configuration.nix and no channels. Ideally I’d like to build this with the configuration.nix I used to cross-compile, and the channels as they exist on my desktop. At least this would guarantee that I won’t have to rebuild the kernel and clang if I forgot to update channels before building (as long as I don’t update them on the Pi as well). Is there a way to say “cross compile and copy the channels and configuration into the sd-image”?

Thanks,

1 Like

This file may be helpful for the channels part. It’s how the nixos installer does it. The configuration itself shouldn’t be too difficult to add on top of that.

1 Like

Did you ever figure this one out?

Sorry, I may have, but I don’t remember. I gave up on my pi1 a long time ago, and I don’t use channels anymore.