NixOS on ARM/Raspberry Pi: Difference between revisions

imported>Lopsided98
I have tested a Raspberry Pi 1 Model B
Tennox (talk | contribs)
Add Raspberry Pi 5 to tables (it's already described below)
 
(37 intermediate revisions by 18 users not shown)
Line 22: Line 22:
|-
|-
!colspan="2" class="title"|Raspberry Pi 4
!colspan="2" class="title"|Raspberry Pi 4
|-
!Architecture
|AArch64 + ARMv7
|-
! colspan="2" |Raspberry Pi 5
|-
|-
!Architecture
!Architecture
Line 83: Line 88:
| Raspberry Pi 4 Model B
| Raspberry Pi 4 Model B
| AArch64<br /> ''+ armv7''
| AArch64<br /> ''+ armv7''
| ? ([https://github.com/NixOS/nixpkgs/issues/63720 GitHub issue])
| YES
|-
!colspan="3" style="text-align: left;"|Raspberry Pi 400
|-
| Raspberry Pi 400
| AArch64<br /> ''+ armv7''
| Yes (only with kernel >= 6.1)
|-
! colspan="3" |Raspberry Pi 5
|-
|Raspberry Pi 5
|AArch64<br /> ''+ armv7''
|C*
|}
|}


Line 118: Line 135:
Use <code>nix-shell -p screen --run "screen /dev/ttyUSB0 115200"</code> to connect to the console.  
Use <code>nix-shell -p screen --run "screen /dev/ttyUSB0 115200"</code> to connect to the console.  
{{note|The mainline kernel (tested with nixos kernel 4.18.7) [https://github.com/raspberrypi/linux/wiki/Upstreaming#downstream-drivers does not include support for cpu frequency scaling] on the Raspberry Pi. To get higher clock speed, set [https://www.raspberrypi.org/documentation/configuration/config-txt/overclocking.md <code><nowiki>force_turbo=1</nowiki></code>] in <code>/boot/config.txt</code> }}
{{note|The mainline kernel (tested with nixos kernel 4.18.7) [https://github.com/raspberrypi/linux/wiki/Upstreaming#downstream-drivers does not include support for cpu frequency scaling] on the Raspberry Pi. To get higher clock speed, set [https://www.raspberrypi.org/documentation/configuration/config-txt/overclocking.md <code><nowiki>force_turbo=1</nowiki></code>] in <code>/boot/config.txt</code> }}
{{note|As of today (2018-01-13) the stable channel contains fixes for wifi for both the stable and the latest linux kernel. Check out {{pull|53747}} }}
 
<syntaxhighlight lang=nix>
<syntaxhighlight lang=nix>
{
{
Line 125: Line 142:
}
}
</syntaxhighlight>
</syntaxhighlight>
==== HDMI output issue with kernel 5.4 (NixOS 20.03 or NixOS unstable) ====
(Unverified for 5.5 or 5.6)
Some users have reported that the 5.4 kernel "hung at Starting kernel..." {{issue|82455}}. In all cases where it was possible to investigate, it was found that the device did boot, but that the HDMI out didn't function as expected.
It looks like it may be a setup-dependent issue, as a 20.03 image with 5.4 was verified as working.
If your setup is having the issue, first report on {{issue|82455}} with the Raspberry Pi model (important to note whether it is a plus or non-plus) and the kind of display used with the HDMI out, including whether it is using adapters or not.
Then, you can work around the issue by configuring your system to use the 4.19 kernel (previous LTS) using one of the following tricks.
# Use the serial console to configure the system, and <code>nixos-rebuild boot</code> it.
# Use a 19.09 image, specify the kernel in its configuration and upgrade to 20.03
# Boot the image, poweroff blindly using a keyboard, edit on another computer <code>/home/nixos/.ssh/authorized_keys</code> from the SD to add your key file, chmod as 600, unmount, boot the Raspberry Pi and find it on your network by some means.
<syntaxHighlight>
{
  boot.kernelPackages = pkgs.linuxPackages_4_19;
}
</syntaxHighlight>
=== Raspberry Pi 4 ===
''See'' [[NixOS on ARM/Raspberry Pi 4]]
=== Raspberry Pi 5===
''See'' [[NixOS on ARM/Raspberry Pi 5]]
== Audio ==
In addition to the usual config, it might be required 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>}}


== Serial console==
== Serial console==
Line 138: Line 196:
}
}
</nowiki>}}
</nowiki>}}
If the Raspberry Pi downstream kernel is used the serial interface is named <code>serial0</code> instead.
== Bluetooth ==
The bluetooth controller is by default connected via a UART device (<code>/dev/ttyAMA0</code> on the RPi4) and needs to be enabled through <code>btattach</code>:
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{ pkgs, ... }:
{
  systemd.services.btattach = {
    before = [ "bluetooth.service" ];
    after = [ "dev-ttyAMA0.device" ];
    wantedBy = [ "multi-user.target" ];
    serviceConfig = {
      ExecStart = "${pkgs.bluez}/bin/btattach -B /dev/ttyAMA0 -P bcm -S 3000000";
    };
  };
}
</nowiki>}}
== Camera ==
== Camera ==


