NixOS on ARM: Difference between revisions

m Resources: Add additional links
Line 501: Line 501:


Some '''''users''''' have provided best effort caches for 32 bit ARM, but none are currently available.
Some '''''users''''' have provided best effort caches for 32 bit ARM, but none are currently available.
== Build your own image natively ==
You can customize image by using the following snippet.
<syntaxhighlight lang="nix">
# save as sd-image.nix somewhere
{ ... }: {
  imports = [
    <nixpkgs/nixos/modules/installer/sd-card/sd-image-aarch64.nix>
  ];
  # put your own configuration here, for example ssh keys:
  users.users.root.openssh.authorizedKeys.keys = [
    "ssh-ed25519 AAAAC3NzaC1lZDI1.... username@tld"
  ];
}
</syntaxhighlight>
Then build with:
<syntaxhighlight lang="nix">
$ nix-build '<nixpkgs/nixos>' -A config.system.build.sdImage -I nixos-config=./sd-image.nix
</syntaxhighlight>
Note that this requires a machine with aarch64. You can however also build it from your laptop using an aarch64 remote builder as described in [[Distributed build]] or ask for access on the [https://github.com/nix-community/aarch64-build-box community aarch64 builder].
if you use the experimental flake, instead of doing the above stuff, can put the following lines in <code>flake.nix</code>, <code>git add flake.nix</code> and build with <code>nix build .#images.rpi2</code>:
<syntaxhighlight lang="nix">
{
  description = "Build image";
  inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-22.11";
  outputs = { self, nixpkgs }: rec {
    nixosConfigurations.rpi2 = nixpkgs.lib.nixosSystem {
      modules = [
        "${nixpkgs}/nixos/modules/installer/sd-card/sd-image-raspberrypi.nix"
        {
          nixpkgs.config.allowUnsupportedSystem = true;
          nixpkgs.hostPlatform.system = "armv7l-linux";
          nixpkgs.buildPlatform.system = "x86_64-linux"; #If you build on x86 other wise changes this.
          # ... extra configs as above
        }
      ];
    };
    images.rpi2 = nixosConfigurations.rpi2.config.system.build.sdImage;
  };
}
</syntaxhighlight>
=== Cross-compiling ===
It is possible to cross-compile from a different architecture. To cross-compile to <code>armv7l</code>, on the same <code>sd-image.nix</code> add in <code>crossSystem</code>:
<syntaxhighlight lang="nix">
{ ... }: {
  nixpkgs.crossSystem.system = "armv7l-linux";
  imports = [
    <nixpkgs/nixos/modules/installer/sd-card/sd-image-aarch64.nix>
  ];
  # ...
}
</syntaxhighlight>
=== Compiling through binfmt QEMU ===
It is also possible to compile for aarch64 on your non-aarch64 local machine, or a remote builder, by registering QEMU as a binfmt wrapper for the aarch64 architecture. This <b>wrapper uses emulation</b> and will therefore be slower than comparable native machines or cross-compiling.
To enable the binfmt wrapper on NixOS, add the following to <code>configuration.nix</code>
<syntaxhighlight lang="nix">
{
  boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
}
</syntaxhighlight>
Then, add <code>--argstr system aarch64-linux</code> to the build command:
<syntaxhighlight lang="nix">
$ nix-build '<nixpkgs/nixos>' -A config.system.build.sdImage -I nixos-config=./sd-image.nix --argstr system aarch64-linux
</syntaxhighlight>
If you are building on non-NixOS machine with QEMU binfmt wrapper configured, you will want to configure nix daemon to let it know that it can build for aarch64. Add the following line to <code>/etc/nix/nix.conf</code>:
<code>extra-platforms = aarch64-linux arm-linux</code>
{{note| archlinux users can install <code>extra/qemu-system-aarch64</code>, <code>extra/qemu-user-static</code> and <code>extra/qemu-user-static-binfmt</code>
and restart <code>systemd-binfmt.service</code>. Check if binfmt is loaded by <code>ls  /proc/sys/fs/binfmt_misc/</code> (there must be  <code>qemu-aarch64</code> or needed architecture) and add line <code><nowiki>extra-sandbox-paths = /usr/bin/qemu-aarch64-static</nowiki></code> to <code>/etc/nix/nix.conf</code> and don't forget to restart the <code>nix-daemon.service</code> systemd unit afterwards.}}
If you want to build just one specific package, use this:
<syntaxhighlight lang="nix">
nix-build '<nixpkgs/nixos>' -A pkgs.theRequiredPackage --argstr system aarch64-linux -I nixos-config=/path/to/target/machine/nixos/config/copy
</syntaxhighlight>
(the last option should not be required on NixOS machines)
=== Compiling through QEMU/kvm ===
It is also possible to build nixos images through full emulation using QEMU/kvm but will be way slower than native and binfmt QEMU.


== Installer image with custom U-Boot ==
== Installer image with custom U-Boot ==