Guix sur une carte ARM
par Julien Lepiller — mer. 27 novembre 2019
De plus en plus les gens qui découvrent Guix veulent l'essayer sur une carte ARM, au lieu de leur ordinateur x86. Il peut y avoir plusieurs raisons pour cela, comme la consommation de ressources ou la sécurité. Dans mon cas, j'ai trouvé ces cartes pratiques pour l'autohébergement et je crois que les propriétés uniques de Guix font que ce système est parfaitement adapté à ce cas d'utilisation. J'ai installé GNU Guix sur un Cubietruck, donc mes exemples ci-dessous parleront de cette carte. Cependant, vous devriez être capables de changer les exemples pour votre propre cas.
Installer le système Guix sur une carte ARM n'est pas aussi facile que pour un ordinateur de bureau à base x86 : il n'y a pas d'image d'installation. Cependant, Guix prend en charge ARM et peut être installé sur une distribution externe qui tourne sur cette architecture. L'astuce consiste à utiliser le Guix installé sur cette distribution externe pour initialiser le système Guix. Cet article va vous montrer comment installer le système Guix sur votre carte, sans utiliser d'image d'installation. Comme cela a déjà été mentionné, il est possible de générer une image d'installation par vous-même, si votre carte est prise en charge.
La plupart des cartes peuvent être démarrées avec une distribution GNU+Linux existante. Vous aurez besoin d'installer une distribution (n'importe laquelle) et d'installer GNU Guix dessus, en utilisant p. ex. le script d'installation. Ensuite, mon plan était d'installer le système Guix sur un disque SSD externe, au lieu de la carte SD, mais nous verrons que les deux cas sont parfaitement possibles.
La première partie de cet article se concentrera sur la création d'une configuration u-boot appropriée et d'une déclaration du système d'exploitation qui correspond à votre carte. La seconde partie de cet article se concentrera sur la procédure d'installation, quand il n'y a pas d'installateur pour votre système.
Écrirure un fichier de configuration pour une carte ARM
Un fichier de configuration pour une carte ARM n'est pas très différent d'un fichier de configuration pour un bureau ou un serveur qui utilise une autre architecture. Cependant, la plupart des cartes utilise le chargeur d'amorçage u-boot et ont besoin de modules moins communs au démarrages.
Le système de fichiers racine
Tout d'abord, vous devriez décider où votre système de fichiers racine sera installé. Dans mon cas, je voulais l'installer sur le SSD externe, donc j'ai choisi ceci :
(file-systems
(cons* (file-system
(mount-point "/")
(device "/dev/sda1")
(type "ext4"))
%base-file-systems))
Si vous voulez plutôt installer le système de fichiers racine sur une carte
SD, vous devrez trouver son nom de périphérique associé, généralement /dev/mmcblk0
et le numéro de partition. Le périphérique correspondant à la première partition
devrait être /dev/mmcblk0p1
. Dans ce cas, vous devriez avoir :
(file-systems
(cons* (file-system
(mount-point "/")
(device "/dev/mmcblk0p1")
(type "ext4"))
%base-file-systems))
Le chargeur d'amorçage
Because of the way the Guix System is designed, you cannot use an already existing bootloader to boot your system: it wouldn't know where to look for the kernel, because it doesn't know its store path. It wouldn't be able to let you boot older generations either. Most boards use the u-boot bootloader, so we will focus on that bootloader here.
Contrary to grub, there are multiple variants of u-boot, one per board type. The installation procedure for u-boot is also somewhat specific to the board, so there are two things that you need to take care of: the u-boot package and the bootloader declaration.
Guix défini déjà quelques chargeurs d'amorçages basés sur u-boot, comme u-boot-a20-olinuxino-lime-bootloader
ou u-boot-pine64-plus-bootloader
entre autres. Si votre carte a déjà un u-boot-*-bootloader
défini dans (gnu bootloader u-boot)
, vous avez de la chance et vous pouvez passer cette partie
de l'article !
Sinon, peut-être que le paquet du chargeur d'amorçage est défini dans (gnu packages bootloaders)
,
comme c'est le cas du paquet u-boot-cubietruck
. Si c'est le cas, vous avez un peu
de chance et vous pouvez passer la création de votre propre définition d'un paquet.
Si votre carte n'a pas de paquet u-boot-*
défini, vous pouvez en créer un.
Cela peut être aussi simple que (make-u-boot-package "Cubietruck" "arm-linux-gnueabihf")
.
Le premier argument est le nom de la carte, tel que le connait le système de
construction de u-boot. Le second argument est le triplet cible qui correspond
à l'architecture de la carte. Vous devriez vous référer à la documentation de
votre carte pour choisir les bonnes valeurs. Si vous n'avez vraiment pas de chance,
vous devrez travailler un peu plus pour que le paquet u-boot que vous venez de créer
fonctionne, comme c'est le cas de u-boot-puma-rk3399
par exemple : il a besoin
de phases supplémentaires pour installer un firmware.
Vous pouvez ajouter la définition du paquet à votre fichier de configuration du système d'exploitation comme ceci, avant la déclaration du système d'exploitation :
(use-modules (gnu packages bootloaders))
(define u-boot-my-board
(make-u-boot-package "Myboard" "arm-linux-gnueabihf"))
(operating-system
[...])
Ensuite, vous devrez définir le chargeur d'amorçage. Un chargeur d'amorçage est une structure qui a un nom, un paquet, un installateur, un fichier de configuration et un générateur de fichiers de configuration. Heureusement, Guix défini déjà un chargeur d'amorçage u-boot de base, donc on peut en hériter et seulement définir une partie.
Le Cubietruck est basé sur un cœur allwinner, pour lequel il y a déjà une définition
du chargeur d'amorçage u-boot u-boot-allwinner-bootloader
. Ce chargeur
d'amorçage n'est pas utilisable par le Cubietruck, mais il défini presque tout
ce dont on a besoin. Pour en faire un chargeur d'amorçage correct pour le Cubietruck,
nous définissons un chargeur d'amorçage basé sur la définition du chargeur d'amorçage
pour Allwinner :
(define u-boot-cubietruck-bootloader
(bootloader
(inherit u-boot-allwinner-bootloader)
(package u-boot-cubietruck)))
Maintenant que nous avons nos définitions, nous pouvons choisir où installer
le chargeur d'amorçage. Dans le cas du Cubietruck, j'ai décidé de l'installer
sur la carte SD, parce qu'il ne peut pas démarrer depuis le SSD directement.
Référez-vous à la documentation de votre carte pour vous assurer d'installer
u-boot sur un périphérique amorçable. Comme je le disais tout à l'heure,
la carte SD est /dev/mmcblk0
sur mon appareil.
On peut maintenant tout mettre ensemble comme ceci :
(use-modules (gnu packages bootloaders))
(define u-boot-cubietruck
(make-u-boot-package "Cubietruck" "arm-linux-gnueabihf"))
;; u-boot-allwinner-bootloader n'est pas exporté par (gnu bootloader u-boot),
;; donc nous utilisons @@ pour le récupérer. (@ (module) variable) signifie :
;; récupère la valeur de « variable » définie (et exportée) dans (module).
;; (@@ (module) variable) signifie la même chose, mais se fiche de savoir
;; si la variable est exportée ou non.
(define u-boot-allwinner-bootloader
(@@ (gnu bootloader u-boot) u-boot-allwinner-bootloader))
(define u-boot-cubietruck-bootloader
(bootloader
(inherit u-boot-allwinner-bootloader)
(package u-boot-cubietruck)))
(operating-system
[...]
(bootloader
(bootloader-configuration
(target "/dev/mmcblk0")
(bootloader u-boot-cubietruck-bootloader)))
[...])
Les modules du noyau
Pour que Guix puisse charger le système à partir de l'initramfs, il aura surement
besoin de charger quelques modules, surtout pour accéder au système de fichiers
racine. Dans mon cas, le SSD est un périphérique AHCI, donc j'ai besoin d'un
pilote approprié. Le noyau défini ahci_sunx
pour ce périphiérique sur toutes
les cartes sunxi. La carte SD elle-même a besoin de deux pilotes : sunxi-mmc
et sd_mod
.
Votre propre carte peut avoir besoin d'autres modules du noyau pour démarrer
correctement, mais il est difficile de les découvrir. Guix peut vous indiquer
qu'un module manque dans votre configuration s'il est chargé en tant que
module. La plupart des distributions construisent ces modules en dur dans le
noyau directement, donc Guix ne peut pas les détecter correctement. Une autre
manière de découvrir les pilotes qui peuvent être requis consiste à regarder
la sortie de dmesg
. Vous trouverez des messages comme :
[ 5.193684] sunxi-mmc 1c0f000.mmc: Got CD GPIO
[ 5.219697] sunxi-mmc 1c0f000.mmc: initialized, max. request size: 16384 KB
[ 5.221819] sunxi-mmc 1c12000.mmc: allocated mmc-pwrseq
[ 5.245620] sunxi-mmc 1c12000.mmc: initialized, max. request size: 16384 KB
[ 5.255341] mmc0: host does not support reading read-only switch, assuming write-enable
[ 5.265310] mmc0: new high speed SDHC card at address 0007
[ 5.268723] mmcblk0: mmc0:0007 SD32G 29.9 GiB
ou
[ 5.614961] ahci-sunxi 1c18000.sata: controller can't do PMP, turning off CAP_PMP
[ 5.614981] ahci-sunxi 1c18000.sata: forcing PORTS_IMPL to 0x1
[ 5.615067] ahci-sunxi 1c18000.sata: AHCI 0001.0100 32 slots 1 ports 3 Gbps 0x1 impl platform mode
[ 5.615083] ahci-sunxi 1c18000.sata: flags: ncq sntf pm led clo only pio slum part ccc
[ 5.616840] scsi host0: ahci-sunxi
[ 5.617458] ata1: SATA max UDMA/133 mmio [mem 0x01c18000-0x01c18fff] port 0x100 irq 37
[ 5.933494] ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
Remarquez aussi que les noms des modules ne sont pas cohérents entre ce qu'attend Guix et ce qui est affiché par dmesg, surtout quand ils contiennent un « - » ou un « _ ». Vous trouverez le bon nom de fichier en construisant (ou en utilisant un substitute pour) linux-libre :
find `guix build linux-libre`/lib/modules -name '*mmc*'
Ici, j'ai trouvé un fichier nommé kernel/drivers/mmc/host/sunxi-mmc.ke
, d'où
le nom de module sunxi-mmc
. Pour l'autre pilote, j'ai trouvé
kernel/drivers/ata/ahci_sunxi.ko
, d'où le nom ahci_sunxi
, même si dmesg
suggérait ahci-sunxi
.
Une fois que vous avez trouvé les modules que vous voulez charger avant de monter votre partition racine, vous pouvez les ajouter à votre fichier de déclaration du système d'exploitation :
(initrd-modules (cons* "sunxi-mmc" "sd_mod" "ahci_sunxi" %base-initrd-modules))
Installer le système Guix
Installer sur un autre périphérique
Dans mon cas, je voulais installer le système sur un SSD externe, alors que le système de la distribution externe tournait sur la carte SD. Ce qui est bien avec ce scénario, c'est qu'en cas de vrai souci (votre SSD a pris feu ou est cassé), vous pouvez toujours démarrer sur l'ancien système extrene avec Guix installé dessus et tous vos outils en reflashant simplement le chargeur d'amorçage.
Dans ce scénario, nous utilisons le système externe comme nous aurions utilisé l'iso de l'installateur, en utilisant la procédure l'installation manuelle décrite dans le manuel. EN gros, vous devez partitionner votre SSD comme vous le souhaitez, formater vos nouvelles partitions et vous assurer de référencer la bonne partition qui contient le système de fichiers racine dans votre fichier de configuration. Ensuite, initialisez le système avec :
mount /dev/sda1 /mnt
mkdir /mnt/etc
$EDITOR /mnt/etc/config.scm # create the configuration file
guix system init /mnt/etc/config.scm /mnt
Vous pouvez maintenant redémarrer et jouer avec votre nouveau système Guix !
Installer sur le même périphérique
Une autre option consiste à installer le système Guix par dessus une distribution externe existante, en la remplaçant complètement. Remarquez que le système de fichiers racine du nouveau système Guix est le système de fichiers racine actuel, donc il n'est pas nécessaire de le monter. Les commandes suivantes vont initialiser votre système :
$EDITOR /etc/config.scm # create the configuration file
guix system init /etc/config.scm /
Assurez-vous de supprimer les fichiers de votre ancien système. Vous devriez
au moins vous débarrasser du répertoire /etc
, comme ceci :
mv /etc{,.bak}
mkdir /etc
Assurez-vous qu'il y a un dossier /etc
vide, ou le nouveau système ne démarrera
pas correctement. Vous pouvez copier votre config.scm
vers votre nouveau
répertoire /etc
. Vous pouvez maintenant redémarrer et profiter de votre
nouveau système Guix !
À propos de GNU Guix
GNU Guix est un gestionnaire de paquets transactionnel et une distribution avancée du système GNU qui respecte les libertés de ses utilisateurs. Guix est utilisable sur tous les systèmes qui utilisent le noyau Linux ou en tant que distribution de système d'exploitation indépendante pour le machines à base i686, x86_64, ARMv7 et AArch64.
En plus des fonctionnalités de gestion des paquets standards, Guix prend en charge les mises à jour et les retours transactionnels, la gestion de paquets non privilégiée, les profils par utilisateur et le nettoyage. Lorsqu'il est utilisé comme distribution GNU/Linux indépendante, Guix propose une approche déclarative et sans état à la gestion de configuration du système d'exploitation. Guix est facilement personnalisable et hackable à travers ses interfaces de programmation Guile et ses extensions au langage Scheme.