NixOS on ARM/Raspberry Pi 4: Difference between revisions

imported>Tobias.bora
No edit summary
Update Pi 4 installation and profile guidance: cover optional modules, device-tree overlay limits, EEPROM updates, and HDMI connector names
 
(52 intermediate revisions by 25 users not shown)
Line 1: Line 1:
{{ARM/breadcrumb}}
{{ARM/breadcrumb}}
<div class="infobox">
<div class="infobox">
{|class="table"
{| class="table"
!colspan="2" class="title"|Raspberry Pi 4 Family
! colspan="2" class="title" | Raspberry Pi 4 family
|-
|-
|colspan="2"|(Image not available)
| colspan="2" | [[File:Raspberry_Pi_4,_2_GB_RAM_version_4.jpg|frameless|256px|A Raspberry Pi 4.]]
|-
|-
!Manufacturer
! Manufacturer
|Raspberry Pi Foundation
| Raspberry Pi Ltd
|-
|-
!Architecture
! Architecture
|AArch64
| AArch64
|-
|-
!Bootloader
! Boot method
|Custom or U-Boot
| Raspberry Pi EEPROM and firmware, U-Boot, and extlinux
|-
|-
!Boot order
! SoC
|Configurable; SD, USB, Netboot
| BCM2711
|-
|-
!Maintainer
! Variants
|
| Pi 4B, Pi 400, CM4, and CM4S
|-
!colspan="2" class="title"|Raspberry Pi 4B
|-
!SoC
|BCM2711
|}
|}
</div>
</div>
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 ==
The '''Raspberry Pi 4''' family works with the generic AArch64 SD image and has a board profile in <code>nixos-hardware</code>. The profile selects a Raspberry Pi downstream kernel and includes the Pi 4 initrd modules and Wi-Fi and Bluetooth firmware. It requests full KMS and provides optional modules for Pi 4 peripherals and HATs.


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