For the camera to work, you will need to add the following code to your configuration.nix:  
For the camera to work, you will need to add the following code to your configuration.nix:  


{{note| Two pull requests ({{pull|38490}} and {{pull|38342}}) are required to make this configuration.nix and the camera working.}}
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{ config, pkgs, lib, ... }:
{ config, pkgs, lib, ... }:
Line 191: Line 269:
| AArch64
| AArch64
|}
|}
== Kernel selection ==
By default NixOS uses the official Linux kernel released by kernel.org (a "mainline" kernel, e.g. <code>pkgs.linuxPackages</code>). This works fine on a Raspberry Pi, and is the better-tested option.
It is also possible to use a kernel released by the Raspberry Pi Foundation (a "vendor" kernel, e.g. <code>pkgs.linuxPackages_rpi3</code>). This may be preferable if you're using an add-on board that the mainline kernel does not have drivers for.
You can select your kernel by setting <code>boot.kernelPackages</code>.


== Notes about the boot process ==
== Notes about the boot process ==
The Raspberry Pi's stage 1 bootloader (in ROM) loads the stage 2 bootloader (bootcode.bin) from the first VFAT partition on the SD card. The NixOS aarch64 SD card image includes a VFAT partition (labelled <code>FIRMWARE</code>) with the stage 2 bootloader and configuration that loads U-Boot. U-Boot then continues from the second partition (labelled <code>NIXOS_SD</code>).


