NixOS on raspberry pi zero w

Hello. Thank you for this great topic.
So I decided to try build my own image for rpi zero w.
I basically used provided flake and try to compile on aws aarch64 machine.

However, without luck.
System is 23.11 and this issue (unable to unpack archive) seems to be weird.

What I missed? NixOS on aws is just some random selected comunity ami so maybe should I start to dig here?

error: builder for '/nix/store/vy12b7lmf3y548whsjfv3m81vlm8g2zz-libpng-apng-armv6l-unknown-linux-gnueabihf-1.6.40.drv' failed with exit code 1;
       last 3 log lines:
       > unpacking sources
       > unpacking source archive /nix/store/jpqz1p52xw3jlhc8w143v92k0iaar2i4-libpng-1.6.40.tar.xz
       > do not know how to unpack source archive /nix/store/jpqz1p52xw3jlhc8w143v92k0iaar2i4-libpng-1.6.40.tar.xz
       For full logs, run 'nix log /nix/store/vy12b7lmf3y548whsjfv3m81vlm8g2zz-libpng-apng-armv6l-unknown-linux-gnueabihf-1.6.40.drv'.
error: 1 dependencies of derivation '/nix/store/2q5j823rwvrr8431y8dyg9i2w3cdrbsr-freetype-armv6l-unknown-linux-gnueabihf-2.13.2.drv' failed to build
error: 1 dependencies of derivation '/nix/store/9v3h4811dqsqc65yrvwq4y7mbyz7s8k0-fontconfig-armv6l-unknown-linux-gnueabihf-2.14.2.drv' failed to build
error: 1 dependencies of derivation '/nix/store/kdw5vbdbnp6djlqggmcw02lniqkay0zd-fontconfig-conf.drv' failed to build
error: 1 dependencies of derivation '/nix/store/li54ky7kl6yhjq204rkba2aig66x2hqk-system-path.drv' failed to build
error (ignored): error: cannot unlink '/run/user/0/nix-build-binutils-armv6l-unknown-linux-gnueabihf-2.40.drv-0/binutils-2.40/ld/.deps': Directory not empty
error (ignored): error: cannot unlink '/run/user/0/nix-build-libtasn1-armv6l-unknown-linux-gnueabihf-4.19.0.drv-0': Directory not empty
error: 1 dependencies of derivation '/nix/store/ban8rmijp7l85kvhgy5jg3qsrynahgm1-nixos-system-nixos-23.11.20240115.b8dd8be.drv' failed to build
error: 1 dependencies of derivation '/nix/store/sg2x74hlkf721z4355s8sy3zs9sqwm1y-ext4-fs.img.zst-armv6l-unknown-linux-gnueabihf.drv' failed to build
error: 1 dependencies of derivation '/nix/store/34ywqprscl80bmpwcpc2ihggnrk021wa-nixos-sd-image-23.11.20240115.b8dd8be-armv6l-linux.img-armv6l-unknown-linux-gnueabihf.drv' failed to build

[root@ip-172-31-16-53:~/flake]# nix --extra-experimental-features nix-command  log /nix/store/vy12b7lmf3y548whsjfv3m81vlm8g2zz-libpng-apng-armv6l-unknown-linux-gnueabihf-1.6.40.drv
warning: The interpretation of store paths arguments ending in `.drv` recently changed. If this command is now failing try again with '/nix/store/vy12b7lmf3y548whsjfv3m81vlm8g2zz-libpng-apng-armv6l-unknown-linux-gnueabihf-1.6.40.drv^*'
@nix { "action": "setPhase", "phase": "unpackPhase" }
unpacking sources
unpacking source archive /nix/store/jpqz1p52xw3jlhc8w143v92k0iaar2i4-libpng-1.6.40.tar.xz
do not know how to unpack source archive /nix/store/jpqz1p52xw3jlhc8w143v92k0iaar2i4-libpng-1.6.40.tar.xz