== Board-specific installation notes ==
Use the generic AArch64 SD image described on the [[NixOS on ARM/Raspberry Pi#Installation|family page]]. It contains boot files for Pi 4B, Pi 400, CM4, and CM4S.<ref name="generic-image">[https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/installer/sd-card/sd-image-aarch64.nix Nixpkgs generic AArch64 SD image module]</ref> In a flake, import <code>nixos-hardware.nixosModules.raspberry-pi-4</code>. With channels, import <code>&lt;nixos-hardware/raspberry-pi/4&gt;</code>. The [[NixOS on ARM/Raspberry Pi#Board profiles|family page]] provides complete examples and explains that a profile is not a bootable image.


First follow the [[NixOS_on_ARM#Installation|generic installation steps]] to get the installer image and install using the [[NixOS_on_ARM#NixOS_installation_.26_configuration|installation and configuration steps]].
== Profile defaults ==


The Raspberry Pi 4B works with  the [https://hydra.nixos.org/job/nixos/trunk-combined/nixos.sd_image.aarch64-linux generic SD image].
The Pi 4 profile selects a pinned kernel from Raspberry Pi's downstream Linux tree and limits generation device trees to <code>bcm2711-rpi-*.dtb</code>. Its initrd includes the BCM2711 PCIe and VL805 reset drivers. The profile also installs pinned Wi-Fi and Bluetooth firmware, disables GRUB, and enables extlinux generation.<ref name="profile">[https://github.com/NixOS/nixos-hardware/blob/master/raspberry-pi/4/default.nix nixos-hardware Raspberry Pi 4 profile]</ref>


Sample instructions for [https://nix.dev/tutorials/installing-nixos-on-a-raspberry-pi installing NixOS on a Raspberry Pi] are available at nix.dev.
The shared <code>config.txt</code> defaults request full VC4 KMS with <code>dtoverlay=vc4-kms-v3d</code>.<ref name="config-defaults">[https://github.com/NixOS/nixos-hardware/blob/master/raspberry-pi/common/config-txt-defaults.nix nixos-hardware Raspberry Pi config.txt defaults]</ref> The compatibility option <code>hardware.raspberry-pi."4".fkms-3d.enable</code> is disabled by default and is not the normal graphics path.


{{warning| Note that the Raspberry Pi 4 has two HDMI outputs, and apparently sometimes the user prompt for the console/TTY is displayed on HDMI 1 while the boot process is displayed on HDMI 0. So if after the message "Welcome on NixOs" at the end of phase 2 your screen goes black/disconnects, try to use the other HDMI port. See the related bug [https://github.com/NixOS/nixpkgs/issues/179701 here].}}
== Optional hardware modules ==


=== Configuration ===
The Pi 4 profile imports the following options, all disabled by default. Each path starts with <code>hardware.raspberry-pi."4".</code>.


{{outdated|These instructions were written when the generic image did not work. Using the vendor kernel may be desirable under some conditions<sup>[which?]</sup>}}
{| class="wikitable"
 
! Hardware
Using <code>nixos-generate-config</code> will not generate the required minimal configuration.
! Option suffixes
 
! Purpose
For better GPU Support, remember to add the nixos-hardware channel:
|-
<code>nixos-hardware https://github.com/NixOS/nixos-hardware/archive/master.tar.gz</code>
| Audio and Bluetooth
 
| <code>audio.enable</code>, <code>bluetooth.enable</code>
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
| Adds a build-time audio node or Bluetooth UART pin routing. Enable the corresponding NixOS audio or Bluetooth services separately.
{ config, pkgs, lib, ... }:
|-
 
| USB controllers
{
| <code>dwc2.enable</code>, <code>dwc2.dr_mode</code>, <code>xhci.enable</code>
# This configuration worked on 09-03-2021 nixos-unstable @ commit 102eb68ceec
| Configures the DWC2 dual-role controller or the BCM2711 XHCI node.
# The image used https://hydra.nixos.org/build/134720986
|-
 
| GPIO, I2C, and PWM
  boot = {
| <code>gpio.enable</code>, <code>i2c0.enable</code>, <code>i2c1.enable</code>, <code>pwm0.enable</code>
    kernelPackages = pkgs.linuxPackages_rpi4;
| Adds GPIO permissions, enables an I2C controller, or enables PWM0 on GPIO 18. Both I2C options also accept <code>frequency</code>.
    tmpOnTmpfs = true;
|-
    initrd.availableKernelModules = [ "usbhid" "usb_storage" ];
| Official display
    # ttyAMA0 is the serial console broken out to the GPIO
| <code>backlight.enable</code>, <code>touch-ft5406.enable</code>
    kernelParams = [
| Adds support nodes for the original official touch display and its FT5406 controller.
        "8250.nr_uarts=1"
|-
        "console=ttyAMA0,115200"
| HATs and capture devices
        "console=tty1"
| <code>digi-amp-plus.enable</code>, <code>poe-hat.enable</code>, <code>poe-plus-hat.enable</code>, <code>tv-hat.enable</code>, <code>tc358743.enable</code>
        # A lot GUI programs need this, nearly all wayland applications
| Configures the listed audio, PoE fan, TV tuner, or HDMI-to-CSI hardware. The PoE options expose fan temperature and hysteresis settings.
        "cma=128M"
|-
    ];
| LEDs
  };
| <code>leds.eth.disable</code>, <code>leds.act.disable</code>, <code>leds.pwr.disable</code>
 
| Disables the selected Ethernet, activity, or power LED behaviour on supported Pi 4 boards.
  boot.loader.raspberryPi = {
|}
    enable = true;
    version = 4;
  };
  boot.loader.grub.enable = false;
 
  # Required for the Wireless firmware
  hardware.enableRedistributableFirmware = true;
 
  networking = {
    hostName = "nixos-raspi-4"; # Define your hostname.
    networkmanager = {
      enable = true;
    };
  };
 
  nix = {
    autoOptimiseStore = true;
    gc = {
      automatic = true;
      dates = "weekly";
      options = "--delete-older-than 30d";
    };
    # Free up to 1GiB whenever there is less than 100MiB left.
    extraOptions = ''
      min-free = ${toString (100 * 1024 * 1024)}
      max-free = ${toString (1024 * 1024 * 1024)}
    '';
  };
  system.stateVersion = "20.09";
}
</nowiki>}}
=== USB boot ===
 
For USB booting to work properly, a firmware update might be needed:
 
{{commands|<nowiki>
$ nix-shell -p raspberrypi-eeprom
$ rpi-eeprom-update -d -a
</nowiki>}}
 
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:
 
{{outdated|This will only work when not using U-Boot. Configuring through an overlay will be required.}}
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{
  boot.loader.raspberryPi.firmwareConfig = "dtparam=sd_poll_once=on";
}
</nowiki>}}
=== 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 ====
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{
  services.xserver = {
    enable = true;
    displayManager.lightdm.enable = true;
    desktopManager.gnome3.enable = true;
    videoDrivers = [ "fbdev" ];
  };
}
</nowiki>}}
==== With GPU ====
 
In [https://github.com/NixOS/nixos-hardware/pull/261 nixos-hardware#261] a new option has been added to use the <code>fkms-3d</code> overlay. This will only work with the vendor kernel.
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{ pkgs, ... }:
 
{
  imports = [
    .../nixos-hardware/raspberry-pi/4
  ];
 
  hardware.raspberry-pi."4".fkms-3d.enable = true;
 
  services.xserver = {
    enable = true;
    displayManager.lightdm.enable = true;
    desktopManager.gnome3.enable = true;
  };
}
</nowiki>}}
==== Tools ====
 
The raspberry tools are available in the <code>libraspberrypi</code> package and include commands like <code>vcgencmd</code> to measure temperature and CPU frequency.
 
==== Audio ====
 
{{outdated|An equivalent change that works with U-Boot through <code>hardware.deviceTree</code> is needed.}}
 
In addition to the usual config, you will need to enable audio support explicitly in the firmwareConfig.
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
  sound.enable = true;
  hardware.pulseaudio.enable = true;
 
  boot.loader.raspberryPi.firmwareConfig = ''
    dtparam=audio=on
  '';
</nowiki>}}
 
=== Gpio ===
Add gpio group and change permission for all users in new gpio group.
Now all users in gpio group have access to /dev/gpiomem and to gpio pins via sysfs.
 
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
  # add gpio group
  users.groups.gpio = {};
 
  # udev rule for gpio
  services.udev.extraRules = ''
    SUBSYSTEM=="bcm2835-gpiomem", KERNEL=="gpiomem", GROUP="gpio",MODE="0660"
    SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", RUN+="${pkgs.bash}/bin/bash -c 'chown root:gpio  /sys/class/gpio/export /sys/class/gpio/unexport ; chmod 220 /sys/class/gpio/export /sys/class/gpio/unexport'"
    SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add",RUN+="${pkgs.bash}/bin/bash -c 'chown root:gpio /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value ; chmod 660 /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value'"
  '';
 
  # add user with gpio group
  users = {
    mutableUsers = false;
    users.mygpiouser = {
      isNormalUser = true;
      password = "mygpiouserpasswd";
      extraGroups = [ "wheel" "gpio" ];
    };
  };
 
</nowiki>}}
 
