4 points par GN⁺ 2025-10-27 | Aucun commentaire pour le moment. | Partager sur WhatsApp
  • Explique étape par étape comment créer une « micro-distribution Linux » en compilant directement le noyau Linux et en construisant un espace utilisateur minimal
  • Présente depuis les bases le rôle du noyau du système d’exploitation, les composants d’une distribution Linux et la relation entre le noyau et l’espace utilisateur
  • Utilise l’architecture RISC-V (la machine riscv64 virt de QEMU) comme exemple, mais les mêmes principes s’appliquent aussi à d’autres architectures comme x86
  • Construit un environnement Linux minimal réellement exécutable, comprenant le processus init, l’initramfs et un shell simple écrit en Go
  • Présente enfin comment créer une micro-distribution réellement utile à l’aide du projet u-root, et se conclut comme un guide d’introduction aidant à comprendre l’ensemble de l’architecture d’un système Linux

Qu’est-ce que le noyau d’un système d’exploitation ?

  • Le noyau est le composant central du système d’exploitation chargé de gérer les ressources matérielles et de contrôler l’exécution des programmes
    • Même dans un environnement à cœur unique, il fournit une fonction de gestion du multitâche donnant l’impression que plusieurs programmes s’exécutent simultanément
  • Le noyau abstrait le contrôle des périphériques d’entrée/sortie afin que les applications n’aient pas à manipuler directement les adresses matérielles détaillées ou les valeurs des registres
    • Par exemple, un programme demande simplement d’« écrire un message sur la sortie standard », et le noyau se charge de l’interaction avec le matériel réel
  • Il fournit un interface de système de fichiers offrant un mode d’accès aux données de haut niveau
    • Un fichier n’est pas seulement une donnée sur disque, mais fonctionne comme une interface logique pour communiquer avec le noyau
  • Le noyau fournit un modèle d’isolation et de communication entre processus, permettant à chaque application de s’exécuter indépendamment ou de coopérer
  • Le noyau Linux est open source, peut fonctionner sur de nombreuses architectures et fait partie des noyaux les plus utilisés au monde

Qu’est-ce qu’une distribution Linux ?

  • Le noyau Linux seul ne permet pas à l’utilisateur d’exécuter un navigateur web ou des applications GUI ; il faut plusieurs couches d’infrastructure logicielle au-dessus du noyau
  • La configuration réseau, l’attribution d’IP ou la gestion d’un VPN relèvent non pas du noyau, mais de programmes de l’espace utilisateur situés à un niveau supérieur
  • Une distribution Linux se définit donc comme la combinaison du noyau et de l’infrastructure de l’espace utilisateur
  • Une distribution inclut, au-dessus des fonctions de base fournies par le noyau, des paquets, des outils, de la configuration et le processus d’initialisation (init)
  • Leur degré de complexité varie, depuis une configuration minimale comme Arch Linux jusqu’à une configuration conviviale comme Ubuntu

L’infrastructure hors noyau : l’espace utilisateur et le processus init

  • Une fois le démarrage terminé, le noyau lance d’abord le processus init portant le PID 1
    • init devient ensuite l’ancêtre de tous les processus de l’espace utilisateur et exécute successivement les services et outils du système
  • L’ensemble des processus et outils exécutés par init constitue la substance réelle d’une distribution Linux
  • Plus une distribution devient complexe, plus elle accumule des fonctions superflues et se voit parfois critiquée comme « bloated »
  • À l’inverse, en créant une micro-distribution personnalisée, on peut construire un système léger n’incluant que le strict minimum

Compiler un noyau Linux pour RISC-V

  • Depuis un environnement x86, compiler un noyau pour RISC-V à l’aide d’une chaîne d’outils de cross-compilation
    • Télécharger les sources linux-6.5.2.tar.xz depuis kernel.org, puis exécuter make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- defconfig
  • menuconfig permet de modifier visuellement la configuration du noyau
  • Après une compilation parallèle avec make -j16, le fichier arch/riscv/boot/Image est généré
  • Démarrer dans QEMU avec qemu-system-riscv64 -machine virt -kernel arch/riscv/boot/Image
    • Dans les logs de démarrage, on peut voir des messages indiquant la détection de la couche SBI, l’initialisation de l’UART et l’activation de printk

