{ config, pkgs, lib, ... }:
{
  boot = {
    loader.generic-extlinux-compatible.enable = false;
    loader.raspberryPi = {
      enable = true;
      version = 4;
      firmwareConfig = lib.mkDefault ''
        gpu_mem=256
        dtparam=audio=on
        # disable uart, enable bluetooth
        enable_uart=0
      '';
    };
    kernelParams = [
      "verbose" "shell_on_fail"
      "elevator=deadline"
      # ethernet causes panics every few boots,
      # reboot automatically after 5s
      "panic=5"
    ];
    initrd = {
      network = {
        enable = true;
        flushBeforeStage2 = false;
        # DHCP: 120 tries every 1 second
        udhcpc.extraArgs = [ "-t" "120" "-T" "1" ];
      };
      supportedFilesystems = lib.mkForce [
        "nfs"
      ];
      includeDefaultModules = false;
      availableKernelModules = [
        "genet"
        "usbhid"
      ];
    };

    tmp.useTmpfs = true;
  };

  hardware.deviceTree.enable = true;

  environment.systemPackages = with pkgs; [
    libraspberrypi
    raspberrypi-eeprom
  ];

  services.journald.extraConfig = ''
    Storage=volatile
  '';

  networking.networkmanager.enable = false;

  system.build.tftproot = pkgs.runCommand "tftproot-${config.networking.hostName}" {} ''
    mkdir -p $out

    cp -rs ${pkgs.raspberrypifw}/share/raspberrypi/boot/* $out/
    ln -sf ${config.system.build.kernel}/Image $out/kernel8.img
    ln -sf ${config.system.build.initialRamdisk}/initrd $out/initrd.img

    chmod u+w $out/overlays
    rm -fr $out/*.dtb $out/overlays
    for f in $(find ${config.hardware.deviceTree.package}/ -name \*.dtb) ; do
      ln -s $f $out/
    done

    cat << EOF > $out/config.txt
    kernel=kernel8.img
    initramfs initrd.img followkernel
    arm_64bit=1
    ${toString config.boot.loader.raspberryPi.firmwareConfig}
    EOF

    echo "dwc_otg.lpm_enable=0 init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}" > $out/cmdline.txt
  '';
}
