I saw this example of producing an armv7l SD Card image, but it assumes that the host you’re running nix-build on is an armv7l machine. In my case, I want to produce an SD Card image for an Orange Pi Zero with 256MB of RAM, which will never be able to run the Nix tooling natively.
So, how do I cross-compile an SD Card image for armv7l from an X86 host? I’ve read a bit about crossSystem and assume that this is how it’s supposed to be done, but get lost very quickly. Is it possible someone could give me a minimal example for this?
a specific pinned nixpkgs. for me, whatever crosspkgs is in my flake inputs was a known good revision for (x86_64->aarch64 crossing). Your luck will vary with your cross, whatever rev you’re on, what exact packages you need, what the caches have, etc.
I haven’t personally tried it but the wiki mentions an interesting alternative to cross-compiling namely “native”-compilation using QEMU, which could remove some of the problems that cross-compilation comes with. https://nixos.wiki/wiki/NixOS_on_ARM
Have you already seen or tried that?
I’ve tried that, at least for armv7l it is unbearably slow. It was taking many many minutes to compile the hello derivation on a Ryzen 3900X, I cancelled after 20 minutes.
So how would I build this? rpizero1 is not a derivation, so nix build .#nixosConfigurations.rpizero1 would fail with error: flake output attribute 'nixosConfigurations.rpizero1' is not a derivation.
which can be read as “generate an attribute set, use the attribute names from nixosConfiguration as keys, and use the nixosConfigurations.<x>.config.system.build.toplevel as the value”.
Thus, nix build .#nixosConfigurations.rpizero1.config.system.build.toplevel evaluates to the same thing as nix build .#toplevels.rpizero1.
I have managed to do that with armv7l in place of your rpizero1 config, but what do I do with the result? How am I intended to flash this to an SD card and boot it? I was expecting an ISO, not an activation script. What is your process?
[matthew@swordfish:~/tmp/armv7l/nixcfg]$ ls result
activate dtbs init kernel-modules sw
append-initrd-secrets etc init-interface-version kernel-params system
bin extra-dependencies initrd nixos-version systemd
configuration-name firmware kernel specialisation
Same as usual with these sorts of NixOS-level build artifacts – somewhere in my config I added an import. That import added stuff into the nixos build that resulted in an extra output attribute. So, in addition to the config.system.build.toplevel, the rpizero1 build also now has config.system.build.sdImage.
While I’m sure it’s far from idiomatic, searchers may be interested in my example below:
Points of interest include:
cross compiles an SD image that is bootable on an RPi3 with nix build
uses pkgs.vmTools.runInLinuxVM to create a subvolumed, compressed, BTRFS-root partition layout for the image
adds some customizations to uboot to support BTRFS and ZSTD compression
provides a booting VM target for local testing (though doesn’t do much other than boot – thread)
uses GitHub Actions to automatically build the image in CI (on tagged releases), and uploads the image to Releases · n8henrie/nixos-btrfs-pi · GitHub where then can be directly downloaded and burned to an SD card
I’m sure others will want to customize and probably take out a lot of cruft, but I’m blown away that this can all be done with nix + GitHub Actions, newbies (like myself) might find the example interesting.