NixOS on ARM/Raspberry Pi
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
Only the Raspberry Pi 3 Family is supported upstream, with the AArch64 effort. Other Raspberry Pis are part of @dezgeg's porting efforts to ARMv6 and ARMv7.
The Linux kernel in use, except for the Raspberry Pi 1 family, is the mainline Linux kernel, and not the Raspberry Pi Foundation's fork. This could reduce compatibility with some add-on boards or third-party libraries[expanded explanation needed].
The following table is intended to be updated by the NixOS contributors with the current status of the boards. For a list of products, see the Products Archive.
Board name | Architecture | Support |
---|---|---|
Raspberry Pi 1 | ||
Raspberry Pi 1 Model B | armv6 | C |
Raspberry Pi 1 Model A+ | C* | |
Raspberry Pi 1 Model B+ | C | |
Raspberry Pi Zero | C* | |
Raspberry Pi Zero W | C | |
Raspberry Pi 2 | ||
Raspberry Pi 2 Model B | armv7 | C |
Raspberry Pi 3 | ||
Raspberry Pi 3 Model B | AArch64 + armv7 |
YES |
Raspberry Pi 3 Model B+ | YES | |
Raspberry Pi 3 Model A+ | ? | |
Raspberry Pi 4 | ||
Raspberry Pi 4 Model B | AArch64 + armv7 |
YES* (GitHub issue) |
Support
- YES: Supported architecture by Nixpkgs downstream and tested to be working.
- YES*: Available in Nixpkgs downstream but experimental.
- C: Community supported, and tested to be working.
- C*: Community supported, unverified but should be working.
- ? : Unverified, unknown if it will work.
The Raspberry Pi 3 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.
Raspberry Pi (1)
The ARMv6 image boots out-of-the-box.
Raspberry Pi 2
The ARMv7 image should boot out-of-the-box, though the author hasn't personally tested this.
Raspberry Pi 3 / 3B+
Both the AArch64 and ARMv7 images boot out-of-the-box. Using the 64-bit AArch64 image is highly recommended, as the availability of binaries is much better and allows the use of the 64-bit instruction set.
For the UART console, edit /extlinux/extlinux.conf
on the boot partition of the SD card to set console=ttyS1,115200n8
in the kernel boot parameters, and use the following GPIO Pins with an USB-TTL connector:
GND - 3rd in top row, black cable
GPIO 14 TXD - 4th in top row, white cable
GPIO 15 RXD - 5th in top row, green cable
Use nix-shell -p screen --run "screen /dev/ttyUSB0 115200"
to connect to the console.
{
hardware.enableRedistributableFirmware = true;
networking.wireless.enable = true;
}
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..." #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 #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
nixos-rebuild boot
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
/home/nixos/.ssh/authorized_keys
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.
{
boot.kernelPackages = pkgs.linuxPackages_4_19;
}
Raspberry Pi 4B
Support for the Pi 4 in nixpkgs is still experimental. These configurations will boot (from this PR comment):
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.
Without GPU
/etc/nixos/configuration.nix
{ pkgs, ... }:
{
imports = [ <nixpkgs/nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix> ];
networking.wireless.enable = false;
services.xserver = {
enable = true;
displayManager.slim.enable = true;
desktopManager.gnome3.enable = true;
videoDrivers = [ "fbdev" ];
};
}
With GPU
/etc/nixos/configuration.nix
{ pkgs, ... }:
{
imports = [ <nixpkgs/nixos/modules/installer/cd-dvd/sd-image-raspberrypi4.nix> ];
networking.wireless.enable = false;
hardware.opengl = {
enable = true;
setLdLibraryPath = true;
package = pkgs.mesa_drivers;
};
hardware.deviceTree = {
base = pkgs.device-tree_rpi;
overlays = [ "${pkgs.device-tree_rpi.overlays}/vc4-fkms-v3d.dtbo" ];
};
services.xserver = {
enable = true;
displayManager.slim.enable = true;
desktopManager.gnome3.enable = true;
videoDrivers = [ "modesetting" ];
};
boot.loader.raspberryPi.firmwareConfig = ''
gpu_mem=192
'';
}
Tools
The raspberry tools are available in the raspberrypi-tools
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
'';
Serial console
Your configuration.nix
will need to add console=ttyS1,115200n8
to the boot.kernelParams
configuration to use the serial console.
/etc/nixos/configuration.nix
{ config, pkgs, lib, ... }:
{
boot.kernelParams = [
"console=ttyS1,115200n8"
];
}
If the Raspberry Pi downstream kernel is used the serial interface is named serial0
instead.
Bluetooth
The bluetooth controller is by default connected to the UART device at /dev/ttyAMA0
and needs to be enabled through btattach
:
/etc/nixos/configuration.nix
{ 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";
};
};
}
Camera
For the camera to work, you will need to add the following code to your configuration.nix:
/etc/nixos/configuration.nix
{ config, pkgs, lib, ... }:
{
boot.loader.raspberryPi.enable = true;
# Set the version depending on your raspberry pi.
boot.loader.raspberryPi.version = 3;
# We need uboot
boot.loader.raspberryPi.uboot.enable = true;
# These two parameters are the important ones to get the
# camera working. These will be appended to /boot/config.txt.
boot.loader.raspberryPi.firmwareConfig = ''
start_x=1
gpu_mem=256
'';
}
To make the camera available as v4l device under /dev/video0
the bcm2835-v4l2
kernel module need to be loaded. This can be done by adding the following code to your configuration.nix:
/etc/nixos/configuration.nix
{ config, pkgs, lib, ... }:
{
boot.kernelModules = [ "bcm2835-v4l2" ];
}
Binary Cache
Depending on the architecture used, binary caches availability varies. Binary caches instructions are on the main NixOS on ARM page. The following table describes the architectures supported by each board.
Raspberry Pi 1 | armv6 |
---|---|
Raspberry Pi 2 | armv7 |
Raspberry Pi 3 | armv7 |
AArch64 | |
Raspberry Pi 4 | armv7 |
AArch64 |
Notes about the boot process
It takes approximately 1 minute to boot a Pi 3B.
Raspberry Pi (all versions)
USB keyboards and HDMI displays should work, though some issues have been reported (see Troubleshooting below).
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.
Troubleshooting
Power issues
Especially with the power-hungry Raspberry Pi 3, it is important to have a sufficient enough power supply or weirdness may happen. Weirdness may include:
- Lightning bolt 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
This problem 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.[1] The lightning bolt indicator can be disabled by adding the line avoid_warnings=1
in config.txt[2]
WiFi / WLAN
For a possible solution to 802.11 wireless connectivity issues, see: https://github.com/NixOS/nixpkgs/issues/82462#issuecomment-604634627
HDMI
HDMI issues have been observed on the 18.09 AArch64 image. The display would hang on "Starting Kernel...", then act as if the HDMI cable was unplugged. Re-plugging the HDMI cable after boot fixed the issue, as did a different monitor and HDMI cable.
Early boot messages
To show boot messages from initrd with the mainline kernel, add this to configuration.nix
.
{
boot.initrd.kernelModules = [ "vc4" "bcm2835_dma" "i2c_bcm2835" ];
}
Raspberry Pi 3B+ HDMI output issues
As of 2019/08/19, the u-boot build and kernel build can disagree about the name of the dtb file for the Raspberry Pi 3B+. This happens because the upstream filename has changed, and the built u-boot has hardcoded expectations for the filename to load.
For now, do not use linuxPackages_latest, use the default linuxPackages which is the latest LTS, 4.19, which is known to be compatible.
See #66960.
Additional Troubleshooting
Additional troubleshooting information may be found at elinux.org.