Difference between revisions of "NixOS on ARM"

From NixOS Wiki
Jump to: navigation, search
(added resource regarding sd images)
 
(140 intermediate revisions by 58 users not shown)
Line 1: Line 1:
 
ARM support for NixOS is a work-in-progress, but is progressing quickly.
 
ARM support for NixOS is a work-in-progress, but is progressing quickly.
  
The support varies depending on the architecture and the specific boards. The way the ARM integration is built into NixOS is by making generic builds the first-class citizens; as soon as there is upstream support for the board in the kernel and the bootloader, NixOS should work once updated to these versions. It is still possible, when needed, to build and use a customised bootloader and kernel for specific boards<sup>[[Talk:NixOS_on_ARM#NixOS_.22support.22_for_board-specific_kernels_or_bootloaders|[reference needed]]]</sup>. At this moment in time (early 2018) only AArch64 is planned for full support upstream. Though, neither armv6l or armv7l are being ignored, fixes are worked on and approved as needed; what's missing is support and upstream builds being maintained in binary form. Additional resources (and some sd card images) can be found courtesy of [https://github.com/illegalprime/nixos-on-arm illegalprime].
+
The support varies depending on the architecture and the specific boards. The way the ARM integration is built into NixOS is by making generic builds the first-class citizens; as soon as there is upstream support for the board in the kernel and the bootloader, NixOS should work once updated to these versions. It is still possible, when needed, to build and use a customised bootloader and kernel for specific boards<sup>[[Talk:NixOS_on_ARM#NixOS_.22support.22_for_board-specific_kernels_or_bootloaders|[reference needed]]]</sup>. At this moment in time (late 2021) only AArch64 has full support upstream.
 +
 
 +
Though, neither armv6l or armv7l are being ignored, fixes are worked on and approved as needed; what's missing is support and upstream builds being maintained in binary form. At the time of writing, no publicly available caches for armv6l or armv7l are available.<!-- please get in touch with samueldr on the NixOS on ARM channel if you want to share your own cache, before editing. We need to review the wording to make it crystal clear it's a user-provided cache. -->
 +
 
 +
'''For images links, including UEFI install''', skip to the [[NixOS on ARM#Installation|Installation]] section.
  
 
== Supported devices ==
 
== Supported devices ==
 +
 +
Table legend:
 +
* SoC - https://en.wikipedia.org/wiki/System_on_a_chip
 +
* ISA - https://en.wikipedia.org/wiki/Instruction_set_architecture
  
 
=== Upstream (NixOS) supported devices ===
 
=== Upstream (NixOS) supported devices ===
  
NixOS has support for these boards using AArch64 architecture on the nixpkgs-unstable and nixpkgs-18.03 channel.  
+
NixOS has support for these boards using AArch64 architecture on the nixpkgs-unstable and stable channel.
 +
 
 +
Support for those board assumes as much is supported as Mainline Linux supports.
 
<!--
 
<!--
 
Order for the device table is:
 
Order for the device table is:
Line 17: Line 27:
 
!width="2%"| Board
 
!width="2%"| Board
 
!width="2%"| SoC
 
!width="2%"| SoC
!width="2%"| ISA
+
!width="1%"| ISA
 
!width="2%"| CPU
 
!width="2%"| CPU
!width="2%"| RAM
+
!width="1%"| RAM
 
!width="2%"| Storage
 
!width="2%"| Storage
 
|-
 
|-
 
| Raspberry Pi Foundation
 
| Raspberry Pi Foundation
| [[NixOS_on_ARM/Raspberry_Pi|Raspberry Pi 3]]
+
| [[NixOS_on_ARM/Raspberry_Pi_3|Raspberry Pi 3]]
 
| Broadcom BCM2837
 
| Broadcom BCM2837
 
| AArch64 / ARMv7
 
| AArch64 / ARMv7
| 4× Cortex-A53 @ 1.2 GHz
+
| 4× Cortex-A53 @ 1.2 - 1.4 GHz
 
| 1 GB
 
| 1 GB
 
| SD/microSD
 
| SD/microSD
 +
|-
 +
| Raspberry Pi Foundation
 +
| [[NixOS_on_ARM/Raspberry_Pi 4|Raspberry Pi 4]]
 +
| Broadcom BCM2711
 +
| AArch64 / ARMv7
 +
| 4× Cortex-A72 @ 1.5 - 1.8 GHz
 +
| 1-8 GB
 +
| microSD, eMMC
 
|}
 
|}
 
=== Community supported devices ===
 
=== Community supported devices ===
 
The installation images by '''@dezgeg''' should work on the following devices; follow the links for more details, like installation instructions and device-specific notes.
 
  
 
<!--
 
<!--
Line 39: Line 55:
 
  * By release date, chronological (older first).
 
  * By release date, chronological (older first).
 
-->
 
-->
<div class="table-responsive">
+
<div class="table">
 
{|class="table"
 
{|class="table"
 
!width="2%"| Manufacturer
 
!width="2%"| Manufacturer
 
!width="2%"| Board
 
!width="2%"| Board
 
!width="2%"| SoC
 
!width="2%"| SoC
!width="2%"| ISA
+
!width="1%"| ISA
 
!width="2%"| CPU
 
!width="2%"| CPU
 
!width="2%"| RAM
 
!width="2%"| RAM
 
!width="2%"| Storage
 
!width="2%"| Storage
 +
|-
 +
| Apple
 +
| [[NixOS_on_ARM/Apple Silicon Macs|Apple Silicon Macs]]
 +
| M1/M1 Pro/M1 Max
 +
| AArch64
 +
| —
 +
| —
 +
| NVMe
 
|-
 
|-
 
| ASUS
 
| ASUS
Line 72: Line 96:
 
| 2 GB
 
| 2 GB
 
| microSD, 8GB eMMc
 
| microSD, 8GB eMMc
 +
|-
 +
| Banana Pi BPI-M5
 +
| [[NixOS_on_ARM/Banana Pi BPI-M5|Banana Pi BPI-M5]]
 +
| Amlogic S905X3
 +
| ARMv8.2
 +
| 4× Cortex-A55
 +
| 4 GB LPDDR4
 +
| microSD, 16G eMMC
 
|-
 
|-
 
| BeagleBoard.org
 
| BeagleBoard.org
 
| [[NixOS_on_ARM/BeagleBone_Black|BeagleBone Black]]
 
| [[NixOS_on_ARM/BeagleBone_Black|BeagleBone Black]]
| TI AM335x
+
| TI AM335x [https://git.beagleboard.org/beagleboard/beaglebone-black (src)]
 
| ARMv7
 
| ARMv7
 
| 1× Cortex-A8 @ 1 GHz
 
| 1× Cortex-A8 @ 1 GHz
Line 84: Line 116:
 
| [[NixOS_on_ARM/Firefly_AIO-3399C|AIO-3399C]]
 
| [[NixOS_on_ARM/Firefly_AIO-3399C|AIO-3399C]]
 
| Rockchip RK3399
 
| Rockchip RK3399
| AARCH64
+
| AArch64
| 2× Cortex-A72 @ 2.0 GHz, 4x Cortex-A53 @ 1.5 Ghz
+
| 2× Cortex-A72 @ 2.0 GHz, Cortex-A53 @ 1.5 Ghz
 
| 2/4 GB
 
| 2/4 GB
 
| 8/16 GB eMMC, microSD
 
| 8/16 GB eMMC, microSD
 +
|-
 +
| FriendlyElec
 +
| [[NixOS_on_ARM/NanoPC-T4|NanoPC-T4]]
 +
| Rockchip RK3399
 +
| AArch64
 +
| 2× Cortex-A72 @ 2.0 GHz, 4× Cortex-A53 @ 1.5 Ghz
 +
| 4 GB
 +
| 16 GB eMMC, microSD, NVMe
 +
|-
 +
| FriendlyElec
 +
| [[NixOS_on_ARM/NanoPi-M4|NanoPi-M4]]
 +
| Rockchip RK3399
 +
| AArch64
 +
| 2× Cortex-A72 @ 2.0 GHz, 4× Cortex-A53 @ 1.5 Ghz
 +
| 4 GB
 +
| optional eMMC, microSD
 +
|-
 +
| FriendlyElec
 +
| [[NixOS_on_ARM/NanoPi-R6C|NanoPi-R6C]]
 +
| Rockchip RK3588S
 +
| AArch64
 +
| 4× ARM Cortex-A76 @ 2.4 GHz, 4× Cortex-A55 @ 1.8 Ghz
 +
| 4 GB / 8 GB
 +
| optional eMMC, microSD, NVMe
 +
|-
 +
| Hardkernel
 +
| [[NixOS_on_ARM/ODROID-HC1|ODROID-HC1 & ODROID-HC2]]
 +
| Samsung Exynos 5422
 +
| ARMv7
 +
| 4× Cortex-A15 @ 2GHz, 4× Cortex-A7 @ 1.4GHz
 +
| 2 GB
 +
| microSD
 
|-
 
|-
 
| Hardkernel
 
| Hardkernel
Line 93: Line 157:
 
| Amlogic S905
 
| Amlogic S905
 
| AArch64
 
| AArch64
| 4 × Cortex-A53 @ 1.5GHz
+
| Cortex-A53 @ 1.5GHz
 
| 2 GB
 
| 2 GB
 +
| eMMC, microSD
 +
|-
 +
| Hardkernel
 +
| [[NixOS_on_ARM/ODROID-HC4|ODROID-HC4]]
 +
| Amlogic S905X3
 +
| AArch64
 +
| 4× Cortex-A55 @ 1.8GHz
 +
| 4 GB
 +
| microSD, SATA
 +
|-
 +
| Libre Computer
 +
| [[NixOS_on_ARM/Libre_Computer_ROC-RK3399-PC|ROC-RK3399-PC]]
 +
| Rockchip RK3399
 +
| AArch64
 +
| 2× Cortex-A72 @ 2.0 GHz, 4× Cortex-A53 @ 1.5 Ghz
 +
| 4 GB
 +
| eMMC, microSD, NVMe
 +
|-
 +
| Libre Computer
 +
| [[NixOS_on_ARM/Libre_Computer_ROC-RK3328-CC|ROC-RK3328-CC]]
 +
| Rockchip RK3328
 +
| AArch64
 +
| 4× ARM Cortex-A53 @ 1.4GHz
 +
| 4 GB
 +
| eMMC, microSD
 +
|-
 +
| Libre Computer
 +
| [[NixOS_on_ARM/Libre_Computer_AML-S905X-CC-V2|AML-S905X-CC-V2]]
 +
| Amlogic S905X
 +
| AArch64
 +
| 4× Cortex-A53 @ 1.512 GHz
 +
| 1/2GB
 
| eMMC, microSD
 
| eMMC, microSD
 
|-
 
|-
Line 112: Line 208:
 
| 2 GB
 
| 2 GB
 
| 16 GB eMMC, SD, SATA
 
| 16 GB eMMC, SD, SATA
 +
|-
 +
| NXP
 +
| [https://github.com/NiklasGollenstede/nixos-imx/ i.MX 8M Plus EVK]
 +
| i.MX 8M Plus
 +
| AArch64
 +
| 4× Cortex-A53 @ 1.8 Ghz
 +
| 6 GB
 +
| 32 GB eMMC, microSD
 +
|-
 +
| NXP
 +
| [https://github.com/gangaram-tii/nixos-imx8mq/ i.MX 8M Quad EVK]
 +
| i.MX 8M Quad
 +
| AArch64
 +
| 4× Cortex-A53 @ 1.5 Ghz + 1x Cortex-M4
 +
| 3 GB
 +
| 16 GB eMMC, microSD
 +
|-
 +
| OLIMEX
 +
| [[NixOS_on_ARM/OLIMEX_Teres-A64|Teres-A64]]
 +
| AllWinner A64
 +
| AArch64
 +
| 4x Cortex-A53 @ 1152MHz
 +
| 2GB
 +
| 16 GB eMMC, microSD
 
|-
 
|-
 
| Orange Pi
 
| Orange Pi
Line 136: Line 256:
 
| 1 GB
 
| 1 GB
 
| SD/microSD + 8GB eMMC
 
| SD/microSD + 8GB eMMC
 +
|-
 +
| Orange Pi
 +
| [[NixOS_on_ARM/Orange_Pi_Zero2_H626|Orange Pi Zero2 (H616)]]
 +
| Allwinner H616
 +
| AArch64
 +
| 4× Cortex-A53 @ 1.2 GHz
 +
| 1 GB
 +
| SD/microSD + 2MB SPI Flash
 +
|-
 +
| Orange Pi
 +
| [[NixOS_on_ARM/Orange_Pi_R1_Plus_LTS|Orange Pi R1 Plus LTS]]
 +
| Rockchip RK3328
 +
| AArch64
 +
| 4x Cortex-A53 @ -1.5 GHz
 +
| 1 GB
 +
| microSD
 +
|-
 +
| Orange Pi
 +
| [[NixOS_on_ARM/Orange_Pi_5|Orange Pi 5]]
 +
| Rockchip RK3588s
 +
| AArch64
 +
| 4× Cortex-A76 @ 2.4GHz, 4×Cortex-A55 @ 1.8 GHz
 +
| 4/8/16 GB
 +
| microSD, NVMe
 +
|-
 +
| Orange Pi
 +
| [[NixOS_on_ARM/Orange_Pi_5_Plus|Orange Pi 5 Plus]]
 +
| Rockchip RK3588
 +
| AArch64
 +
| 4× Cortex-A76 @ 2.4GHz, 4×Cortex-A55 @ 1.8 GHz
 +
| 4/8/16 GB
 +
| eMMC, microSD, NVMe
 
|-
 
|-
 
| PINE64
 
| PINE64
Line 149: Line 301:
 
| Allwinner A64
 
| Allwinner A64
 
| AArch64
 
| AArch64
| 4× Cortex-A53 @ ? GHz
+
| 4× Cortex-A53 @ ? Ghz
 
| 2 GB
 
| 2 GB
 +
| microSD & eMMC
 +
|-
 +
| PINE64
 +
| [[NixOS_on_ARM/PINE64_Pinebook_Pro|Pinebook Pro]]
 +
| Rockchip RK3399
 +
| AArch64
 +
| 2× Cortex-A72 @ 2.0 GHz, 4× Cortex-A53 @ 1.5 Ghz
 +
| 4 GB
 
| microSD & eMMC
 
| microSD & eMMC
 
|-
 
|-
Line 157: Line 317:
 
| Rockchip RK3328
 
| Rockchip RK3328
 
| AArch64
 
| AArch64
| 4x Cortex-A53 @ 1.5 GHz
+
| Cortex-A53 @ 1.5 GHz
 
| 1/2/4 GB
 
| 1/2/4 GB
 
| microSD/eMMC
 
| microSD/eMMC
Line 165: Line 325:
 
| Rockchip RK3399
 
| Rockchip RK3399
 
| AArch64
 
| AArch64
| 2× Cortex-A72 @ 2.0 GHz, 4x Cortex-A53 @ 1.5 Ghz
+
| 2× Cortex-A72 @ 2.0 GHz, Cortex-A53 @ 1.5 Ghz
 
| 2/4 GB
 
| 2/4 GB
 
| microSD/eMMC
 
| microSD/eMMC
 +
|-
 +
| Clockworkpi
 +
| [[NixOS_on_ARM/Clockworkpi_A06_uConsole|uConsole A06]]
 +
| Rockchip RK3399
 +
| AArch64
 +
| 2× Cortex-A72 @ 2.0 GHz, 4× Cortex-A53 @ 1.5 Ghz
 +
| 4 GB
 +
| microSD
 +
|-
 +
| Radxa
 +
| [[NixOS on ARM/Radxa ROCK5 Model B|ROCK5 Model B]]
 +
| Rockchip RK3588
 +
| AArch64
 +
| 4× Cortex-A76 @ 2.4GHz, 4×Cortex-A55 @ 1.8 GHz
 +
| 4/8/16 GB
 +
| eMMC, microSD, NVMe
 +
|-
 +
| Radxa
 +
| [[NixOS on ARM/Radxa ROCK5 Model A|ROCK5 Model A]]
 +
| Rockchip RK3588s
 +
| AArch64
 +
| 4× Cortex-A76 @ 2.4GHz, 4×Cortex-A55 @ 1.8 GHz
 +
| 4/8/16 GB
 +
| eMMC, microSD, NVMe
 
|-
 
|-
 
| Raspberry Pi Foundation
 
| Raspberry Pi Foundation
Line 173: Line 357:
 
| Broadcom BCM2835
 
| Broadcom BCM2835
 
| ARMv6
 
| ARMv6
| ARM1176 @ 700 MHz
+
| 1 × ARM1176 @ 700 MHz
 
| 256 MB / 512 MB
 
| 256 MB / 512 MB
 
| SD/microSD
 
| SD/microSD
Line 186: Line 370:
 
|-
 
|-
 
| Raspberry Pi Foundation
 
| Raspberry Pi Foundation
| [[NixOS_on_ARM/Raspberry_Pi|Raspberry Pi 3]]
+
| [[NixOS_on_ARM/Raspberry_Pi 3|Raspberry Pi 3]]
 
| Broadcom BCM2837
 
| Broadcom BCM2837
 
| AArch64 / ARMv7
 
| AArch64 / ARMv7
 
| 4× Cortex-A53 @ 1.2 GHz
 
| 4× Cortex-A53 @ 1.2 GHz
| 1 GB
+
| 1 GB
 
| SD/microSD
 
| SD/microSD
 +
|-
 +
| Raspberry Pi Foundation
 +
| [[NixOS_on_ARM/Raspberry_Pi 4|Raspberry Pi 4]]
 +
| Broadcom BCM2711
 +
| AArch64 / ARMv7
 +
| 4× Cortex-A53 @ 1.5 GHz
 +
| 1-8 GB
 +
| microSD
 +
|-
 +
| Raspberry Pi Foundation
 +
| [[NixOS_on_ARM/Raspberry_Pi 5|Raspberry Pi 5]]
 +
| Broadcom BCM2712
 +
| AArch64
 +
| 4× Cortex-A76 @ 2.4 GHz
 +
| 4-8 GB
 +
| microSD
 
|-
 
|-
 
| Toshiba
 
| Toshiba
Line 239: Line 439:
 
=== Getting the installer ===
 
=== Getting the installer ===
  
For aarch64 it is possible to download images from Hydra ([https://hydra.nixos.org/job/nixos/release-19.03/nixos.sd_image.aarch64-linux 19.03]) and ([https://hydra.nixos.org/job/nixos/trunk-combined/nixos.sd_image.aarch64-linux unstable]). On the page click on the latest successful built to get a download link under build products.
+
==== UEFI iso ====
  
The most current installation images and miscellaneous boot files for ARMv6 and ARMv7 devices are currently built maintained and hosted by '''@dezgeg''' at http://nixos-arm.dezgeg.me/installer. '''Warning: Due to a [https://github.com/NixOS/nix/issues/2393 bug] in the version of nix supplied with these images, upgrading (e.g. via <code>nixos-rebuild switch --upgrade</code> will not work. See [https://github.com/NixOS/nixpkgs/issues/51798 here] for details, and a workaround [https://github.com/qolii/nixpkgs/releases/tag/sd-image-ARMv7-68aad73 replacement image] for armv7l'''. Generic usage is described in this page, and board-specific instructions when needed are described on their page.
+
{{note| On Raspberry Pi devices, the NixOS ISO are not compatible due to hardware limitations rather than issues with the NixOS installer itself. As a result, it is recommended to use the SD card images files (.img) instead for a successful installation experience.}}
 +
 
 +
Continue to the [[NixOS on ARM/UEFI|UEFI]] page.
 +
 
 +
==== SD card images (SBCs and similar platforms) ====
 +
 
 +
For <code>AArch64</code> it is possible to download images from Hydra.
 +
 
 +
* [https://hydra.nixos.org/job/nixos/release-23.11/nixos.sd_image.aarch64-linux 23.11]
 +
* [https://hydra.nixos.org/job/nixos/release-23.05/nixos.sd_image.aarch64-linux 23.05]
 +
* [https://hydra.nixos.org/job/nixos/trunk-combined/nixos.sd_image.aarch64-linux unstable (LTS kernel)]
 +
* [https://hydra.nixos.org/job/nixos/trunk-combined/nixos.sd_image_new_kernel_no_zfs.aarch64-linux unstable (Latest kernel)]
 +
 
 +
On the page click on the latest successful build to get a download link under build products.
 +
 
 +
If the image has the extension <code>.zst</code>, it will need to be decompressed before writing to installation device. Use <code>nix-shell -p zstd --run "unzstd <img-name>.img.zst"</code> to decompress the image.
  
 
=== Installation steps ===
 
=== Installation steps ===
  
The installation images come in two flavors: <code>sd-image-armv6l-linux.img</code> is built for the ARMv6 architecture and it comes with the Raspberry Pi kernel. sd-image-armv7l-linux.img is built for the ARMv7 architecture and comes with the mainline multiplatform ARMv7 kernel (multi_v7_defconfig). Make sure you download the correct image for your board!
+
The .img files can be directly written to a microSD/SD card (minimal recommended size: 4 GB) using dd, once uncompressed from the ZSTD container. The SD card needs to be unmounted first.
  
The .img files can be directly written to a microSD/SD card (minimal recommended size: 4 GB) using dd.
+
Once the NixOS image file is downloaded, run the following command to install the image onto the SD Card, replace <code>/dev/mmcblk0</code> with the path to the SD card (use <code>dmesg</code> to find it out).  
  
<syntaxhighlight lang="bash">sudo dd if=sd-image-armv7l-linux.img of=/dev/sdX</syntaxhighlight>
+
<code>
Replace <code>/dev/sdX</code> with the path to your SD card device.
+
sudo dd if=nixos-sd-image-23.05pre482417.9c7cc804254-aarch64-linux.img of=/dev/mmcblk0
 +
</code>
 +
 
 +
This should be enough to get you started, you may now boot your device for the first time.
  
 
The base images are configured to boot up with a serial TTY ( RX/TX UART ) @ 115200 Baud. That way you not necessarily have to have a HDMI Display and keyboard.
 
The base images are configured to boot up with a serial TTY ( RX/TX UART ) @ 115200 Baud. That way you not necessarily have to have a HDMI Display and keyboard.
  
Note: I (kalbasit) had to replace <code>console=ttyS0,115200n8 console=ttyAMA0,115200n8 console=tty0</code> with <code>console=ttyS1,115200n8</code> in <code>/boot/extlinux/extlinux.conf</code> to make the serial console work on my Rasberry-Pi 3.
+
{{note| For some platforms, manually editing and adding kernel command-line arguments to <code>/boot/extlinux/extlinux.conf</code> may be needed for serial to work, and is "as" supported as would be editing the command-line manually during boot.}}
  
 
Continue with [[#NixOS installation & configuration]].
 
Continue with [[#NixOS installation & configuration]].
Line 262: Line 480:
 
=== AArch64 ===
 
=== AArch64 ===
  
Thanks to [https://github.com/grahamc @grahamc] and [https://www.packet.com/ Packet] the [https://hydra.nixos.org/ official NixOS Hydra] builds a full set of binaries (available on https://cache.nixos.org) for the AArch64 architecture on the nixpkgs-unstable channel. Starting with the 18.03 release  [https://hydra.nixos.org/jobset/nixos/release-19.03 the official Hydra instance will also build the stable channel] .
+
The [https://hydra.nixos.org/ official NixOS Hydra] instance builds a full set of binaries (available on https://cache.nixos.org) for the AArch64 architecture on the nixpkgs-unstable and stable channels.
 
 
  
 
=== armv6l and armv7l ===
 
=== armv6l and armv7l ===
  
A binary cache, containing a [https://github.com/dezgeg/nixconfs/blob/master/packages.txt subset] of the [https://github.com/NixOS/nixpkgs-channels/tree/nixos-unstable nixos-unstable] channel, is hosted at http://nixos-arm.dezgeg.me/channel (signed with '''key''' <code>nixos-arm.dezgeg.me-1:xBaUKS3n17BZPKeyxL4JfbTqECsT+ysbDJz29kLFRW0=%</code>).
+
Some '''''users''''' have provided best effort caches for 32 bit ARM, but none are currently available.
 
 
=== Additional caches ===
 
  
* An armv7l cache by '''@clever'''
+
== Build your own image natively ==
** http://hydra.earthtools.ca/jobset/arm/nixpkgs-arm-unstable/channel/latest
 
* [https://cachix.org cachix] provides an arm binary cache ([https://discourse.nixos.org/t/armv7l-builds-on-cachix/788 Discourse post]:
 
** https://arm.cachix.org/ - <code>arm.cachix.org-1:fGqEJIhp5zM7hxe/Dzt9l9Ene9SY27PUyx3hT9Vvei0=</code>
 
 
 
== Build your own image ==
 
  
 
You can customize image by using the following snippet.
 
You can customize image by using the following snippet.
Line 284: Line 494:
 
{ ... }: {
 
{ ... }: {
 
   imports = [
 
   imports = [
     <nixpkgs/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix>
+
     <nixpkgs/nixos/modules/installer/sd-card/sd-image-aarch64.nix>
 
   ];
 
   ];
 
   # put your own configuration here, for example ssh keys:
 
   # put your own configuration here, for example ssh keys:
   users.extraUsers.root.openssh.authorizedKeys.keys = [
+
   users.users.root.openssh.authorizedKeys.keys = [
 
     "ssh-ed25519 AAAAC3NzaC1lZDI1.... username@tld"
 
     "ssh-ed25519 AAAAC3NzaC1lZDI1.... username@tld"
 
   ];
 
   ];
Line 301: Line 511:
 
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].
 
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].
  
=== Crosscompiling ===
+
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:
  
It is also possible to crosscompile aarch64 on your local machine or a remote builder by registering  QEMU as a binfmt wrapper for the aarch64 architecture. This wrapper uses emulation and will therefore be slower than comparable native machines. A [https://github.com/cleverca22/nixos-configs/blob/master/qemu.nix module] and and [https://github.com/cleverca22/nixos-configs/tree/master/overlays/qemu overlay] are provided by user '''@clever'''.
+
<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>:
 
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>
 
<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:
 
If you want to build just one specific package, use this:
Line 313: Line 576:
 
</syntaxHighlight>
 
</syntaxHighlight>
 
(the last option should not be required on NixOS machines)
 
(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 ==
 +
 +
The [https://github.com/Mic92/nixos-aarch64-images Mic92/nixos-aarch64-images] repository provides a mechanism to modify the official NixOS installer to embed the board-specific U-Boot firmware required for different boards. This method does not require QEMU or native ARM builds since the existing Hydra-built U-Boot binaries are used.
  
 
== Board-specific installation notes ==
 
== Board-specific installation notes ==
Line 331: Line 602:
 
== NixOS installation & configuration ==
 
== NixOS installation & configuration ==
  
The installation image is actually a MBR partition table plus two partitions; a FAT32 /boot and a ext4 root filesystem. The image is designed such that it's possible to directly reuse the SD image's partition layout and "install" NixOS on the very same SD card by simply replacing the default configuration.nix and running nixos-rebuild. Using this installation method is strongly recommended, though if you know exactly what you're doing and how U-Boot on your board works, you can use nixos-install as usual. To help with the SD card installation method, the boot scripts on the image automatically resize the rootfs partition to fit the SD card on the first boot.
+
{{outdated|The kernel version recommendations of this section are severely outdated. This section should be rewritten to be generic and refer people to the board-specific page. Only the board specific page should make recommendations about the kernel.}}
  
Use this as a template:
+
The installation image is actually a MBR partition table plus two partitions; a FAT16 /boot and a ext4 root filesystem. The image is designed such that it's possible to directly reuse the SD image's partition layout and "install" NixOS on the very same SD card by simply replacing the default configuration.nix and running nixos-rebuild. Using this installation method is strongly recommended, though if you know exactly what you're doing and how U-Boot on your board works, you can use nixos-install as usual. To help with the SD card installation method, the boot scripts on the image automatically resize the rootfs partition to fit the SD card on the first boot.
 +
 
 +
* To generate a default <code>/etc/nixos/configuration.nix</code> file, run <code>sudo nixos-generate-config</code>.
 +
 
 +
* You can also use an existing template:
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 
{ config, pkgs, lib, ... }:
 
{ config, pkgs, lib, ... }:
Line 344: Line 619:
 
   # !!! If your board is a Raspberry Pi 1, select this:
 
   # !!! If your board is a Raspberry Pi 1, select this:
 
   boot.kernelPackages = pkgs.linuxPackages_rpi;
 
   boot.kernelPackages = pkgs.linuxPackages_rpi;
   # !!! Otherwise (even if you have a Raspberry Pi 2 or 3), pick this:
+
   # On other boards, pick a different kernel, note that on most boards with good mainline support, default, latest and hardened should all work
   boot.kernelPackages = pkgs.linuxPackages_latest;
+
   # Others might need a BSP kernel, which should be noted in their respective wiki entries
 
    
 
    
 
   # !!! This is only for ARMv6 / ARMv7. Don't enable this on AArch64, cache.nixos.org works there.
 
   # !!! This is only for ARMv6 / ARMv7. Don't enable this on AArch64, cache.nixos.org works there.
   nix.binaryCaches = lib.mkForce [ "http://nixos-arm.dezgeg.me/channel" ];
+
   nix.binaryCaches = lib.mkForce [ "https://cache.armv7l.xyz" ];
   nix.binaryCachePublicKeys = [ "nixos-arm.dezgeg.me-1:xBaUKS3n17BZPKeyxL4JfbTqECsT+ysbDJz29kLFRW0=%" ];
+
   nix.binaryCachePublicKeys = [ "cache.armv7l.xyz-1:kBY/eGnBAYiqYfg0fy0inWhshUo+pGFM3Pj7kIkmlBk=" ];
 
 
  # !!! Needed for the virtual console to work on the RPi 3, as the default of 16M doesn't seem to be enough.
 
  # If X.org behaves weirdly (I only saw the cursor) then try increasing this to 256M.
 
  # On a Raspberry Pi 4 with 4 GB, you should either disable this parameter or increase to at least 64M if you want the USB ports to work.
 
  boot.kernelParams = ["cma=32M"];
 
 
      
 
      
   # File systems configuration for using the installer's partition layout
+
   # nixos-generate-config should normally set up file systems correctly
 +
  imports = [ ./hardware-configuration.nix ];
 +
  # If not, you can set them up manually as shown below
 +
  /*
 
   fileSystems = {
 
   fileSystems = {
 +
    # Prior to 19.09, the boot partition was hosted on the smaller first partition
 +
    # Starting with 19.09, the /boot folder is on the main bigger partition.
 +
    # The following is to be used only with older images. Note such old images should not be considered supported anymore whatsoever, but if you installed back then, this might be needed
 +
    /*
 
     "/boot" = {
 
     "/boot" = {
 
       device = "/dev/disk/by-label/NIXOS_BOOT";
 
       device = "/dev/disk/by-label/NIXOS_BOOT";
 
       fsType = "vfat";
 
       fsType = "vfat";
 
     };
 
     };
 +
    */
 
     "/" = {
 
     "/" = {
 
       device = "/dev/disk/by-label/NIXOS_SD";
 
       device = "/dev/disk/by-label/NIXOS_SD";
Line 367: Line 645:
 
     };
 
     };
 
   };
 
   };
 +
  */
 
      
 
      
   # !!! Adding a swap file is optional, but strongly recommended!
+
   # !!! Adding a swap file is optional, but recommended if you use RAM-intensive applications that might OOM otherwise.
 +
  # Size is in MiB, set to whatever you want (though note a larger value will use more disk space).
 
   # swapDevices = [ { device = "/swapfile"; size = 1024; } ];
 
   # swapDevices = [ { device = "/swapfile"; size = 1024; } ];
 
}</nowiki>}}
 
}</nowiki>}}
Note: the default configuration.nix will contain something like <code>imports = [ <nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix> ];</code> do not include that in your final installation or you will experience interesting problems. It is only for building the installation image!
+
Note: the default configuration.nix will contain something like <code>imports = [ <nixos/modules/installer/sd-card/sd-image-armv7l-multiplatform.nix> ];</code> do not include that in your final installation or you will experience interesting problems. It is only for building the installation image!
  
 
==== First rebuild on ARMv6 and ARMv7 ====
 
==== First rebuild on ARMv6 and ARMv7 ====
  
To make the unsupported ARM experience slightly less painful, the config template adds <code>nixos-arm.dezgeg.me</code> as a binary cache, which contains a small subset of packages on the unstable channel (though a caution for US users: the server hosting them is physically located in Finland). Note that the binary cache isn't enabled on the prebuilt images, so enable it via the command line when building for the first time:
+
To rebuild your system, run: <code>sudo nixos-rebuild switch</code>
  
<syntaxhighlight lang="bash">nixos-rebuild switch --fast --option binary-caches http://nixos-arm.dezgeg.me/channel --option binary-cache-public-keys nixos-arm.dezgeg.me-1:xBaUKS3n17BZPKeyxL4JfbTqECsT+ysbDJz29kLFRW0=%</syntaxhighlight>
+
{{note|Instructions removed since they referred to a long abandoned user-provided cache...}}
 +
<!--
 +
To make the unsupported ARM experience slightly less painful, the config template adds <code>[...]</code> as a binary cache, which contains a small subset of packages on the unstable channel (though a caution for US users: the server hosting them is physically located in Finland). Note that the binary cache isn't enabled on the prebuilt images, so enable it via the command line when building for the first time:
  
=== Resizing the boot partition ===
+
<syntaxhighlight lang="bash">nixos-rebuild switch --fast --option binary-caches [...]/channel --option binary-cache-public-keys [...]-1:XXXXXXXXXXXXXX+XXXXXXXXXXXXXX=%</syntaxhighlight>
{{note|The instructions as they are were tested on the Raspberry Pi 3}}
+
-->
 
 
{{warning|Platforms needing a secondary boot loader before the boot partition, (when using <code>dd</code> to add u-boot, MLO or SPL) will need to take in consideration where the original <code>/boot</code> partition starts.}}
 
 
 
It is possible that you run out of disk space on the boot partition after some system upgrades.
 
To resize the boot partition:
 
* (If not already done, boot once to trigger the initial partition resizing)
 
* Backup the files currently stored in the boot partition
 
* Repartition and make sure to delete and then recreate the boot partition (fat32, primary, label: <code>NIXOS_BOOT</code>)
 
* Copy the files from the backup back to the new boot partition
 
 
 
=== Disable use of <tt>/boot</tt> partition ===
 
{{note|The instructions as they are were tested on the PINE A64-LTS, though were written for the Raspberry Pi 3}}
 
 
 
The <tt>/boot</tt> partition is quite small on the NixOS on ARM images. This means that few generations can be kept, and <code>nixos-rebuild</code> can often fail due to lack of space.
 
 
 
Here are quick [https://github.com/NixOS/nixpkgs/issues/22014#issuecomment-290152982 instructions to disable use of the (small) <tt>/boot</tt> partition]. The disk used in the following example is <tt>/dev/mmcblk1</tt> which may differ depending on use of SD card and the particular device.
 
 
 
{{commands|<nowiki>
 
# umount /boot
 
</nowiki>}}
 
 
 
Comment out the fileSystems."/boot" entry from configuration.nix
 
 
 
{{commands|<nowiki>
 
# $EDITOR /etc/configuration.nix
 
</nowiki>}}
 
 
 
Use fdisk or cfdisk to remove the bootable flag from the FAT32 partition, and set it for the ext4 partition
 
 
 
{{commands|<nowiki>
 
# fdisk -l /dev/mmcblk1
 
Disk /dev/mmcblk1: 58.2 GiB, 62537072640 bytes, 122142720 sectors
 
Units: sectors of 1 * 512 = 512 bytes
 
Sector size (logical/physical): 512 bytes / 512 bytes
 
I/O size (minimum/optimal): 512 bytes / 512 bytes
 
Disklabel type: dos
 
Disk identifier: 0x2178694e
 
 
 
Device        Boot  Start      End  Sectors  Size Id Type
 
/dev/mmcblk1p1 *    16384    262143    245760  120M  b W95 FAT32
 
/dev/mmcblk1p2      262144 122142567 121880424 58.1G 83 Linux
 
 
 
# echo -e 'a\n1\na\n2\nw' | fdisk /dev/mmcblk1
 
 
 
Welcome to fdisk (util-linux 2.31.1).
 
Changes will remain in memory only, until you decide to write them.
 
Be careful before using the write command.
 
 
 
 
 
Command (m for help): Partition number (1,2, default 2):
 
The bootable flag on partition 1 is disabled now.
 
 
 
Command (m for help): Partition number (1,2, default 2):
 
The bootable flag on partition 2 is enabled now.
 
 
 
Command (m for help): The partition table has been altered.
 
Syncing disks.
 
 
 
 
 
# fdisk -l /dev/mmcblk1
 
Disk /dev/mmcblk1: 58.2 GiB, 62537072640 bytes, 122142720 sectors
 
Units: sectors of 1 * 512 = 512 bytes
 
Sector size (logical/physical): 512 bytes / 512 bytes
 
I/O size (minimum/optimal): 512 bytes / 512 bytes
 
Disklabel type: dos
 
Disk identifier: 0x2178694e
 
 
 
Device        Boot  Start      End  Sectors  Size Id Type
 
/dev/mmcblk1p1      16384    262143    245760  120M  b W95 FAT32
 
/dev/mmcblk1p2 *    262144 122142567 121880424 58.1G 83 Linux
 
</nowiki>}}
 
 
 
Then rebuild the system.
 
 
 
{{commands|<nowiki>
 
$ nixos-rebuild switch
 
</nowiki>}}
 
 
 
You may want to verify the presence of the <tt>/boot/extlinux/extlinux.conf</tt> file.
 
  
 
== Details about the boot process ==
 
== Details about the boot process ==
  
On NixOS, all ARM boards use the popular U-Boot as the bootloader and [https://github.com/u-boot/u-boot/blob/master/doc/README.distro U-Boot's Generic Distro Configuration Concept] as the mechanism to communicate boot information (such as path to kernel zImage, initrd, DTB, command line arguments). For a quick TL;DR about the generic distro configuration support: U-Boot is scripted to scan all attached storage devices & partitions and look for a file named <code>/extlinux/extlinux.conf</code> or <code>/boot/extlinux/extlinux.conf</code> (which will be generated by NixOS, just like <code>/boot/grub/grub.cfg</code> is generated on PCs).
+
On NixOS, all ARM boards are expected to use U-Boot as the firmware and bootloader. NixOS uses [https://github.com/u-boot/u-boot/blob/master/doc/develop/distro.rst U-Boot's Generic Distro Configuration Concept] as the mechanism to communicate boot information (such as path to kernel zImage, initrd, DTB, command line arguments). For a quick TL;DR about the generic distro configuration support: U-Boot is scripted to scan all attached storage devices & partitions and look for a file named <code>/extlinux/extlinux.conf</code> or <code>/boot/extlinux/extlinux.conf</code> (which will be generated by NixOS, just like <code>/boot/grub/grub.cfg</code> is generated on PCs). The partition needs to have its "bootable" flag set.
  
 
U-Boot also provides an interactive shell and the generation selection menu (just like GRUB). However, support for input or display devices varies greatly, depending on the board. Details for what the boards support in relationship to the boot process are detailed in their respective pages.
 
U-Boot also provides an interactive shell and the generation selection menu (just like GRUB). However, support for input or display devices varies greatly, depending on the board. Details for what the boards support in relationship to the boot process are detailed in their respective pages.
Line 471: Line 674:
 
=== The easiest way ===
 
=== The easiest way ===
  
Assuming upstream u-boot supports the board through a defconfig, it is possible possible to build u-boot using the cross-compiling architecture from an x86_64 host. Here's a sample use.
+
Assuming upstream U-Boot supports the board through a defconfig, it is possible possible to build U-Boot using the cross-compiling architecture from an x86_64 host. Here's a sample use.
  
 
<syntaxhighlight>
 
<syntaxhighlight>
Line 482: Line 685:
 
For armv7 and armv6 <code>pkgsCross.arm-embedded</code> should work, this is available in the unstable channel (19.03 and following) by setting <code>-I "nixpkgs=/path/to/new-nixpkgs-checkout</code>.
 
For armv7 and armv6 <code>pkgsCross.arm-embedded</code> should work, this is available in the unstable channel (19.03 and following) by setting <code>-I "nixpkgs=/path/to/new-nixpkgs-checkout</code>.
  
This should build whatever is needed for, and then build u-boot for the desired defconfig, then open a shell with the build in <code>$buildInputs</code>. Do note that this particular invocation may need more changes than only the defconfig if built for other than allwinner boards.
+
This should build whatever is needed for, and then build U-Boot for the desired defconfig, then open a shell with the build in <code>$buildInputs</code>. Do note that this particular invocation may need more changes than only the defconfig if built for other than allwinner boards.
  
 
Here's an example command, for allwinner boards, on how to write to an SD card.
 
Here's an example command, for allwinner boards, on how to write to an SD card.
Line 499: Line 702:
 
* Otherwise, you can get the boot information (path to kernel zImage, initrd, DTB, command line arguments) by extracting <code>extlinux.conf</code> from the boot partition of the image, and then attempt to boot it via the U-Boot shell, or some other mechanism that your board's distro uses (e.g. <code>uEnv.txt</code>).
 
* Otherwise, you can get the boot information (path to kernel zImage, initrd, DTB, command line arguments) by extracting <code>extlinux.conf</code> from the boot partition of the image, and then attempt to boot it via the U-Boot shell, or some other mechanism that your board's distro uses (e.g. <code>uEnv.txt</code>).
  
==== Building u-boot from your NixOS PC ====
+
==== Building U-Boot from your NixOS PC ====
  
 
Assuming
 
Assuming
  
* Your board is supported upstream by u-boot or there is a recent enough fork with <code>extlinux.conf</code> support.
+
* Your board is supported upstream by U-Boot or there is a recent enough fork with <code>extlinux.conf</code> support.
 
* You do not have nix setup on an ARM device
 
* You do not have nix setup on an ARM device
 
* Your nix isn't setup for cross-compilation
 
* Your nix isn't setup for cross-compilation
  
It is still possible to build u-boot using tools provided by NixOS.
+
It is still possible to build U-Boot using tools provided by NixOS.
  
In the following terminal session, replace <code>orangepi_pc_defconfig</code> with the appropriate board [http://git.denx.de/?p=u-boot.git;a=tree;f=configs;hb=HEAD from the configs folder] of u-boot.
+
In the following terminal session, replace <code>orangepi_pc_defconfig</code> with the appropriate board [http://git.denx.de/?p=u-boot.git;a=tree;f=configs;hb=HEAD from the configs folder] of U-Boot.
  
 
{{Commands|<nowiki>
 
{{Commands|<nowiki>
Line 540: Line 743:
 
=== Contributing new boards to nixpkgs ===
 
=== Contributing new boards to nixpkgs ===
  
* Add a new derivation for your board's U-Boot configuration, see for example ubootJetsonTK1 in {{Nixpkgs Link|short=all-packages.nix|pkgs/top-level/all-packages.nix}}.
+
* Add a new derivation for your board's U-Boot configuration, see for example ubootPine64LTS in {{Nixpkgs Link|short=all-packages.nix|pkgs/top-level/all-packages.nix}}.
 
* If your board's U-Boot configuration doesn't use the <code>extlinux.conf</code> format by default, create a patch to enable it. Some C hacking skills & U-Boot knowledge might be required. For some pointers, see this patch to enable it on the Versatile Express.
 
* If your board's U-Boot configuration doesn't use the <code>extlinux.conf</code> format by default, create a patch to enable it. Some C hacking skills & U-Boot knowledge might be required. For some pointers, see this patch to enable it on the Versatile Express.
* Make a pull request, also containing the board-specific instructions. Ping '''@dezgeg''' for review and for building & hosting the U-Boots at http://nixos-arm.dezgeg.me/installer.
+
* Make a pull request, also containing the board-specific instructions.
  
 
== Support ==
 
== Support ==
  
All ARM platforms are experimental. Only AArch64 platforms are currently being worked on for eventual support from NixOS.
+
Only AArch64 is supported by NixOS.
 +
 
 +
All 32 bit ARM platforms are experimental for the time being.
  
There is a dedicated IRC Channel for the upstream effort on [irc://irc.freenode.net/nixos-aarch64 freenode, #nixos-aarch64].
+
There is a dedicated room for the upstream effort on Matrix,
 +
[https://matrix.to/#/#nixos-on-arm:nixos.org #nixos-on-arm:nixos.org].
  
 
== Resources ==
 
== Resources ==

Latest revision as of 06:58, 27 February 2024

ARM support for NixOS is a work-in-progress, but is progressing quickly.

The support varies depending on the architecture and the specific boards. The way the ARM integration is built into NixOS is by making generic builds the first-class citizens; as soon as there is upstream support for the board in the kernel and the bootloader, NixOS should work once updated to these versions. It is still possible, when needed, to build and use a customised bootloader and kernel for specific boards[reference needed]. At this moment in time (late 2021) only AArch64 has full support upstream.

Though, neither armv6l or armv7l are being ignored, fixes are worked on and approved as needed; what's missing is support and upstream builds being maintained in binary form. At the time of writing, no publicly available caches for armv6l or armv7l are available.

For images links, including UEFI install, skip to the Installation section.

Supported devices

Table legend:

Upstream (NixOS) supported devices

NixOS has support for these boards using AArch64 architecture on the nixpkgs-unstable and stable channel.

Support for those board assumes as much is supported as Mainline Linux supports.

Manufacturer Board SoC ISA CPU RAM Storage
Raspberry Pi Foundation Raspberry Pi 3 Broadcom BCM2837 AArch64 / ARMv7 4× Cortex-A53 @ 1.2 - 1.4 GHz 1 GB SD/microSD
Raspberry Pi Foundation Raspberry Pi 4 Broadcom BCM2711 AArch64 / ARMv7 4× Cortex-A72 @ 1.5 - 1.8 GHz 1-8 GB microSD, eMMC

Community supported devices

Manufacturer Board SoC ISA CPU RAM Storage
Apple Apple Silicon Macs M1/M1 Pro/M1 Max AArch64 NVMe
ASUS Tinker Board Rockchip RK3288 ARMv7 4× Cortex-A17 2 GB microSD
Banana Pi Banana Pi Allwinner A20 ARMv7 2× Cortex-A7 1 GB SD, SATA
Banana Pi M64 Banana Pi M64 Allwinner A64 ARMv8 4× Cortex-A53 2 GB microSD, 8GB eMMc
Banana Pi BPI-M5 Banana Pi BPI-M5 Amlogic S905X3 ARMv8.2 4× Cortex-A55 4 GB LPDDR4 microSD, 16G eMMC
BeagleBoard.org BeagleBone Black TI AM335x (src) ARMv7 1× Cortex-A8 @ 1 GHz 512 MB 4 GB eMMC, microSD
Firefly AIO-3399C Rockchip RK3399 AArch64 2× Cortex-A72 @ 2.0 GHz, 4× Cortex-A53 @ 1.5 Ghz 2/4 GB 8/16 GB eMMC, microSD
FriendlyElec NanoPC-T4 Rockchip RK3399 AArch64 2× Cortex-A72 @ 2.0 GHz, 4× Cortex-A53 @ 1.5 Ghz 4 GB 16 GB eMMC, microSD, NVMe
FriendlyElec NanoPi-M4 Rockchip RK3399 AArch64 2× Cortex-A72 @ 2.0 GHz, 4× Cortex-A53 @ 1.5 Ghz 4 GB optional eMMC, microSD
FriendlyElec NanoPi-R6C Rockchip RK3588S AArch64 4× ARM Cortex-A76 @ 2.4 GHz, 4× Cortex-A55 @ 1.8 Ghz 4 GB / 8 GB optional eMMC, microSD, NVMe
Hardkernel ODROID-HC1 & ODROID-HC2 Samsung Exynos 5422 ARMv7 4× Cortex-A15 @ 2GHz, 4× Cortex-A7 @ 1.4GHz 2 GB microSD
Hardkernel ODROID-C2 Amlogic S905 AArch64 4× Cortex-A53 @ 1.5GHz 2 GB eMMC, microSD
Hardkernel ODROID-HC4 Amlogic S905X3 AArch64 4× Cortex-A55 @ 1.8GHz 4 GB microSD, SATA
Libre Computer ROC-RK3399-PC Rockchip RK3399 AArch64 2× Cortex-A72 @ 2.0 GHz, 4× Cortex-A53 @ 1.5 Ghz 4 GB eMMC, microSD, NVMe
Libre Computer ROC-RK3328-CC Rockchip RK3328 AArch64 4× ARM Cortex-A53 @ 1.4GHz 4 GB eMMC, microSD
Libre Computer AML-S905X-CC-V2 Amlogic S905X AArch64 4× Cortex-A53 @ 1.512 GHz 1/2GB eMMC, microSD
Linksprite pcDuino3 Nano Allwinner A20 ARMv7 2× Cortex-A7 @ 1 GHz 1 GB 4 GB NAND, microSD, SATA
NVIDIA Jetson TK1 Tegra K1/T124 ARMv7 4× Cortex-A15 @ 2.3 GHz 2 GB 16 GB eMMC, SD, SATA
NXP i.MX 8M Plus EVK i.MX 8M Plus AArch64 4× Cortex-A53 @ 1.8 Ghz 6 GB 32 GB eMMC, microSD
NXP i.MX 8M Quad EVK i.MX 8M Quad AArch64 4× Cortex-A53 @ 1.5 Ghz + 1x Cortex-M4 3 GB 16 GB eMMC, microSD
OLIMEX Teres-A64 AllWinner A64 AArch64 4x Cortex-A53 @ 1152MHz 2GB 16 GB eMMC, microSD
Orange Pi Orange Pi One Allwinner H3 ARMv7 4× Cortex-A7 @ 1.2 GHz 512 MB microSD
Orange Pi Orange Pi PC Allwinner H3 ARMv7 4× Cortex-A7 @ 1.6 GHz 1 GB SD/microSD
Orange Pi Orange Pi Zero Plus2 (H5) Allwinner H5 AArch64 4× Cortex-A53 @ 1.2 GHz 1 GB SD/microSD + 8GB eMMC
Orange Pi Orange Pi Zero2 (H616) Allwinner H616 AArch64 4× Cortex-A53 @ 1.2 GHz 1 GB SD/microSD + 2MB SPI Flash
Orange Pi Orange Pi R1 Plus LTS Rockchip RK3328 AArch64 4x Cortex-A53 @ -1.5 GHz 1 GB microSD
Orange Pi Orange Pi 5 Rockchip RK3588s AArch64 4× Cortex-A76 @ 2.4GHz, 4×Cortex-A55 @ 1.8 GHz 4/8/16 GB microSD, NVMe
Orange Pi Orange Pi 5 Plus Rockchip RK3588 AArch64 4× Cortex-A76 @ 2.4GHz, 4×Cortex-A55 @ 1.8 GHz 4/8/16 GB eMMC, microSD, NVMe
PINE64 PINE A64-LTS Allwinner R18 AArch64 4× Cortex-A53 @ ? GHz 2 GB microSD & eMMC
PINE64 Pinebook Allwinner A64 AArch64 4× Cortex-A53 @ ? Ghz 2 GB microSD & eMMC
PINE64 Pinebook Pro Rockchip RK3399 AArch64 2× Cortex-A72 @ 2.0 GHz, 4× Cortex-A53 @ 1.5 Ghz 4 GB microSD & eMMC
PINE64 ROCK64 Rockchip RK3328 AArch64 4× Cortex-A53 @ 1.5 GHz 1/2/4 GB microSD/eMMC
PINE64 ROCKPro64 Rockchip RK3399 AArch64 2× Cortex-A72 @ 2.0 GHz, 4× Cortex-A53 @ 1.5 Ghz 2/4 GB microSD/eMMC
Clockworkpi uConsole A06 Rockchip RK3399 AArch64 2× Cortex-A72 @ 2.0 GHz, 4× Cortex-A53 @ 1.5 Ghz 4 GB microSD
Radxa ROCK5 Model B Rockchip RK3588 AArch64 4× Cortex-A76 @ 2.4GHz, 4×Cortex-A55 @ 1.8 GHz 4/8/16 GB eMMC, microSD, NVMe
Radxa ROCK5 Model A Rockchip RK3588s AArch64 4× Cortex-A76 @ 2.4GHz, 4×Cortex-A55 @ 1.8 GHz 4/8/16 GB eMMC, microSD, NVMe
Raspberry Pi Foundation Raspberry Pi Broadcom BCM2835 ARMv6 1 × ARM1176 @ 700 MHz 256 MB / 512 MB SD/microSD
Raspberry Pi Foundation Raspberry Pi 2 Broadcom BCM2836 ARMv7 4× Cortex-A7 @ 900 MHz 1 GB SD/microSD
Raspberry Pi Foundation Raspberry Pi 3 Broadcom BCM2837 AArch64 / ARMv7 4× Cortex-A53 @ 1.2 GHz 1 GB SD/microSD
Raspberry Pi Foundation Raspberry Pi 4 Broadcom BCM2711 AArch64 / ARMv7 4× Cortex-A53 @ 1.5 GHz 1-8 GB microSD
Raspberry Pi Foundation Raspberry Pi 5 Broadcom BCM2712 AArch64 4× Cortex-A76 @ 2.4 GHz 4-8 GB microSD
Toshiba AC100 (mini laptop) Tegra 2 250 (T20) ARMv7 2× Cortex-A9 @ 1 GHz 512 MB 8­­–32 GB eMMC, SD
Wandboard Wandboard Solo/Dual/Quad Freescale i.MX6 ARMv7 1×/2×/4× Cortex-A9 @ 1000 MHz 512 MB / 1 GB / 2 GB microSD, SATA

Special Devices

It is possible to emulate an ARM platform with QEMU.

Manufacturer Board SoC ISA CPU RAM Storage
QEMU QEMU ARMv7 up to 8 up to 2 GB Anything QEMU supports

Installation

Getting the installer

UEFI iso

Note: On Raspberry Pi devices, the NixOS ISO are not compatible due to hardware limitations rather than issues with the NixOS installer itself. As a result, it is recommended to use the SD card images files (.img) instead for a successful installation experience.

Continue to the UEFI page.

SD card images (SBCs and similar platforms)

For AArch64 it is possible to download images from Hydra.

On the page click on the latest successful build to get a download link under build products.

If the image has the extension .zst, it will need to be decompressed before writing to installation device. Use nix-shell -p zstd --run "unzstd <img-name>.img.zst" to decompress the image.

Installation steps

The .img files can be directly written to a microSD/SD card (minimal recommended size: 4 GB) using dd, once uncompressed from the ZSTD container. The SD card needs to be unmounted first.

Once the NixOS image file is downloaded, run the following command to install the image onto the SD Card, replace /dev/mmcblk0 with the path to the SD card (use dmesg to find it out).

sudo dd if=nixos-sd-image-23.05pre482417.9c7cc804254-aarch64-linux.img of=/dev/mmcblk0

This should be enough to get you started, you may now boot your device for the first time.

The base images are configured to boot up with a serial TTY ( RX/TX UART ) @ 115200 Baud. That way you not necessarily have to have a HDMI Display and keyboard.

Note: For some platforms, manually editing and adding kernel command-line arguments to /boot/extlinux/extlinux.conf may be needed for serial to work, and is "as" supported as would be editing the command-line manually during boot.

Continue with #NixOS installation & configuration.

Binary cache

AArch64

The official NixOS Hydra instance builds a full set of binaries (available on https://cache.nixos.org) for the AArch64 architecture on the nixpkgs-unstable and stable channels.

armv6l and armv7l

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.

# 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"
  ];
}

Then build with:

$ nix-build '<nixpkgs/nixos>' -A config.system.build.sdImage -I nixos-config=./sd-image.nix

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 community aarch64 builder.

if you use the experimental flake, instead of doing the above stuff, can put the following lines in flake.nix, git add flake.nix and build with nix build .#images.rpi2:

{
  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;
  };
}

Cross-compiling

It is possible to cross-compile from a different architecture. To cross-compile to armv7l, on the same sd-image.nix add in crossSystem:

{ ... }: {
  nixpkgs.crossSystem.system = "armv7l-linux";
  imports = [
    <nixpkgs/nixos/modules/installer/sd-card/sd-image-aarch64.nix>
  ];
  # ...
}

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 wrapper uses emulation and will therefore be slower than comparable native machines or cross-compiling.

To enable the binfmt wrapper on NixOS, add the following to configuration.nix

{
  boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
}

Then, add --argstr system aarch64-linux to the build command:

$ nix-build '<nixpkgs/nixos>' -A config.system.build.sdImage -I nixos-config=./sd-image.nix --argstr system aarch64-linux

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 /etc/nix/nix.conf: extra-platforms = aarch64-linux arm-linux

Note: archlinux users can install extra/qemu-system-aarch64, extra/qemu-user-static and extra/qemu-user-static-binfmt and restart systemd-binfmt.service. Check if binfmt is loaded by ls /proc/sys/fs/binfmt_misc/ (there must be qemu-aarch64 or needed architecture) and add line extra-sandbox-paths = /usr/bin/qemu-aarch64-static to /etc/nix/nix.conf and don't forget to restart the nix-daemon.service systemd unit afterwards.

If you want to build just one specific package, use this:

nix-build '<nixpkgs/nixos>' -A pkgs.theRequiredPackage --argstr system aarch64-linux -I nixos-config=/path/to/target/machine/nixos/config/copy

(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

The Mic92/nixos-aarch64-images repository provides a mechanism to modify the official NixOS installer to embed the board-specific U-Boot firmware required for different boards. This method does not require QEMU or native ARM builds since the existing Hydra-built U-Boot binaries are used.

Board-specific installation notes

Depending on the board, some additional preparation steps might be needed to make the SD card bootable on your device. All of the board-specific installation notes are now found on their respective pages.

Enable UART

If you try to use UART to log on NixOS, you might hang on the line "Starting kernel ...". To enable UART, you will need to add at the end of the line that contains loglevel4 in the file /extlinux/extlinux.conf the text:

Breeze-text-x-plain.png
/extlinux/extlinux.conf
    console=ttyAMA0,115200n8
Breeze-text-x-plain.png
/extlinux/extlinux.conf
    console=ttyS0,115200n8

The actual device (ttyAMA0, ttyS0, ttyS1) will depend on the hardware.

NixOS installation & configuration

The installation image is actually a MBR partition table plus two partitions; a FAT16 /boot and a ext4 root filesystem. The image is designed such that it's possible to directly reuse the SD image's partition layout and "install" NixOS on the very same SD card by simply replacing the default configuration.nix and running nixos-rebuild. Using this installation method is strongly recommended, though if you know exactly what you're doing and how U-Boot on your board works, you can use nixos-install as usual. To help with the SD card installation method, the boot scripts on the image automatically resize the rootfs partition to fit the SD card on the first boot.

  • To generate a default /etc/nixos/configuration.nix file, run sudo nixos-generate-config.
  • You can also use an existing template:
Breeze-text-x-plain.png
/etc/nixos/configuration.nix
{ config, pkgs, lib, ... }:
{
  # NixOS wants to enable GRUB by default
  boot.loader.grub.enable = false;
  # Enables the generation of /boot/extlinux/extlinux.conf
  boot.loader.generic-extlinux-compatible.enable = true;
 
  # !!! If your board is a Raspberry Pi 1, select this:
  boot.kernelPackages = pkgs.linuxPackages_rpi;
  # On other boards, pick a different kernel, note that on most boards with good mainline support, default, latest and hardened should all work
  # Others might need a BSP kernel, which should be noted in their respective wiki entries
  
  # !!! This is only for ARMv6 / ARMv7. Don't enable this on AArch64, cache.nixos.org works there.
  nix.binaryCaches = lib.mkForce [ "https://cache.armv7l.xyz" ];
  nix.binaryCachePublicKeys = [ "cache.armv7l.xyz-1:kBY/eGnBAYiqYfg0fy0inWhshUo+pGFM3Pj7kIkmlBk=" ];
    
  # nixos-generate-config should normally set up file systems correctly
  imports = [ ./hardware-configuration.nix ];
  # If not, you can set them up manually as shown below
  /*
  fileSystems = {
    # Prior to 19.09, the boot partition was hosted on the smaller first partition
    # Starting with 19.09, the /boot folder is on the main bigger partition.
    # The following is to be used only with older images. Note such old images should not be considered supported anymore whatsoever, but if you installed back then, this might be needed
    /*
    "/boot" = {
      device = "/dev/disk/by-label/NIXOS_BOOT";
      fsType = "vfat";
    };
    */
    "/" = {
      device = "/dev/disk/by-label/NIXOS_SD";
      fsType = "ext4";
    };
  };
  */
    
  # !!! Adding a swap file is optional, but recommended if you use RAM-intensive applications that might OOM otherwise. 
  # Size is in MiB, set to whatever you want (though note a larger value will use more disk space).
  # swapDevices = [ { device = "/swapfile"; size = 1024; } ];
}

Note: the default configuration.nix will contain something like imports = [ <nixos/modules/installer/sd-card/sd-image-armv7l-multiplatform.nix> ]; do not include that in your final installation or you will experience interesting problems. It is only for building the installation image!

First rebuild on ARMv6 and ARMv7

To rebuild your system, run: sudo nixos-rebuild switch

Note: Instructions removed since they referred to a long abandoned user-provided cache...

Details about the boot process

On NixOS, all ARM boards are expected to use U-Boot as the firmware and bootloader. NixOS uses U-Boot's Generic Distro Configuration Concept as the mechanism to communicate boot information (such as path to kernel zImage, initrd, DTB, command line arguments). For a quick TL;DR about the generic distro configuration support: U-Boot is scripted to scan all attached storage devices & partitions and look for a file named /extlinux/extlinux.conf or /boot/extlinux/extlinux.conf (which will be generated by NixOS, just like /boot/grub/grub.cfg is generated on PCs). The partition needs to have its "bootable" flag set.

U-Boot also provides an interactive shell and the generation selection menu (just like GRUB). However, support for input or display devices varies greatly, depending on the board. Details for what the boards support in relationship to the boot process are detailed in their respective pages.

Porting NixOS to new boards

The easiest way

Assuming upstream U-Boot supports the board through a defconfig, it is possible possible to build U-Boot using the cross-compiling architecture from an x86_64 host. Here's a sample use.

# Assuming you're in a recent nixpkgs checkout
$ nix-shell \
    -I "nixpkgs=$PWD" \
    -p 'let plat = pkgsCross.aarch64-multiplatform; in plat.buildUBoot{defconfig = "orangepi_zero_plus2_defconfig"; extraMeta.platforms = ["aarch64-linux"]; BL31 = "${plat.armTrustedFirmwareAllwinner}/bl31.bin"; filesToInstall = ["u-boot-sunxi-with-spl.bin"];}'

For armv7 and armv6 pkgsCross.arm-embedded should work, this is available in the unstable channel (19.03 and following) by setting -I "nixpkgs=/path/to/new-nixpkgs-checkout.

This should build whatever is needed for, and then build U-Boot for the desired defconfig, then open a shell with the build in $buildInputs. Do note that this particular invocation may need more changes than only the defconfig if built for other than allwinner boards.

Here's an example command, for allwinner boards, on how to write to an SD card.

$ sudo dd if=$buildInputs/u-boot-sunxi-with-spl.bin of=/dev/sdX bs=1024 seek=8

The easy way

(if you're lucky)

If your board is an ARMv7 board supported by multi_v7_defconfig and you have access to U-Boot on the board, getting sd-image-armv7l-linux.img to boot is the easiest option:

  • If you're lucky and your U-Boot build comes with the extlinux.conf support built in, the image boots out-of-the-box. This is the case for all (upstream) Allwinner and Tegra U-Boots, for instance.
  • Otherwise, you can get the boot information (path to kernel zImage, initrd, DTB, command line arguments) by extracting extlinux.conf from the boot partition of the image, and then attempt to boot it via the U-Boot shell, or some other mechanism that your board's distro uses (e.g. uEnv.txt).

Building U-Boot from your NixOS PC

Assuming

  • Your board is supported upstream by U-Boot or there is a recent enough fork with extlinux.conf support.
  • You do not have nix setup on an ARM device
  • Your nix isn't setup for cross-compilation

It is still possible to build U-Boot using tools provided by NixOS.

In the following terminal session, replace orangepi_pc_defconfig with the appropriate board from the configs folder of U-Boot.

$ nix-shell -E 'with import <nixpkgs> {}; stdenv.mkDerivation { name = "arm-shell"; buildInputs = [git gnumake gcc gcc-arm-embedded dtc]; }'
$ git clone git://git.denx.de/u-boot.git
$ cd u-boot
# We're checking out a version from before the use of `binman`.
# The dtc package is 1.4.2, which does not include `pylibftd`.
# Furthermore, I do not know how to package the library so it would be
# available in the python interpreter, making binman happy.
$ git checkout v2017.03
$ make -j4 CROSS_COMPILE=arm-none-eabi- orangepi_pc_defconfig
$ make -j4 CROSS_COMPILE=arm-none-eabi-

The name of the final file will change depending on the board. For this specific build, and most Allwinner builds, the file will be named u-boot-sunxi-with-spl.bin.

You can flash this file to boot device with

 dd if=u-boot-sunxi-with-spl.bin of=/dev/sdX bs=1024 seek=8

Note: This mailing list contains a patch which may help some builds: https://lists.denx.de/pipermail/u-boot/2016-December/275664.html

The hard way

Alternatively/if all else fails, you can do it the hard way and bootstrap NixOS from an existing ARM Linux installation.

Contributing new boards to nixpkgs

  • Add a new derivation for your board's U-Boot configuration, see for example ubootPine64LTS in Nixpkgs-link.pngall-packages.nix.
  • If your board's U-Boot configuration doesn't use the extlinux.conf format by default, create a patch to enable it. Some C hacking skills & U-Boot knowledge might be required. For some pointers, see this patch to enable it on the Versatile Express.
  • Make a pull request, also containing the board-specific instructions.

Support

Only AArch64 is supported by NixOS.

All 32 bit ARM platforms are experimental for the time being.

There is a dedicated room for the upstream effort on Matrix, #nixos-on-arm:nixos.org.

Resources

Subpages

The following is a list of all sub-pages of the NixOS on ARM topic.