├── .gitignore ├── templates └── wifi.nix ├── default.nix ├── README.md ├── rpi-zero-w.nix ├── minification.nix ├── LICENSE └── sd-image.nix /.gitignore: -------------------------------------------------------------------------------- 1 | # nix-build output 2 | /result 3 | 4 | # secrets 5 | /wifi.nix 6 | -------------------------------------------------------------------------------- /templates/wifi.nix: -------------------------------------------------------------------------------- 1 | { ... } : 2 | { 3 | networking = { 4 | wireless = { 5 | networks = { 6 | "SSID" = { 7 | psk = "PASSWORD"; 8 | }; 9 | }; 10 | }; 11 | }; 12 | } -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | let 2 | nixos = import { 3 | configuration = { ... }: { 4 | imports = [ 5 | ./sd-image.nix 6 | ]; 7 | }; 8 | }; 9 | in 10 | nixos.config.system.build.sdImage // { 11 | inherit (nixos) pkgs system config; 12 | } 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [NixOS](https://nixos.org/) on the [Raspberry Pi Zero W](https://www.raspberrypi.com/products/raspberry-pi-zero-w/) 2 | 3 | ## Configuration 4 | Copy the files from the `template` directory to the root of the repository and edit to your requirements. 5 | 6 | ## Building 7 | ```bash 8 | nix-build \ 9 | -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/9bc841f.tar.gz # nixos-unstable on 2022-03-23 10 | ``` 11 | 12 | ## Flashing 13 | ```bash 14 | # set correct path for SD card 15 | export SD_CARD=/dev/sda 16 | # inflate image and write to SD card 17 | zstd -dcf result/sd-image/*.img.zst | sudo dd status=progress bs=64k iflag=fullblock oflag=direct of=$SD_CARD && sync && sudo eject $SD_CARD 18 | ``` 19 | 20 | ## Attribution 21 | - inspired by [**illegalprime**/nixos-on-arm](https://github.com/illegalprime/nixos-on-arm) 22 | - big thanks to **sternenseemann** for helping me with cross compilation 23 | -------------------------------------------------------------------------------- /rpi-zero-w.nix: -------------------------------------------------------------------------------- 1 | { config, lib, pkgs, ... }: 2 | 3 | { 4 | boot = { 5 | loader = { 6 | grub.enable = false; 7 | raspberryPi = { 8 | enable = true; 9 | version = 0; 10 | }; 11 | }; 12 | 13 | kernelPackages = pkgs.linuxPackages_rpi0; 14 | consoleLogLevel = lib.mkDefault 7; 15 | 16 | # prevent `modprobe: FATAL: Module ahci not found` 17 | initrd.availableKernelModules = pkgs.lib.mkForce [ 18 | "mmc_block" 19 | ]; 20 | }; 21 | 22 | sdImage = { 23 | populateRootCommands = ""; 24 | populateFirmwareCommands = with config.system.build; '' 25 | ${installBootLoader} ${toplevel} -d ./firmware 26 | ''; 27 | firmwareSize = 64; 28 | }; 29 | 30 | hardware = { 31 | # needed for wlan0 to work (https://github.com/NixOS/nixpkgs/issues/115652) 32 | enableRedistributableFirmware = pkgs.lib.mkForce false; 33 | firmware = with pkgs; [ 34 | raspberrypiWirelessFirmware 35 | ]; 36 | }; 37 | } -------------------------------------------------------------------------------- /minification.nix: -------------------------------------------------------------------------------- 1 | { config, pkgs, lib, ... }: 2 | 3 | with lib; 4 | { 5 | # no GUI environment 6 | environment.noXlibs = mkDefault true; 7 | 8 | # don't build documentation 9 | documentation.info.enable = mkDefault false; 10 | documentation.man.enable = mkDefault false; 11 | 12 | # don't include a 'command not found' helper 13 | programs.command-not-found.enable = mkDefault false; 14 | 15 | # disable firewall (needs iptables) 16 | networking.firewall.enable = mkDefault false; 17 | 18 | # disable polkit 19 | security.polkit.enable = mkDefault false; 20 | 21 | # disable audit 22 | security.audit.enable = mkDefault false; 23 | 24 | # disable udisks 25 | services.udisks2.enable = mkDefault false; 26 | 27 | # disable containers 28 | boot.enableContainers = mkDefault false; 29 | 30 | # build less locales 31 | # This isn't perfect, but let's expect the user specifies an UTF-8 defaultLocale 32 | i18n.supportedLocales = [ (config.i18n.defaultLocale + "/UTF-8") ]; 33 | } 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [year] [fullname] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /sd-image.nix: -------------------------------------------------------------------------------- 1 | { pkgs, config, lib, ... }: 2 | 3 | { 4 | nixpkgs.crossSystem = lib.systems.elaborate lib.systems.examples.raspberryPi; 5 | 6 | imports = [ 7 | 8 | 9 | ./rpi-zero-w.nix 10 | ./minification.nix 11 | ./wifi.nix 12 | ]; 13 | 14 | environment.systemPackages = with pkgs; [ 15 | libraspberrypi 16 | libgpiod gpio-utils 17 | i2c-tools 18 | screen 19 | vim 20 | git 21 | bottom 22 | (python39.withPackages(ps: with ps;[ 23 | adafruit-pureio 24 | pyserial 25 | ])) 26 | ]; 27 | 28 | networking.wireless.enable = true; 29 | 30 | boot = { 31 | loader.raspberryPi.firmwareConfig = '' 32 | dtparam=i2c=on 33 | ''; 34 | kernelModules = [ 35 | "i2c-dev" 36 | ]; 37 | }; 38 | hardware.i2c.enable = true; 39 | 40 | users = { 41 | extraGroups = { 42 | gpio = {}; 43 | }; 44 | extraUsers.pi = { 45 | isNormalUser = true; 46 | initialPassword = "raspberry"; 47 | extraGroups = [ "wheel" "networkmanager" "dialout" "gpio" "i2c" ]; 48 | }; 49 | }; 50 | services.getty.autologinUser = "pi"; 51 | 52 | services.openssh = { 53 | enable = true; 54 | passwordAuthentication = true; 55 | }; 56 | 57 | services.udev = { 58 | extraRules = '' 59 | KERNEL=="gpiochip0*", GROUP="gpio", MODE="0660" 60 | ''; 61 | }; 62 | 63 | system.stateVersion = "nixos-unstable"; 64 | } 65 | --------------------------------------------------------------------------------