Archives de catégorie : Debian

All articles related to Debian distribution.

Installer Debian sur un portable Asus X73SL

En voulant installer une distribution Linux sur un ordinateur portable de marque Asus, modèle X73SL je me suis heurté à plusieurs problèmes. ll m’a semblé intéressant de les consigner ici, avec les sources que j’ai utilisé pour les résoudres.

Les solutions que je vais donner ici peuvent probablement être appliquées à d’autres distributions Linux (Ubuntu, Fedora, etc) mais nécessiteront peut être un peu d’adaptation. Par ailleurs, il semblerait qu’Asus ai basé plusieurs modèle de portables sur la même carte mère, il se pourrait donc que ces solutions fonctionnent aussi pour les modèles X70, X71, X72, X73 (avec des lettres derrière cette dénomination, voir ici).

TL;DR

Pour les lecteurs (expérimentés ou non qui voudraient un solution rapide) voici le ajustements que j’ai fait :

  • La carte mère ne supporte pas le interruptions MSI, il faut les désactiver pour le noyau dans son ensemble et le driver nouveau en ajoutant les paramètres pci=nomsi et nouveau.config=NvMSI=0 à la ligne de commande du noyau. Soit en live au moment du boot, soit de manière permanente les ajoutant à la variable GRUB_CMD_LINUX en éditant /etc/default/grub, puis en lançant update-grub.
  • Le chipset ethernet SiS191 ne supporte pas un MTU supérieur à 1496, il faut donc éditer votre configuration réseau (par un menu ou une configuration NetworkManager) pour définir sa valeur à 1496

Point de départ

Mon objectif était d’installer une distribution Linux sur un vieux portable Asus (de 2009) histoire de lui donner une seconde jeunesse. Le PC est un Asus X73SL-TY024C avec la configuration suivante :

  • Intel Pentium Dual CPU T3400 @ 2.16GHz (1Mo de cache, bus à 667Mhz)
  • Carte mère avec un chipset SiS 671MX
  • 4 Go de DDR2 à 667Mhz
  • 2 disques dur SATA de 250 Go, 5400 t/min
  • GeForce 9300M GS
  • Controleur ethernet SiS191
  • Carte Wi-Fi AR5B91 (chipset Atheros AR928X) mini PCI-E

Je souhaitais au départ installer Ubuntu car elle a une joli interface qui aurait été facile d’usage pour un néophyte, mais il était impossible de démarrer l’installateur, l’écran restait noir après le passage de Grub (22.04 ou 23.04 même combat). J’ai donc décidé de me rabattre sur une Debian Bullseye (la version stable à l’heure où j’écris ces lignes). Cette fois-ci, l’installation se passe correctement. Je redémarre, passe Grub, je vois les premières lignes de logs du noyau, et ensuite plus rien, écran noir. C’est là que les problèmes commencent.

Dans les sections qui suivent, je vais détailler la méthode que j’ai utilisé pour isoler les problèmes, et les solutions que j’ai trouvé. Dans la suite de cet article je vais partir. du principe qu’une distribution (Debian) est installée et qu’elle ne démarre pas.

Ça démarre pas, je fais quoi ?

La première étape c’est d’arriver à cerner à quel moment le boot est bloqué. Dans mon cas, Grub s’affiche, je peux lancer Debian, il me dit :

Loading Linux 5.10.0-23-amd64 ...
Loading initial ramdisk ...

puis l’écran devient noir avec qui un curseur clignote en haut à gauche de l’écran. Plus tard un changement semble se produire sur l’écran, puis plus rien, tout reste noir. C’est donc à un moment, après le démarrage de Linux, que quelque chose coince.

Dans ce cas, la première étape c’est de désactiver un maximum de périphériques dans le BIOS. Sur ce modèle il faut redémarrer, aller dans le BIOS avec F2, puis Advanced et I/O interface security. On peut alors désactiver un maximum de périphériques en les passant de UNLOCKED à LOCKED. Ensuite on enregistre avec F10 et on redémarre.

Ensuite, il faut modifier (temporairement) la ligne de commande du noyau passée par Grub, de manière à laisser le noyau afficher des traces à l’écran, on saura alors ce qui se passe. Pour ça, au moment où Grub s’affiche et propose des options, il faut presser Control+X pour obtenir l’éditeur et retirer le paramètre quiet de la ligne :