=== HDMI-CEC ===
 
A few bits and pieces for using HDMI-CEC on the Pi4:
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{ pkgs, ... }:
 
{
  # an overlay to enable raspberrypi support in libcec, and thus cec-client
  nixpkgs.overlays = [
    (self: super: { libcec = super.libcec.override { inherit (self) libraspberrypi; }; })
  ];
 
  # install libcec, which includes cec-client (requires root or "video" group, see udev rule below)
  # scan for devices: `echo 'scan' | cec-client -s -d 1`
  # set pi as active source: `echo 'as' | cec-client -s -d 1`
  environment.systemPackages = with pkgs; [
    libcec
  ];


  services.udev.extraRules = ''
The exact option definitions are in the [https://github.com/NixOS/nixos-hardware/tree/master/raspberry-pi/4 Pi 4 profile directory]. Some options apply only to the Pi 4B and exclude Compute Module variants.
    # allow access to raspi cec device for video group (and optionally register it as a systemd device, used below)
    SUBSYSTEM=="vchiq", GROUP="video", MODE="0660", TAG+="systemd", ENV{SYSTEMD_ALIAS}="/dev/vchiq"
  '';


  # optional: attach a persisted cec-client to `/run/cec.fifo`, to avoid the CEC ~1s startup delay per command
=== Device-tree overlay limitation ===
  # scan for devices: `echo 'scan' > /run/cec.fifo ; journalctl -u cec-client.service`
  # set pi as active source: `echo 'as' > /run/cec.fifo`
  systemd.sockets."cec-client" = {
    after = [ "dev-vchiq.device" ];
    bindsTo = [ "dev-vchiq.device" ];
    wantedBy = [ "sockets.target" ];
    socketConfig = {
      ListenFIFO = "/run/cec.fifo";
      SocketGroup = "video";
      SocketMode = "0660";
    };
  };
  systemd.services."cec-client" = {
    after = [ "dev-vchiq.device" ];
    bindsTo = [ "dev-vchiq.device" ];
    wantedBy = [ "multi-user.target" ];
    serviceConfig = {
      ExecStart = ''${pkgs.libcec}/bin/cec-client -d 1'';
      ExecStop = ''/bin/sh -c "echo q > /run/cec.fifo"'';
      StandardInput = "socket";
      StandardOutput = "journal";
      Restart="no";
  };
}
</nowiki>}}