Premier obstacle : pas de système de fichiers racine

  • Pendant le démarrage du noyau, une panic du noyau se produit avec l’erreur VFS: Unable to mount root fs
    • Cause : aucun système de fichiers racine (initramfs) n’est fourni
  • Un système de fichiers peut être constitué non seulement sur disque, mais aussi en mémoire vive (initramfs)
  • L’initramfs est empaqueté au format cpio et peut être chargé dans QEMU avec l’option -initrd

Construire l’initramfs et exécuter « Hello world »

  • L’exigence minimale est la présence du binaire /init
    • Écrire init.c, puis le compiler en liaison statique (-static)
    • L’empaqueter avec cpio -o -H newc < file_list.txt > initramfs.cpio
  • Au lancement dans QEMU, « Hello world » s’affiche, puis l’arrêt de init provoque à nouveau une panic du noyau
    • Solution : ajouter une boucle infinie pour empêcher init de se terminer

Ajouter un shell simple écrit en Go

  • init exécute /little_shell via fork et execl
  • little_shell.go est un shell simple qui reçoit l’entrée utilisateur et réaffiche en écho les commandes
    • Compilation pour RISC-V avec GOOS=linux GOARCH=riscv64 go build little_shell.go
  • init et little_shell partagent tous deux la sortie via l’UART
    • L’entrée/sortie standard est gérée par des descripteurs de fichiers et héritée lors du fork
  • On obtient ainsi un environnement Linux de base où « Hello from init » et les entrées du shell s’affichent en alternance

Récapitulatif du rôle du noyau

  • Abstraction du matériel : les programmes utilisateur peuvent afficher du texte sans connaître les détails de l’UART ou des périphériques
  • Fourniture d’interfaces de haut niveau : accès à d’autres binaires (little_shell) via le système de fichiers
  • Isolation des processus : init et le shell s’exécutent dans des espaces mémoire indépendants
  • Le noyau fournit une base d’exécution stable et hautement portable au-dessus d’un matériel complexe

Définition d’un système d’exploitation

  • Certains considèrent que seul le noyau constitue le système d’exploitation, tandis que d’autres considèrent l’ensemble de la distribution comme le système d’exploitation
  • L’essentiel est de comprendre la frontière des rôles et la structure d’interaction entre le noyau et l’espace utilisateur

Créer une micro-distribution réellement utile avec u-root

  • Le projet u-root fournit un ensemble d’outils d’espace utilisateur basés sur Go
    • u-root inclut un chargeur d’amorçage en espace utilisateur et un environnement shell s’exécutant au-dessus du noyau Linux
  • Après l’installation, la commande GOOS=linux GOARCH=riscv64 u-root génère automatiquement l’initramfs
    • Le fichier /tmp/initramfs.linux_riscv64.cpio peut ensuite être exécuté dans QEMU
  • Au démarrage, une bannière « Welcome to u-root! » s’affiche avec une invite de shell par défaut
    • Prise en charge des commandes de base comme ls, pwd, echo, avec complétion par tabulation

Exercice de connexion réseau

  • Ajouter à QEMU les périphériques virtio-net-device et virtio-rng-pci
    • Utiliser les options -device virtio-net-device,netdev=usernet -netdev user,id=usernet
  • Avec dhclient de u-root, une IP est attribuée automatiquement via DHCP
    • Exemple : 10.0.2.15/24 attribué à eth0
  • Avec wget http://google.com, l’accès au réseau externe réussit, et le téléchargement de index.html est confirmé

L’importance du gestionnaire de paquets et de init

  • Les distributions classiques utilisent un gestionnaire de paquets pour installer et mettre à jour dynamiquement les logiciels
    • Cet exercice adopte une approche de type embarqué, où il faut reconstruire l’image complète
  • init n’est pas un simple lanceur de processus, mais un composant central de l’initialisation des périphériques, de la gestion des services et du contrôle du démarrage du système
    • Le code source de init dans u-root permet d’observer les différentes étapes de configuration des périphériques (/dev)

Dépôt GitHub

  • L’ensemble du code et des exemples de ce guide est disponible dans popovicu/linux-micro-distro
    • Il est possible d’y reconstruire l’image initramfs et de reproduire l’exercice

Aucun commentaire pour le moment.

Aucun commentaire pour le moment.