linux	/boot/vmlinuz-5.10.0-23-amd64 root=UUID=[...] ro quiet

Ensuite Linux démarre, affiche des traces dans la console. Puis au moment de passer la console en mode frame buffer (console de haute résolution), l’image disparait de nouveau, et j’ai un écran noir. Il y a donc sans doute un problème avec la carte graphique ou son driver nouveau.

GeForce 9300M et Nouveau

Pour en avoir le coeur net, je redémarre, j’édite de nouveau la ligne de commande du noyau pour retirer quiet et j’ajoute nouveau.modeset=0 pour désactiver le remplacement de la console :

linux	/boot/vmlinuz-5.10.0-23-amd64 root=UUID=[...] ro quiet nouveau.modeset=0

Je redémarre et … miracle, j’obtiens une invite de login et je peux me connecter en tant qu’utilisateur root. Je décide de démarrer le serveur d’affichage (serveur X) pour voir ce qui se passe et dans le logs je trouve :

(EE) NVIDIA(GPU-0): The NVIDIA kernel module does not appear to be receiving
(EE) NVIDIA(GPU-0):     interrupts generated by the NVIDIA GPU at PCI:1:0:0. 
(EE) NVIDIA(GPU-0):     Please see Chapter 8: Common Problems in the README for additional information.

Le driver ne reçoit pas les interruptions ? En regardant la liste des options du driver nouveau j’ai remarqué un paramètres NvMSI :

NvMSI: Use MSI interrupts, on by default on the chipsets that support it

C’est exactement ce qu’il nous faut. En effet Un périphérique PCI-E n’est pas obligé d’utiliser les interruptions matériels (reliées directement au contrôleur d’interruptions du processeur) mais peut envoyer un message à travers le bus PCI-E pour faire générer un interruption par le contrôleur de bus. C’est ce qu’on appelle les Message Signaled Interrupts ou MSI. Or cette fonctionnalité n’a pas été introduite immédiatement dans PCI-Express, l’ordinateur étant un peu âgé, il se peut qu’il ne les supporte pas.

On peut donc modifier de nouveau ligne de commande du noyau depuis Grub pour voir si ça fonctionne :

linux	/boot/vmlinuz-5.10.0-23-amd64 root=UUID=[...] ro quiet nouveau.config=NvMSI=0

Un petit reboot et hop ça fonctionne, le gestionnaire de login graphique s’affiche ! Il suffit maintenant de rendre cette option permanente. Pour ça j’ai ajouté le paramètre à la configuration de Grub :

# vim /etc/default/grub
[...]
GRUB_DEFAULT=0
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet"
GRUB_CMDLINE_LINUX="nouveau.config=NvMSI=0"
[...]

puis mise à jour de Grub :

# /sbin/update-grub
Generating grub configuration file ...
Found background image: /usr/share/images/desktop-base/desktop-grub.png
Found linux image: /boot/vmlinuz-5.10.0-23-amd64
Found initrd image: /boot/initrd.img-5.10.0-23-amd64
Found linux image: /boot/vmlinuz-5.10.0-21-amd64
Found initrd image: /boot/initrd.img-5.10.0-21-amd64
Warning: os-prober will be executed to detect other bootable partitions.
Its output will be used to detect bootable binaries on them and create new boot entries.
Found Windows Boot Manager on /dev/sda1@/efi/Microsoft/Boot/bootmgfw.efi
Adding boot menu entry for UEFI Firmware Settings ...
done

Après redémarrage tout va bien.

Un peu de réseau ?

Ethernet – SiS191

J’ai réactivé un par un les périphériques dans le BIOS et le problème suivant est apparu avec la carte ethernet SiS191. En effet, au bout d’un moment la connexion au réseau cesse de fonctionner, toutes les requêtes font des timeouts et le réseau devient inaccessible.