== Notes about the boot process ==
These optional modules use <code>hardware.deviceTree.overlays</code>, while <code>hardware.raspberry-pi.configtxt.settings</code> uses a separate firmware-time mechanism. The mechanisms can conflict. See [[NixOS on ARM/Raspberry Pi#Kernels and device trees|Kernels and device trees]]. [https://github.com/NixOS/nixos-hardware/issues/1946 nixos-hardware issue #1946] tracks the migration.


Unless using an extremely early WIP image, the Raspberry Pi 4B boots using the U-Boot platform firmware.
The base profile leaves <code>hardware.raspberry-pi."4".apply-overlays-dtmerge.enable</code> disabled. Some peripheral modules enable it when they require the Raspberry Pi <code>dtmerge</code> implementation. Do not enable it as a general installation step.


=== Updating U-Boot/Firmware ===
== EEPROM and USB boot ==


{{commands| <nowiki>
The Pi 4 bootloader lives in a rewritable EEPROM. USB or network boot may require a suitable EEPROM release and <code>BOOT_ORDER</code>. The <code>hardware.raspberry-pi.firmware</code> module manages files on the FAT firmware partition but does not update this EEPROM. Use the <code>raspberrypi-eeprom</code> package and the [https://www.raspberrypi.com/documentation/computers/configuration.html#update-bootloader-version official update procedure].
$ nix-shell -p raspberrypi-eeprom
$ sudo mount /dev/disk/by-label/FIRMWARE /mnt
$ sudo BOOTFS=/mnt FIRMWARE_RELEASE_STATUS=stable rpi-eeprom-update -d -a
</nowiki>}} [https://nix.dev/tutorials/installing-nixos-on-a-raspberry-pi#updating-firmware source]


== Troubleshooting ==
The Pi 4B has two micro-HDMI outputs. Linux names the connector marked <code>HDMI0</code> as <code>HDMI-A-1</code> and <code>HDMI1</code> as <code>HDMI-A-2</code>.<ref name="display">[https://www.raspberrypi.com/documentation/computers/configuration.html#display-settings Raspberry Pi display documentation]</ref> If a text console or display manager appears on an unexpected output, check both connectors and use a kernel <code>video=</code> parameter when a fixed mapping is required.


=== Power issues ===
For intermittent Wi-Fi reachability problems, see the [[NixOS on ARM/Raspberry Pi#Wi-Fi power saving|power-saving note on the family page]].


The Raspberry Pi 4B is as power-hungry, if not more, as its predecessors. It is important to have a [https://www.raspberrypi.org/documentation/hardware/raspberrypi/power/README.md sufficient enough power supply] or ''weirdness'' may happen. Weirdness may include:
== See also ==


* Lightning bolt icon on HDMI output "breaking" the display.
* [[NixOS on ARM/Raspberry Pi]]
* Screen switching back to u-boot text
* [[NixOS on ARM/Installation]]
** Fixable temporarily when power is sufficient by switching VT (alt+F2 / alt+F1)
* [https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#raspberry-pi-boot-eeprom Raspberry Pi boot EEPROM documentation]
* 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.}}
== References ==


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.
<references />


<hr />
[[Category:NixOS on ARM]]