NixOS on ARM/Raspberry Pi 4

From NixOS Wiki
Revision as of 00:28, 9 January 2021 by imported>Samueldr (Removed stray newline)
Raspberry Pi 4 Family
(Image not available)
Manufacturer Raspberry Pi Foundation
Architecture AArch64
Bootloader Custom or U-Boot
Boot order Configurable; SD, USB, Netboot
Maintainer
Raspberry Pi 4B
SoC BCM2711

The Raspberry Pi family of devices is a series of single-board computers made by the Raspberry Pi Foundation. They are all based on Broadcom System-on-a-chip (SOCs).

Status

Note: The Raspberry Pi 4 is currently unsupported though the NixOS distribution provides upstream beta-quality images.

The default Linux kernel in use, is the Raspberry Pi Foundation's fork. This will change for the mainline kernel once its support for the Raspberry Pi 4 Family is good enough to allow the user to boot, configure, and rebuild a system.

The Raspberry Pi 4 Family is only supported as AArch64. Use as armv7 is community supported.

Board-specific installation notes

First follow the generic installation steps to get the installer image and install using the installation and configuration steps.

Until the generic image works, a temporary device-specific image is build on Hydra. Note that this image is not using u-boot, but rather the Raspberry Pi specific bootloader configuration.

Minimal configuration

Using nixos-generate-config will not generate the required minimal configuration. Change the lines about booting to the following (from this PR comment) (and don't forget to set a user).

/etc/nixos/configuration.nix
{ pkgs, ... }:

{
  # Assuming this is installed on top of the disk image.
  fileSystems = {
    "/" = {
      device = "/dev/disk/by-label/NIXOS_SD";
      fsType = "ext4";
    };
  };
  boot.loader.grub.enable = false;
  boot.loader.raspberryPi.enable = true;
  boot.loader.raspberryPi.version = 4;
  # Mainline doesn't work yet
  boot.kernelPackages = pkgs.linuxPackages_rpi4;

  # ttyAMA0 is the serial console broken out to the GPIO
  boot.kernelParams = [
    "8250.nr_uarts=1" # may be required only when using u-boot
    "console=ttyAMA0,115200"
    "console=tty1"
  ];

  # Required for the Wireless firmware
  hardware.enableRedistributableFirmware = true;
}

USB boot

For USB booting to work properly, firmware update might be needed:

nix-shell -p raspberrypi-eeprom
rpi-eeprom-update -d -a

Now reboot the device so it can update the firmware from boot partition.

When running from USB device without SD card present, kernel spams log about missing SD card, workaround for this is to set:

boot.loader.raspberryPi.firmwareConfig = "dtparam=sd_poll_once=on";

GPU support

The following configuration samples are built on the assumption that they are added to an already working configuration. They are not complete configurations.

Without GPU

/etc/nixos/configuration.nix
{
  services.xserver = {
    enable = true;
    displayManager.lightdm.enable = true;
    desktopManager.gnome3.enable = true;
    videoDrivers = [ "fbdev" ];
  };
}

With GPU

Warning: The device tree overlays provided with the RaspberryPi Kernel don't seem to be compatible with dtc. We might need to add support for the `dtmerge` tool as an alternative, or ask upstream to fix their overlays (or dtc).

See https://github.com/NixOS/nixpkgs/pull/107637#issuecomment-752635965 for details.

/etc/nixos/configuration.nix
{ pkgs, ... }:

{
  hardware.opengl = {
    enable = true;
    setLdLibraryPath = true;
    package = pkgs.mesa_drivers;
  };
  hardware.deviceTree = {
    kernelPackage = pkgs.linux_rpi4;
    overlays = [ "${pkgs.device-tree_rpi.overlays}/vc4-fkms-v3d.dtbo" ];
  };
  services.xserver = {
    enable = true;
    displayManager.lightdm.enable = true;
    desktopManager.gnome3.enable = true;
    videoDrivers = [ "modesetting" ];
  };
  boot.loader.raspberryPi.firmwareConfig = ''
    gpu_mem=192
  '';
}

Tools

The raspberry tools are available in the libraspberrypi package and include commands like vcgencmd to measure temperature and CPU frequency.

Audio

In addition to the usual config, you will need to enable audio support explicitly in the firmwareConfig.

/etc/nixos/configuration.nix
  sound.enable = true;
  hardware.pulseaudio.enable = true;

  boot.loader.raspberryPi.firmwareConfig = ''
    dtparam=audio=on
  '';

Troubleshooting

Power issues

The Raspberry Pi 4B is as power-hungry, if not more, as its predecessors. It is important to have a sufficient enough power supply or weirdness may happen. Weirdness may include:

  • Lightning bolt icon on HDMI output "breaking" the display.
  • Screen switching back to u-boot text
    • Fixable temporarily when power is sufficient by switching VT (alt+F2 / alt+F1)
  • Random hangs
Note: A properly rated USB power supply, AND a good cable are necessary. The cable has to be short enough to not incur power losses through the length. Do note that thin and cheap cables usually have thinner copper wires, which in turn accentuates power losses.

Note that the Type-C USB receptacle for the Raspberry Pi 4B does not implement Power Delivery (USB PD). This means that it is limited to whatever the power supply will provide when not negotiating power, which is most likely 5V at some undetermined power level.

First Install Issues

Make sure that you resize the NIXOS_SD partition and expand the filesystem so that the initial install will have enough space for the /nix/store. Assuming you only have the SD card plugged in:

$ sudo parted resizepart 2 100%
$ sudo resize2fs /dev/disk/by-label/NIXOS_SD

You might also have to add the nix channels manually.

$ sudo mkdir -p /nix/var/nix/profiles/per-user/root/channels/
$ nix-channel --add https://nixos.org/channels/nixos-unstable nixpkgs
$ nix-channel --update

Finally, the nixos-install program might fail to copy your configuration.nix and hardware-configuration.nix files automatically to /etc/nixos/. You can do this yourself by sudo cp /mnt/etc/nixos/* /etc/nixos/.