En cherchant des informations sur le support de ce chip dans Linux, j’ai découvert que ce chip a une taille maximum de MTU (Maximum Transmission Unit) de 1496 octets là ou Linux configure cette taille à 1500 octets par défaut. Ce qui fait que lorsqu’un paquet dépasse 1496 octets, la fin du paquet est tronquée, et le paquet envoyé sur le réseau est invalide. Le problème est documenté dans un bug sur le bug tracker du noyau Linux On peut vérifier le MTU défini pour une interface avec la commande :

# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 00:e8:4c:68:44:71 brd ff:ff:ff:ff:ff:ff
3: wlp2s0: <BROADCAST,ALLMULTI,PROMISC,NOTRAILERS,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 48:45:20:e1:0e:e7 brd ff:ff:ff:ff:ff:ff

Pour corriger le problème, il suffit de dire à NetworkManager (le gestionnaire de connexions) que toutes les connexions qui utilisent cette interface doivent définir un MTU à 1496. Pour cela on va créer un fichier de configuration :

# vim /etc/NetworkManager/conf.d/enp0s4-mtu.conf
[connection-enp0s4-mtu]
match-device=interface-name:enp0s4
ethernet.mtu=1496

Dans le fichier ci-dessus, n’oubliez pas de changer enp0s4 par le nom de votre interface ethernet. Puis on relance NetworkManager :

# systemctl restart NetworkManager

Wi-Fi

L’étape suivante c’est de ré-activer la carte Wi-Fi depuis le BIOS, et là c’est le drame. Lors du reboot, le système gèle pendant le démarrage, et impossible d’en sortir autrement que par un redémarrage à la dure.

La carte Wi-Fi installée dans le PC est une AR5B91 mini PCI-Express munie d’un chip Atheros qui est en théorie bien supportée par le driver ath9k. Le problème se situe donc sans doute ailleurs. Et en effet, la carte est elle aussi sur le bus PCI-Express, elle est donc soumise au même problème que la carte graphique : il faut désactiver le support des MSIs pour que cela fonctionne.

Il suffit de rajouter l’option pci=nomsi à la ligne de commande du noyau de la même manière qu’on l’a fait pour la carte graphique :

# vim /etc/default/grub
[...]
GRUB_DEFAULT=0
GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet" GRUB_CMDLINE_LINUX="nouveau.config=NvMSI=0 pci=nomsi"
[...]

# /sbin/update-grub
Generating grub configuration file ...
Found background image: /usr/share/images/desktop-base/desktop-grub.png
Found linux image: /boot/vmlinuz-5.10.0-23-amd64
Found initrd image: /boot/initrd.img-5.10.0-23-amd64
Found linux image: /boot/vmlinuz-5.10.0-21-amd64
Found initrd image: /boot/initrd.img-5.10.0-21-amd64
Warning: os-prober will be executed to detect other bootable partitions.
Its output will be used to detect bootable binaries on them and create new boot entries.
Found Windows Boot Manager on /dev/sda1@/efi/Microsoft/Boot/bootmgfw.efi
Adding boot menu entry for UEFI Firmware Settings ...
done

Un reboot, et le tour est joué !

Conclusion

Après cet ensemble de changements, le système fonctionne plutôt très bien. En revanche, on peut pas dire que l’installation soit aisée.

Références

Boot direct EFI sur Debian 10 (EFI stubs)

Contexte

Unified Extensible Firmware Interface (UEFI) est une spécification qui décrit une interface entre le firmware d’une carte mère et un système d’exploitation (OS). Il fait suite à l’Extensible Firmware Interface (EFI), originalement créée par Intel. Elle remplace progressivement le Basic Input Output System (BIOS) fourni à l’origine par les ordinateurs compatibles IBM PC.

Depuis quelques années, le fabricants de cartes mères fournissent des firmware compatibles à la fois avec UEFI et BIOS. Le noyau Linux, quant à lui, fourni les interfaces nécessaires pour être lancé directement par un firmware UEFI. Ce qui fait disparaître le besoin de boot loaders intermédiaires tel que GRUB.

Si vous n’avez pas besoin de ce fameux loader intermédiaire, parce que vous n’avez qu’un seul système d’exploitation par exemple, vous pouvez mettre en place le boot direct par UEFI. Dans ce qui va suivre, je vais décrire comment mettre en place cette configuration.

Configuration

Partition de boot EFI