Not sure about that error, I think I also saw this onetime, but don’t know anymore how I got it and also what I did to solve it. Could you maybe provide more logs (nix log /nix/store/vy12b7lmf3y548whsjfv3m81vlm8g2zz-libpng-apng-armv6l-unknown-linux-gnueabihf-1.6.40.drv) and the exact flake (of course redact secrets) you’re using?

Thank you very much for that tip. That did the trick in combination with my initial device tree overlay. I2C now works.

I then tried to analyze if I can get the &i2c1 version to work. Reading about your two links I now understand that these &[node] things are semantic sugar to extend other nodes. I then tried to use that in combination with the hardware.i2c.enable = true but I still had no success as I already predicted since this doesn’t change the dtb file (I already analyzed this in my last post). I then tried to remove the -i2c suffix and still had the hardware.i2c.enable = true set which works now. So

I2C TL;DR

To enable i2c on a raspberry pi zero, use:

          hardware.deviceTree = {
            enable = true;
            overlays = [
              {
                name = "enable-i2c1-device";
                dtsText = ''
                  /dts-v1/;
                  /plugin/;
                  / { compatible = "brcm,bcm2835"; };
                  &i2c1 { status = "okay"; };
                '';
              }
            ];
          };
          hardware.i2c.enable = true;

WIFI

I now also wifi to work by either

wpa_supplicant:

          hardware.firmware = [ pkgs.raspberrypiWirelessFirmware ];
          networking = {
            wireless = {
              enable = true;

              networks = {
                [SSID] = {
                  psk = "[PSK]";
                };
              };
            };
          };

or using iwd:

          systemd.services.iwd.serviceConfig.Restart = "always";
          hardware.firmware = [ pkgs.raspberrypiWirelessFirmware ];
          networking = {
            networkmanager.wifi.backend = "iwd";
            wireless.iwd.enable = true;
          };
          boot.extraModprobeConfig = ''
            options cfg80211 ieee80211_regdom="DE"
          '';

And then connect to the wifi using the following commands:

$ iwctl
# list
# station wlan0 scan
# station wlan0 get-networks
# station wlan0 connect [ssid]

This will save the config for the next boot to: /var/lib/iwd.

5 Likes

@rnhmjoj do you have, by any chance, an idea about my compile issue in Cross-compile cups for armv6l-linux . I have no idea what is happening there.

Output of nix log is provided in previous comment.
Just:
do not know how to unpack source archive /nix/store/jpqz1p52xw3jlhc8w143v92k0iaar2i4-libpng-1.6.40.tar.xz

Not sure if xz missing in system or something.

And my flake is basically yours:

{
  description = "Build image";
  inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
  outputs = { self, nixpkgs }: rec {
    nixosConfigurations.rpi2 = nixpkgs.lib.nixosSystem {
      modules = [
        "${nixpkgs}/nixos/modules/installer/sd-card/sd-image-raspberrypi.nix"
        ({ lib, pkgs, modulesPath, ... }: {
          nixpkgs.config.allowUnsupportedSystem = true;
          nixpkgs.hostPlatform.system = "armv6l-linux";
          nixpkgs.buildPlatform.system = "aarch64-linux"; #If you build on x86 other wise changes this.
          # ... extra configs as above

          system.stateVersion = "23.11";

          nixpkgs.overlays = [
            (final: super: {
              llvmPackages = super.llvmPackages_14;
              cmake = super.cmake.overrideAttrs (old: { env.NIX_CFLAGS_COMPILE = "-latomic"; });
            })
          ];

          boot = {
            initrd.includeDefaultModules = false;
            initrd.kernelModules = [ "ext4" "mmc_block" ];
            supportedFilesystems = lib.mkForce [ "vfat" "ext4" ];
          };
          disabledModules = [
            "${modulesPath}/profiles/all-hardware.nix"
            "${modulesPath}/profiles/base.nix"
          ];


          # setup a user
          users.mutableUsers = false;
          users.users = {
            user = {

...
no chsnges here

I’m building it with:
nix build --extra-experimental-features nix-command --extra-experimental-features flakes --impure --update-input nixpkgs .#images.rpi2

Message came from:
pkgs/stdenv/generic/setup.sh

However, I need to dig around more. For example where unpackCmd come from.

UPDATE:
Seems like I’m not only one stuck with libpng :).

UPDATE 2:
Should be solved but…

What worked for me was to write an overlay using the .tar.gz packaged sources:

(final: prev: {libpng = prev.libpng.overrideAttrs ( old: { src = prev.fetchurl {
      url = "mirror://sourceforge/libpng/libpng-1.6.40.tar.gz";
      hash = "sha256-j3ILNjqghoPJvypWMjb0UxOvLFXVQrVIGuF92NGDu0I=";
    };});})

With this change, I was able to get the sd-image to build (cross-compilation on a x86-64). I updated the nixpkgs bug with the same information.

1 Like

Ok. I ran build of nixos (unstable channel) image on aws arm64 machine and I just ended with:

error: builder for '/nix/store/2d9f8f3gl4hpacfvcr4zj28n0q1mj64b-linux-armv6l-unknown-linux-gnueabihf-6.1.63-stable_20231123.drv' failed with exit code 2;
       last 10 log lines:
       >   LD      vmlinux.o
       >   OBJCOPY modules.builtin.modinfo
       >   GEN     modules.builtin
       >   GEN     .vmlinux.objs
       >   MODPOST Module.symvers
       > ERROR: modpost: "__aeabi_uldivmod" [drivers/pwm/pwm-rp1.ko] undefined!
       > ERROR: modpost: "__aeabi_uldivmod" [drivers/media/platform/raspberrypi/rp1_cfe/rp1-cfe.ko] undefined!
       > ERROR: modpost: "__aeabi_ldivmod" [drivers/media/platform/raspberrypi/rp1_cfe/rp1-cfe.ko] undefined!
       > make[1]: *** [../scripts/Makefile.modpost:126: Module.symvers] Error 1
       > make: *** [../Makefile:1966: modpost] Error 2
       For full logs, run 'nix log /nix/store/2d9f8f3gl4hpacfvcr4zj28n0q1mj64b-linux-armv6l-unknown-linux-gnueabihf-6.1.63-stable_20231123.drv'.
error: 1 dependencies of derivation '/nix/store/314ixmfr3brnjkbxn0ka9lx8rcwy2sgl-nixos-system-handaki-24.05.20240229.1536926.drv' failed to build
error: 1 dependencies of derivation '/nix/store/4jylgypyvdgpjqsnqwq51jingmkalgmd-ext4-fs.img.zst-armv6l-unknown-linux-gnueabihf.drv' failed to build
error: 1 dependencies of derivation '/nix/store/k6jk2vz7zav6ga6bmb60jf87asyn68gc-nixos-sd-image-24.05.20240229.1536926-armv6l-linux.img-armv6l-unknown-linux-gnueabihf.drv' failed to build

I enabled:
boot.binfmt.emulatedSystems = [ "arm7l-linux" ];

However, I’m not sure how to solve missing symbols in kernel modules.

Have you encountered a similar problem?

Ok. Solved. Wrong kernel were on duty.

1 Like

Could you elaborate? I’m running into the same problem.

Hello. Not sure if bug or feature, however I switched to:

system.stateVersion = "nixos-unstable";
boot.kernelPackages = lib.mkForce pkgs.linuxPackages_latest;

And yes, upstream kernel will not have all drivers, but I just don’t need HATs supports etc…

It booted fine, but some time ago. I need to build and test new unstable image.

1 Like

hi together - has anyone experience with this built: GitHub - cyber-murmel/nixos-rpi-zero-w: NixOS on the Raspberry Pi Zero W

Hi @xiil, that build is for an old version of NixOS. There are multiple things in there which don’t apply to NixOS 25.05.

Relevant to this thread, it uses boot.loader.raspberryPi.enable, which has been removed. Nowadays, NixOS uses u-boot (boot.loader.generic-extlinux-compatible.enable). See sd-image-raspberry.pi.nix for how u-boot is installed on the SD card.

With the old raspberryPi boot loader, it was possible to enable i2c with:

# outdated - no longer works
{ boot.loader.raspberryPi.firmwareConfig = "dtparam=i2c=on"; }

But with u-boot, this should be done with a device tree overlay, as shown above by NixOS on raspberry pi zero w - #23 by wolflu.


If someone has a working configuration, I think it would make a really nice addition to nixos-hardware (please :smiley:).

@marmolak, @jue89: It’s possible to get the linux_rpi1 kernel to build by disabling the handful of drivers which fail to link.

{ lib, pkgs, ... }: {
  boot.kernelPackages = pkgs.linuxKernel.packages.linux_rpi1;  # already done by sd-image-raspberrypi.nix
  boot.kernelPatches = [ {
    name = "disable-broken-div64";
    patch = null;
    extraStructuredConfig = with lib.kernel; {
      # pwm-rp1
      PWM_RP1 = no;
      # i2c-designware-core (rpi zero w uses i2c-bcm2835, I think)
      I2C_DESIGNWARE_CORE = no;
      I2C_DESIGNWARE_SLAVE = no;
      I2C_DESIGNWARE_PLATFORM = no;
      I2C_DESIGNWARE_PCI = no;
      # rp1-cfe (Raspberry Pi PiSP Camera Front End)
      VIDEO_RP1_CFE = no;
    };
  } ];
}
1 Like

You can just use systemd-boot, uefi, u-boot, mainline. You don’t need a lot of these hacks. If you can read my nix code in GitHub - MatthewCroughan/raspberrypi-nixos-example: The simplest possible way to begin using and extending a NixOS Configuration with a Raspberry Pi, you can see how to do it.

2 Likes

That’s nice @matthewcroughan. It’s good to use mainline and systemd-boot.

Although, after reading your nix code, it’s not “just” a case of replacing the hacks with systemd-boot and mainline linux. There are still kernel config changes, a patch applied to systemd, and assembling the the repart image.

This is my current basic config for rpi1 (for rpi zero w it would need config for wireless networking and i2c):

{ lib, modulesPath, ... }: {
  nixpkgs.hostPlatform = "armv6l-linux";   # vintage pi
  nixpkgs.buildPlatform = "x86_64-linux";  # cross-compile

  imports = [ "${modulesPath}/installer/sd-card/sd-image-raspberrypi.nix" ];
  disabledModules = [
    "${modulesPath}/profiles/all-hardware.nix"
    "${modulesPath}/profiles/base.nix"
  ];

  system.stateVersion = "25.05";

  # trim down initrd modules
  boot.supportedFilesystems = lib.mkForce [ "vfat" "ext4" ];
  boot.initrd = {
    includeDefaultModules = false;
    kernelModules = [
      "ext4"
      "mmc_block"

      # https://www.raspberrypi.com/documentation/computers/processors.html#bcm2835
      "bcm2835_dma"
      "i2c_bcm2835"
      "vc4"  # Broadcom VideoCore 4 graphics driver
    ];
    availableKernelModules = lib.mkForce [
      "mmc_block"
      "usbhid"
      "hid_generic"
    ];
  };

  nixpkgs.overlays = [ (final: prev: let
    inherit (final.stdenv.hostPlatform) isAarch32;
    isCross = final.stdenv.buildPlatform != final.stdenv.hostPlatform;

    # Fix host arch for armv6 cross compiling
    # https://github.com/NixOS/nixpkgs/pull/402768
    patchUboot = drv: drv.override (originalArgs: {
      extraPatches = originalArgs.extraPatches or [] ++ lib.optional (isCross && isAarch32)
        (final.fetchpatch {
          url = "https://patchwork.ozlabs.org/series/454366/mbox/";
          hash = "sha256-n2TaQ/HOV588nAbd1ttJf3Knn2L5181VjEG5xDwjlT8=";
        });
    });
  in {
    ubootRaspberryPi = patchUboot prev.ubootRaspberryPi;
    ubootRaspberryPiZero = patchUboot prev.ubootRaspberryPiZero;

    linuxKernel = prev.linuxKernel // {
      packages = prev.linuxKernel.packages // {
        # Disable drivers which fail to build under nixpkgs
        linux_rpi1 = prev.linuxKernel.packages.linux_rpi1.extend
          (kself: ksuper: {
            kernel = (ksuper.kernel.override (originalArgs: {
              kernelPatches = (originalArgs.kernelPatches or [ ]) ++ lib.trace "using linux_rpi1 with config patch" [ {
                name = "disable-broken-div64";
                patch = null;
                extraStructuredConfig = with lib.kernel; {
                  # pwm-rp1
                  PWM_RP1 = no;
                  # i2c-designware-core
                  I2C_DESIGNWARE_CORE = no;
                  I2C_DESIGNWARE_SLAVE = no;
                  I2C_DESIGNWARE_PLATFORM = no;
                  I2C_DESIGNWARE_PCI = no;
                  # rp1-cfe  Raspberry Pi PiSP Camera Front End
                  VIDEO_RP1_CFE = no;
                };
              } ];
            }));
          });
      };
    };

    # https://github.com/NixOS/nixpkgs/issues/126755#issuecomment-869149243
    makeModulesClosure = args:
      prev.makeModulesClosure (args // lib.optionalAttrs isAarch32 {
        allowMissing = true;
      });
  }) ];
}

One definition of “simple” is less code on top of nixos. Using mainline kernel and system-boot is the future and it will be good. But for me, at the moment, using linux_rpi1 plus a few hacks seems easier.

2 Likes

Which channel/branch do you use to build this? I’ve tried building with unstable on my Mac and I get intermittent failures. The latest one I saw was something about libapparmor being unable to link to Python.

Update: I managed to build it properly on an x86_64-linux machine (like every example uses as the buildHost). So I guess somethings are a little broken building from aarch64-linux (the mac build was via the linux-builder).

(snippet of log output)
       > -lpython3.12 -ldl -L/nix/store/rzc5hin8k6ffk2058hmkspsn2p90rbr9-libxcrypt-4.4.38/lib -lm
       > checking python extra linking flags... /nix/store/gbml27jdc722w5srjw6mw28v08wi0xbf-python3-3.12.10/bin/python3-config is /nix/store/gbml27jdc722w5srjw6mw28v08wi0xbf-python3-3.12.10/bin/python3-config
       >  -L/nix/store/gbml27jdc722w5srjw6mw28v08wi0xbf-python3-3.12.10/lib -lpython3.12 -ldl -L/nix/store/rzc5hin8k6ffk2058hmkspsn2p90rbr9-libxcrypt-4.4.38/lib -lm
       > checking consistency of all components of python development environment... no
       > configure: error:
       >   Could not link test program to Python. Maybe the main Python library has been
       >   installed in some non-standard library path. If so, pass it to configure,
       >   via the LDFLAGS environment variable.
       >   Example: ./configure LDFLAGS="-L/usr/non-standard-path/python/lib"
       >   ============================================================================
       >    ERROR!
       >    You probably have to install the development version of the Python package
       >    for your distribution.  The exact name of this package varies among them.
       >   ============================================================================
       >
       For full logs, run 'nix log /nix/store/iimhan62asn3mpmg4385slwrjwkf1ya0-libapparmor-armv6l-unknown-linux-gnueabihf-4.1.0.drv'.
error: builder for '/nix/store/iimhan62asn3mpmg4385slwrjwkf1ya0-libapparmor-armv6l-unknown-linux-gnueabihf-4.1.0.drv' failed with exit code 1
error: 1 dependencies of derivation '/nix/store/q8f9ir8jr45nk42c8wgb4qsdklm44l8n-dbus-armv6l-unknown-linux-gnueabihf-1.14.10.drv' failed to build
error: 1 dependencies of derivation '/nix/store/fl951p16jpyfwlwn6gwcj70y1wf5faq8-systemd-armv6l-unknown-linux-gnueabihf-257.5.drv' failed to build
error: 1 dependencies of derivation '/nix/store/4jngd95qrnllhzyzcrsl1fqwlnvx1fy7-nixos-system-nixos-sd-card-25.05pre-git.drv' failed to build