NixOS on ARM/Raspberry Pi: Difference between revisions
imported>Mweinelt |
Add Raspberry Pi 5 to tables (it's already described below) |
||
| (29 intermediate revisions by 14 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'' | ||
| YES | | 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* | |||
|} | |} | ||
''Support'' | ''Support'' | ||
* YES: Supported architecture by Nixpkgs downstream and tested to be working. | * YES: Supported architecture by Nixpkgs downstream and tested to be working. | ||
* C: Community supported, and tested to be working. | * C: Community supported, and tested to be working. | ||
* C*: Community supported, unverified but should be working. | * C*: Community supported, unverified but should be working. | ||
| Line 149: | Line 165: | ||
</syntaxHighlight> | </syntaxHighlight> | ||
=== Raspberry Pi | === 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. | In addition to the usual config, it might be required to enable audio support explicitly in the firmwareConfig. | ||
| Line 226: | Line 198: | ||
If the Raspberry Pi downstream kernel is used the serial interface is named <code>serial0</code> instead. | 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 == | ||
| Line 279: | 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 289: | 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 294: | 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 | 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 301: | Line 357: | ||
* Random hangs | * Random hangs | ||
This | 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> | ||