La première étape à réaliser est de s’assurer que votre système est installé avec une partition de boot EFI lisible par votre firmware. Habituellement c’est une petite partition du disque située au début et formatée avec un système de fichier simple tel que FAT ou EXT2. Cette partition serra utilisée pour stocker le binaires compatibles avec EFI : soit votre GRUB ou le noyau Linux. Durant la phase de boot, l’UEFI va parcourir la partition à la recherche d’un binaire compatible. Voici un exemple du partitionnement sur ma machine :

# lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda           8:0    0 119.2G  0 disk
├─sda1        8:1    0   953M  0 part /boot/efi
└─sda2        8:2    0 118.3G  0 part /

Si vous n’avez pas ce genre de partition, vous devez en créer une, peut être en réinstallant votre système. Mais ceci est en dehors du cadre de cet article, vous pouvez trouver plus d’information à ce sujet ici.

Synchronisation des images

Pour pouvoir démarrer, l’UEFI doit pouvoir accéder à l’exécutable du noyau Linux et à l’image du ramdisk. Ce n’est possible que si ces deux éléments sont présents dans la partition que nous avons mentionné précédemment. Sur une distribution Debian, ces fichiers sont disponibles à la racine du système de fichiers ; nous aurons donc besoin d’un système pour les copier sur la partition EFI à chaque fois qu’ils sont mis à jour. Ainsi, après chaque mise à jour du système, le noyau et son ramdisk seront également mis à jour sur cette partition spéciale.

Sur le wiki de Debian EFI Stubs, la méthode proposée repose sur des scripts post installation pour le noyau et le ramdisk. Malheureusement, cela ne fonctionne plus sur la version Buster car le script post install pour initramfs (ramdisk) n’est plus disponible. Nous ferons donc cette mise à jour en utilisant les services systemd et ses déclencheurs basés sur la surveillance de fichiers. L’idée est de créer un service à exécution unique qui copiera le fichier. Néanmoins, au lieu de lancer le service au démarrage (ou autre évènement régulier), il sera déclenché par un changement sur le fichier que l’on surveille. En l’occurence le noyau et son ramdisk. Nous avons juste à le déclarer, et systemd fera le travail.

Le noyau

Allons-y : on commence par créer le service avec le fichier /etc/systemd/system/uefi-kernel-update.service :

# cat /etc/systemd/system/uefi-kernel-update.service
[Unit]
Description=UEFI Kernel update
After=network.target

[Service]
Type=oneshot
ExecStart=/bin/cp /vmlinuz /boot/efi/EFI/debian/

Ensuite on créé le déclencheur avec /etc/systemd/system/uefi-kernel-update.path :

# cat /etc/systemd/system/uefi-kernel-update.path
[Path]
PathChanged=/vmlinuz

[Install]
WantedBy=multi-user.target

Enfin on active le déclencheur :

# systemctl enable uefi-kernel-update.path
Created symlink /etc/systemd/system/multi-user.target.wants/uefi-kernel-update.path → /etc/systemd/system/uefi-kernel-update.path.
# systemctl start uefi-kernel-update.path

On peut tester que cela fonctionne correctement en faisant un  touch /vmlinuz et en vérifiant dans les logs de systemd que le service a été lancé :

# touch /vmlinuz
# journalctl -xn
Dec 14 18:14:18 fixe-damien systemd[1]: Starting UEFI Kernel update…
 -- Subject: A start job for unit uefi-kernel-update.service has begun execution
 -- Defined-By: systemd
 -- Support: https://www.debian.org/support
 -- A start job for unit uefi-kernel-update.service has begun execution.
 -- The job identifier is 2611.
 Dec 14 18:14:18 fixe-damien systemd[1]: uefi-kernel-update.service: Succeeded.
 -- Subject: Unit succeeded
 -- Defined-By: systemd
 -- Support: https://www.debian.org/support
 -- The unit uefi-kernel-update.service has successfully entered the 'dead' state.
 Dec 14 18:14:18 fixe-damien systemd[1]: Started UEFI Kernel update.
 -- Subject: A start job for unit uefi-kernel-update.service has finished successfully
 -- Defined-By: systemd
 -- Support: https://www.debian.org/support

Le ramdisk (initrd)

