NixOS on ARM/UEFI/fr: Difference between revisions

From NixOS Wiki
Nicolas-goudry (talk | contribs)
Created page with "=== Micrologiciel de la plateforme ==="
Nicolas-goudry (talk | contribs)
Created page with "Définissons d'abord ce qu'est un '''micrologiciel de plateforme'''. C'est un terme générique utilisé pour décrire la première chose démarrée par le processeur lors du démarrage. Sur un système <tt>x86_64</tt>, il s'agit de ce qu'on appelait autrefois le ''BIOS''. Aujourd'hui souvent appelé ''EFI''. C'est ce qui initialise suffisamment de matériel pour que le système d'exploitation puisse démarrer. De plus, il offre souvent à l'utilisateur d'effectuer une c..."
Line 18: Line 18:
=== Micrologiciel de la plateforme ===
=== Micrologiciel de la plateforme ===


<div lang="en" dir="ltr" class="mw-content-ltr">
Définissons d'abord ce qu'est un '''micrologiciel de plateforme'''. C'est un terme générique utilisé pour décrire la première chose démarrée par le processeur lors du démarrage. Sur un système <tt>x86_64</tt>, il s'agit de ce qu'on appelait autrefois le ''BIOS''. Aujourd'hui souvent appelé ''EFI''. C'est ce qui initialise suffisamment de matériel pour que le système d'exploitation puisse démarrer. De plus, il offre souvent à l'utilisateur d'effectuer une configuration basique ainsi que la gestion des options de démarrage.
Let's define what a '''Platform Firmware''' is. It is a generic term I'm using to describe the first thing the CPU starts at boot time. On your typical <tt>x86_64</tt> system, it would be what was previously called the ''BIOS''. Now often diminutively called by the name ''EFI''. This is what initializes enough of the hardware so that the operating system can start. Additionally, it often provides facilities for the user to do basic configuration, and manage boot options.
</div>


<div lang="en" dir="ltr" class="mw-content-ltr">
<div lang="en" dir="ltr" class="mw-content-ltr">

Revision as of 15:57, 12 July 2024

Note: Cette page présume d'une architecture AArch64. La plupart des instructions fonctionneront également pour une architecture armv7l (à date du 19/07/2022), néanmoins l'état actuel du support d'armv7l dans NixOS ne donnera pas une très bonne expérience.

Cette section de la documentation NixOS sur ARM a pour but de documenter le plus d'éléments possibles pour démarrer n'importe quelle carte ARM utilisant l'UEFI. Ce document se concentre particulièrement sur les ordinateurs à carte unique (aussi appelés SBCs), étant donné que c'est pour ceux-ci que le démarrage est le plus compliqué, voir carrément impossible.

Les bases

Support cible

Certains points ne seront pas spécifiques à UEFI. Pour exemple, le support en fonction du noyau utilisé. Ce document présume que les distributions Linux standard fonctionnent sur le système cible afin d'envisager l'installation depuis une image disque (ISO) générique.

Tout comme il est possible de le faire sur x86_64, vous pouvez construire une image disque personnalisée. Les détails sur une telle opération sortent du cadre de cet article. Les mêmes pièges sont à prévoir et éviter. Par exemple, la configuration générée ne prendra pas en compte la personnalisation de la configuration du noyau.

Micrologiciel de la plateforme

Définissons d'abord ce qu'est un micrologiciel de plateforme. C'est un terme générique utilisé pour décrire la première chose démarrée par le processeur lors du démarrage. Sur un système x86_64, il s'agit de ce qu'on appelait autrefois le BIOS. Aujourd'hui souvent appelé EFI. C'est ce qui initialise suffisamment de matériel pour que le système d'exploitation puisse démarrer. De plus, il offre souvent à l'utilisateur d'effectuer une configuration basique ainsi que la gestion des options de démarrage.

In the ARM with SBCs landscape, U-Boot is the de facto solution for the Platform Firmware. Though U-Boot is confusingly, but rightly, often referred to as a Boot Loader. U-Boot plays double duties often. It is tasked with initializing the hardware, and often also used to handle loading and booting the operating system.

UEFI

The Unified Extensible Firmware Interface it not in itself a tangible thing. Wrongly abstracted, it is a specification used to provide an interface to describe a standard boot process, including an environment before the operating system starts, and protocols for operating systems.

There are multiple implementations of UEFI. Vendors like American Megatrends, Phoenix Technologies and Insyde Software may have produced the one on your personal x86_64 machine. TianoCore is the reference UEFI implementation, and Open Source. Luckily enough, U-Boot implements enough (and a bit more) of the UEFI spec.

SBBR? EBBR?

Other than letter salads, they are Server Base Boot Requirements and Embedded Base Boot Requirements. Two specifications for ARM. If your target is in compliance with either, booting with UEFI should already be supported. With the minimal UEFI support in U-Boot, targets that were not made to be EBBR compliant can be made compliant, or be close enough for what it matters.

UEFI, on my SBC???

Believe me or not, it's more likely that you can, if your SBC is well supported by mainline U-Boot. U-Boot provides enough UEFI to comply with EBBR, which in turn is enough to allow us to boot the AArch64 UEFI NixOS iso, and with almost no differences compared to the x86_64 guide, simply follow the installation instruction to boot into an installed system.

Getting a Platform Firmware

As an opinionated example, you can get started with Tow-Boot, a U-Boot distribution, which is intended to make the initial setup a bit easier by abstracting the platform differences so that they do not matter.

Any other UEFI compliant Platform Firmware can be used.

Getting the installer image (ISO)

Choose one of the images (in rough order of preference):

  • NixOS unstable, new kernel – rolling release, latest mainline kernel, does not build with ZFS as it would often lag behind.
  • NixOS unstable, LTS kernel – may be less compatible with specific hardware, but tracks a more recent Nixpkgs
  • NixOS stable – release branch, LTS kernel, generally not recommended unless you are confident your hardware is well-supported upstream

Graphical ISOs are also available in the GNOME and KDE flavors.

This installer image should be written to a USB drive, like usual. In a pinch, it may also be written to an SD image, if your target's platform firmware does not need to be written to that same SD image.

Installing

Following the usual installation steps for UEFI is almost enough. Here's what you need to be mindful about.

Sidenote: As the introduction stated, this guide assumes that the kernel in use fully supports your target board. If there are issues that comes from lack of hardware support, it is not a bug in this documentation.

Shared Firmware Storage

Note: This will make more sense when Getting a Platform Firmware is finished...

If your Platform Firmware lives on the target installation storage, e.g. written to an SD card and you install to the same SD card, you will need need to make sure that:

  • You are not overwriting the firmware, if it is not protected by a partition.
  • The partition table is not rewritten from scratch / zero.
  • To not delete required existing firmware partitions.
Note: If your Platform Firmware is not protected by a partition, consider choosing an alternative Platform Firmware installation method or distribution that protects it.

Otherwise, you can do as you would usually, create an ESP partition, FAT32, to be mounted at /boot/, your preferred rootfs partition, swap if desired, etc.

Bootloader configuration

Know if your Platform Firmware's UEFI implementation has writable EFI vars. This is not true for all UEFI implementations on ARM, but is something to be mindful about. If it does not, boot.loader.efi.canTouchEfiVariables has to be set to false.

/etc/nixos/configuration.nix
{
  boot.loader.efi.canTouchEfiVariables = false;
}

This sample uses GRUB2, but systemd-boot was also verified to work. Since EFI variables cannot be manipulated, using efiInstallAsRemovable handles installing GRUB2 to the default fallback location.

/etc/nixos/configuration.nix
{
  boot.loader.grub.enable = true;
  boot.loader.grub.efiSupport = true;
  boot.loader.grub.efiInstallAsRemovable = true;
  boot.loader.grub.device = "nodev";
}

General Tips

Using the latest kernel is probably a good idea. Hardware support for ARM platforms is always improving, and using the latest kernel, rather than the "latest LTS", might be enough to break it or make it.

/etc/nixos/configuration.nix
{
  boot.kernelPackages = pkgs.linuxPackages_latest;
}

Known Issues

Device Trees

As of right now, there is no consensus within Linux distros about the topic of managing device trees for the boot process with UEFI.

This current setup relies on the platform firmware providing an appropriate device tree for the kernel that will run.

With U-Boot, it is possible to make it load a device tree, for example a more up-to-date one, by placing the dtb folder from a kernel build output at the /dtb location in the ESP. U-Boot will automatically load a device tree according to heuristics, which should be the right one.

It is unknown how much of an actual issue this is in practice.