It takes approximately 1 minute to boot a Pi 3B.
It takes approximately 1 minute to boot a Pi 3B.
There are 2 primary options for booting a Raspberry Pi:
=== Boot option 1: <code>boot.loader.generic-extlinux-compatible</code> ===
This configuration is the most similar to the way that NixOS works on other devices. The downside is that NixOS won't attempt to manage anything associated with the first and second stage bootloaders (e.g. config.txt).
You can feel better about this by thinking about this configuration as similar to BIOS settings.
<syntaxhighlight lang="nix">
boot.loader.grub.enable = false;
boot.loader.generic-extlinux-compatible.enable = true;
</syntaxhighlight>
=== Boot option 2: <code>boot.loader.raspberryPi</code> ===
{{warning| This option has been deprecated in https://github.com/NixOS/nixpkgs/pull/241534}}
This configuration assumes that the VFAT firmware partition is mounted to /boot. If it isn't, options like <code>boot.loader.raspberryPi.firmwareConfig</code> will write their configuration to the wrong partition and have no effect.
<syntaxhighlight lang="nix">
boot.loader.grub.enable = false;
boot.loader.raspberryPi.enable = true;
boot.loader.raspberryPi.uboot.enable = true;
</syntaxhighlight>


=== Raspberry Pi (all versions) ===
=== Raspberry Pi (all versions) ===
Line 201: Line 314:


Using the 3.3v serial port via the pin headers (exact location depends on hardware version) will get u-boot output and, when configured, a Linux kernel console.
Using the 3.3v serial port via the pin headers (exact location depends on hardware version) will get u-boot output and, when configured, a Linux kernel console.
== Device trees ==
Raspberry Pi add-on hardware often requires a device tree overlay. On other OSes this is usually set up using a <code>dtoverlay=</code> option in config.txt on the firmware partition. This approach can be made to work on NixOS with some combination of bootloader and kernel, but it may be easier and more explicit to use NixOS' <code>hardware.deviceTree</code> option to compile the overlay directly into the device tree.
A device tree config looks something like this:
<syntaxhighlight lang="nix">
hardware.deviceTree = {
    enable = true;
    overlays = [
      {
        name = "hifiberry-dacplus";
        dtsText = ''
/dts-v1/;
/plugin/;
/ {
      compatible = "brcm,bcm2835";
// ... etc.
'';
      };
    ];
  };
</syntaxhighlight>
This will apply the overlay to all <code>.dtb</code> files with a matching <code>compatible</code> line.
After rebooting you can check if the overlay has been applied by looking for it in the output of <code>dtc --sort /proc/device-tree</code>.
dtoverlay may fail with <code>FDT_ERR_NOTFOUND</code> on some Raspberry Pi device tree overlays. In this case dtmerge should be used instead. There is a Nix overlay to use dtmerge for applying device tree overlays: https://github.com/NixOS/nixos-hardware/blob/429f232fe1dc398c5afea19a51aad6931ee0fb89/raspberry-pi/4/apply-overlays-dtmerge.nix


== Troubleshooting ==
== Troubleshooting ==
Line 206: Line 350:
=== Power issues ===
=== Power issues ===


Especially with the power-hungry Raspberry Pi 3, 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:
Especially with the power-hungry Raspberry Pi 3, it is important to have a [https://www.raspberrypi.org/documentation/hardware/raspberrypi/power/README.md sufficient enough power supply] or unexpected behaviour may occur; this may include:


* Lightning bolt on HDMI output "breaking" the display.
* Lightning bolt on HDMI output "breaking" the display.
Line 213: Line 357:
* Random hangs
* Random hangs


This problem is a hard problem. It is caused by the Raspberry Pi warning about power issues, but the current drivers (as of  
This is a hard problem. It is caused by the Raspberry Pi warning about power issues, but the current drivers (as of  
Linux 4.14) have a hard time dealing with it properly. If the power supply is rated properly AND the cable is not incurring too much power losses, it may be required to disable the lightning bolt indicator so the display driver isn't messed up.<ref>https://logs.nix.samueldr.com/nixos/2017-12-20#1513784657-1513784714;</ref> The lightning bolt indicator can be disabled by adding the line <code>avoid_warnings=1</code> in config.txt<ref>https://www.raspberrypi.org/documentation/configuration/config-txt/README.md</ref>
Linux 4.14) have a hard time dealing with it properly. If the power supply is rated properly AND the cable is not incurring too much power losses, it may be required to disable the lightning bolt indicator so the display driver isn't messed up.<ref>https://logs.nix.samueldr.com/nixos/2017-12-20#1513784657-1513784714;</ref> The lightning bolt indicator can be disabled by adding the line <code>avoid_warnings=1</code> in config.txt<ref>https://www.raspberrypi.org/documentation/configuration/config-txt/README.md</ref>


{{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|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.}}
===WiFi / WLAN===
For a possible solution to 802.11 wireless connectivity issues, see: https://github.com/NixOS/nixpkgs/issues/82462#issuecomment-604634627


===HDMI===
===HDMI===