Répétons l’opération en créant un service et un déclencheur pour copier le fichier /initrd.img. Les fichiers sont fournis ci-dessous.

# cat /etc/systemd/system/uefi-initrd-update.service
[Unit]
Description=UEFI ignited update
After=network.target

[Service]
Type=oneshot
ExecStart=/bin/cp /initrd.img /boot/efi/EFI/debian/
# cat /etc/systemd/system/uefi-initrd-update.path
[Path]
PathChanged=/initrd.img

[Install]
WantedBy=multi-user.target

Enfin, on active le service et son déclencheur.

# systemctl enable uefi-initrd-update.path
Created symlink /etc/systemd/system/multi-user.target.wants/uefi-initrd-update.path → /etc/systemd/system/uefi-initrd-update.path.
# systemctl start uefi-initrd-update.path

N’oubliez pas de tester que cela fonctionne avec touch et journalctl.

Ajouter une entrée dans l’UEFI

Maintenant que nous sommes sur que le noyau et le ramdisk seront correctement mis à jour, il faut ajouter une entrée dans l’UEFI pour qu’il sache quel noyau lancer et comment.

Premièrement, il faut obtenir la ligne de commande du noyau (les paramètres qui lui sont passés) à partir de la configuration de GRUB. Dans le fichier /boot/grub/grub.cfg, cherchez le bloc menuentry ... { ... } qui correspond à l’entrée que GRUB utilise pour démarrer. Ensuite lisez ce bloc et cherchez la ligne linux /boot/vmlinuz..., elle nous indique les arguments passés au noyau au démarrage. Sur ma machine elle ressemble à ceci :

menuentry 'Debian GNU/Linux' ... {
  ...
  echo   'Loading Linux 4.19.0-6-amd64 ...'
  linux  /boot/vmlinuz-4.19.0-6-amd64 root=UUID=3c51b884-79b9-46f5-aff9-a2d8f68cd308 ro quiet
  echo   'Loading initial ramdisk ...'
  initrd /boot/initrd.img-4.19.0-6-amd64
}

Les arguments du noyau sont root=UUID=3c51b884-79b9-46f5-aff9-a2d8f68cd308 ro quiet. On peut maintenant utiliser efibootmgr pour ajouter une entrée dans l’UEFI, n’oubliez pas de mettre à jour la commande avec vos paramètres :

# efibootmgr -c -g -L "Debian (EFI stubs)" -l '\EFI\debian\vmlinuz' -u "root=UUID=3c51b884-79b9-46f5-aff9-a2d8f68cd308 ro quiet rootfstype=ext4 add_efi_memmap initrd=\\EFI\\debian\\initrd.img"

Si la commande échoue, vous aurez peut être besoin d’ajouter une option telle que : --disk /dev/nvme0n1.

Vous pouvez maintenant vérifier qu’elle a été ajoutée correctement :

# efibootmgr
 BootCurrent: 0008
 Timeout: 1 seconds
 BootOrder: 0008,0000,0009,0003,0001,0002,0004,0005
 Boot0000* debian
 Boot0001* Hard Drive
 Boot0002* UEFI:CD/DVD Drive
 Boot0003* CD/DVD Drive
 Boot0004* UEFI:Removable Device
 Boot0005* UEFI:Network Device
 Boot0008* Debian (EFI stubs)
 Boot0009* debian

La prochaine étape est le redémarrage ! Si tout s’est bien passé, votre machine devrait redémarrer et sauter le boot avec GRUB. Dans le cas où la configuration ne serait pas correcte, vous pourriez ne pas être capable de terminer le démarrage. Si cela arrive, vous pouvez toujours choisir manuellement l’entrée UEFI debian entry. Ainsi vous pourrez résoudre le problème.

Conclusion

Évidemment c’est essentiellement une réussite technique, car le temps passé dans GRUB lors du boot n’est pas excessif. Mais il était important pour moi de consigner cette procédure quelque part car j’utilise cette configuration tous les jours. J’espère qu’elle pourra servir à d’autres.

Par ailleurs, il y a des améliorations possibles. Par exemple, il serait pertinent de régénérer l’entrée dans l’UEFI lorsque la ligne de commande du noyau est mise à jour.

Sources