Nixos-RaspberryPi
Unopinionated Nix flake for infrastructure, vendor packages, kernel, and some optimized third-party packages for NixOS running on Raspberry Pi devices.
Provides bootloader infrastructure
Manages Raspberry Pi firmware partition /boot/firmware (the path is configurable with boot.loader.raspberryPi.firmwarePath).
Partition provisioning is integrated with bootloader activation scripts, happening on NixOS generation switch, enabling to use deployment tools like nixos-anywhere without any interactive intervention.
Supported boot methods (configurable with boot.loader.raspberryPi.bootloader):
kernelboot(legacy), default for RPi5uboot, default bootloader for all other boardskernel, new generation ofkernelboot, supporting multiple NixOS generations (see #60), default for RPi5 sd-image/installer images, recommended for new installations.
Provides vendor kernel packages with matched firmware
pkgs.linuxAndFirmware.default contains compatible:
linuxPackages_rpi<board model># Linux kernelraspberrypifw# Raspberry firmware, device trees (DTBs), device overlaysraspberrypiWirelessFirmware# wireless firmware
Latest stable version compatible with the board is selected in the flake module by default.
Provides 3rd-party optimised packages
overlays, containing vendor, and optimized packages, like libcamera, ffmpeg, etc.
Usage
Adding flake input
inputs = {
# follow `main` branch of this repository, considered being stable
nixos-raspberrypi.url = "github:nvmd/nixos-raspberrypi/main";
};
# Optional: Binary cache for the flake
nixConfig = {
extra-substituters = [
"https://nixos-raspberrypi.cachix.org"
];
extra-trusted-public-keys = [
"nixos-raspberrypi.cachix.org-1:4iMO9LXa8BqhU+Rpg6LQKiGa2lsNh/j2oiYLNOQ5sPI="
];
};Using the flake to create NixOS configuration
There’re helper functions intended to be used as a drop-in replacement for nixpkgs.lib.nixosSystem:
nixos-raspberrypi.lib.nixosSystemnixos-raspberrypi.lib.nixosSystemFull- same as above, but with RPi-optimized overlays applied globally, this may lead to more rebuildsnixos-raspberrypi.lib.nixosInstaller- same asnixosSystemFullbut with additional installer-specific modules
All of them take the following additional optional arguments:
nixpkgs– default = nixpkgs of the nixos-raspberrypi will be usedtrustCaches– default=true, trust binary caches of nixos-raspberrypi
nixosConfigurations.rpi5-demo = nixos-raspberrypi.lib.nixosSystem {
specialArgs = inputs;
modules = [
{
# Hardware specific configuration, see section below for a more complete
# list of modules
imports = with nixos-raspberrypi.nixosModules; [
raspberry-pi-5.base
raspberry-pi-5.page-size-16k
raspberry-pi-5.display-vc4
raspberry-pi-5.bluetooth
];
}
({ config, pkgs, lib, ... }: {
networking.hostName = "rpi5-demo";
system.nixos.tags = let
cfg = config.boot.loader.raspberryPi;
in [
"raspberry-pi-${cfg.variant}"
cfg.bootloader
config.boot.kernelPackages.kernel.version
];
})
# ...
];
};See also: https://github.com/nvmd/nixos-raspberrypi-demo, Installers and examples.
Choosing modules corresponding to your hardware
See flake.nix, nixosModules for a full list of configuration modules for your hardware. Here is the list of the most important:
imports = with nixos-raspberrypi.nixosModules; [
# Base board support modules
raspberry-pi-02.base
raspberry-pi-3.base
raspberry-pi-4.base
raspberry-pi-5.base
# (Potentially) All boards
usb-gadget-ethernet # Configures USB Gadget/Ethernet - Ethernet emulation over USB
# RPi4:
# import this if you have the display, on rpi4 this is the only display configuration option
raspberry-pi-4.display-vc4
# RPi5:
raspberry-pi-5.page-size-16k # Recommended: optimizations and fixes for issues arising from 16k memory page size (only for systems running default rpi5 (bcm2712) kernel)
# use one of following for the "PrimaryGPU" configuration:
raspberry-pi-5.display-vc4 # "regular" display connected
raspberry-pi-5.display-rp1 # for RP1-connected (DPI/composite/MIPI DSI) display
];Configure the bootloader and firmware (config.txt)
Sane default configuration is provided by the base module for a corresponding Raspberry board, but further configuration is, of course, possible:
Configuration options for the bootloader are in boot.loader.raspberryPi (defined in modules/system/boot/loader/raspberrypi/default.nix).
Raspberry’s config.txt can be configured with hardware.raspberry-pi.config options, see modules/configtxt.nix as an example (this is the default configuration as provided by RaspberryPi OS, but translated to nix format).
Options for advanced usage
Options for a more fine-grained control:
see implementation details in lib/default.nix, lib/internal.nix
Use nixos-raspberrypi.lib.int.nixosSystemRPi instead of nixos-raspberrypi.lib.nixosSystem
Use regular nixpkgs.lib.nixosSystem importing the modules manually, see below
imports = with nixos-raspberrypi.nixosModules; [
# Required: Add necessary overlays with kernel, firmware, vendor packages
nixos-raspberrypi.lib.inject-overlays
# Binary cache with prebuilt packages for the currently locked `nixpkgs`,
# see `devshells/nix-build-to-cachix.nix` for a list
trusted-nix-caches
# Optional: All RPi and RPi-optimised packages to be available in `pkgs.rpi`
nixpkgs-rpi
# Optonal: add overlays with optimised packages into the global scope
# provides: ffmpeg_{4,6,7}, kodi, libcamera, vlc, etc.
# This overlay may cause lots of rebuilds (however many
# packages should be available from the binary cache)
nixos-raspberrypi.lib.inject-overlays-global
];Installer configurations
The flake provides installation SD card images for Raspberry Pi Zero2, 3, 4, and 5, based on https://github.com/nix-community/nixos-images. They have several advantages over the “standard” ones, making the installation more user-friendly: mDNS enabled, iwd for easier wlan configuration, etc.
Note: these images are mutable, i.e. they’re suitable to be used both as an installation media, and as a ready to use system on the sd-card. The partition table will be expanded to use all the available space during the first boot. This can helpful for boards with a single storage device option, like RPi Zero/Zero 2.
Tip: installer images use new generational bootloader for RPi5 by default (see #60), to keep that in your configuration, set
boot.loader.raspberryPi.bootloader = "kernel". This is recommended for new installations.
See nixosConfigurations.rpi{02,4,5}-installer in flake.nix.
SD image can be built with:
nix build .#installerImages.rpi02
nix build .#installerImages.rpi3
nix build .#installerImages.rpi4
nix build .#installerImages.rpi5Randomly generated connection credentials will be displayed on the screen, once the system is booted.
Network access to Raspberry Pi Zero2 (RPi02) boards is also possible via USB Gadget/Ethernet functionality.
Tip: You can optionally replace
# YOUR SSH PUB KEY HERE #incustom-user-configwith your SSH public key to generate the image with your SSH key already baked in
.#nixosConfigurations.rpi{02,4,5}-installer.config.system.build.toplevel are included in the binary cache.
NixOS configuration examples
Sophisticated demo configurations are available in https://github.com/nvmd/nixos-raspberrypi-demo.
Installer configurations can also double as the configuration examples.
Deployment
for example, with nixos-anywhere to the system running installer image (will use disko to set the disks up):
nixos-anywhere --flake .#<system> root@<hostname>"or, to an already running system (to change configuration of it):
nixos-rebuild switch --flake .#<system> --target-host root@<hostname>Alternative ways to get individual packages
An alternative ways to consume individual packages without overlays are:
to get it directly from the flake, it will based on stable nixpkgs without any of other optimisations transitively applied (i.e. only this particular package is optimised):
environment.systemPackages = [
nixos-raspberrypi.packages.aarch64-linux.vlc
];to get it from nixos-raspberrypi.legacyPackages.<system>. Here all overlays are applied.