Une distribution Linux de Zero
Je pense comme beaucoup de gens, j’utilise linux au quotidien. Perso j’utilise NixOS. Mais finalement je ne sais pas vraiment comment ça fonctionne sous le capot.
Je suis tombé plusieurs fois sur des vidéos d’un américain Nir Lichtman, qui s’amuse à créer différentes distribution linux de zéro pour différents cas d’utilisation.
un exemple de vidéo
Le concept est vraiment cool et ça rend la chose très accessible donc merci à lui pour ces vidéos.
IMPORTANTLa distribution finale n’est pas destinée à être utilisée en production, mais juste à des fins éducatives.
Dans ce post je vais vous montrer ce que j’ai fait pour créer une distribution linux minimale from scratch.
Pré-requis techniques
Dans mon cas je vais faire cela sur un container docker ubuntu. Et pour lancer la vm j’utilise QEMU, que vous pouvez installer facilement.
Sur nixOS j’ai simplement lancé : nix-shell -p qemu
pour les autres distributions vous pouvez voir la doc officielle de QEMU. la documentation de docker. Et au passage la documentation officielle de Linux From Scratch qui est très bien faite.
Division
On aura besoin de trois briques pour faire fonctionner notre distribution:
kernel(le noyau linux)User Space(BusyBox)bootloader(Syslinux)
Le Noyau Linux
Comme je vous l’ai dit au début, je vais utiliser un container docker ubuntu pour faire tout ça. Donc ma première étape est de le lancer.
docker run —privileged -it ubuntu

On se retrouve dans le shell du container, la première étape est de faire les mises à jour et d’installer les dépendances nécessaires.
apt update && apt upgrade -y apt install bzip2 git vim make gcc libncurses-dev flex bison bc cpio libelf-dev libssl-dev -y

On a nos dépendances d’installées, on peut maintenant cloner le dépôt du noyau linux.
NOTEJe préfère le cloner dans le repertoire de l’utilisateur mais ça c’est comme vous préférez (/home/ubuntu).
git clone —depth 1 https://github.com/torvalds/linux.git
*—depth 1 - pour ne pas avoir tout l’historique git du noyau mais juste le dernier commit

Vu que l’on part sur une installation x86_64 on va configurer le noyau pour cette architecture. On utilise une configuration déjà faite par les développeurs du noyau.
make x86_64_defconfig

une fois fait on peut lancer la compilation du noyau, on peut soit utiliser make ou make -j N où N est le nombre de coeurs de votre processeur pour accélérer la compilation.
Moi je vais utiliser tout les coeurs disponibles pour aller plus vite.
make -j $(nproc)


Kernel: arch/x86/boot/bzImage is ready (#1)
Une fois la compilation terminée on peut voir l’image du noyau dans le répertoire arch/x86/boot/bzImage.
On crée un répertoire boot-files à la racine et on copie l’image du noyau dedans.
mkdir /boot-files mv arch/x86/boot/bzImage /boot-files
Fini pour le noyau, on passe à l’espace utilisateur.
Espace Utilisateur - BusyBox
La documentation officielle de BusyBox.
On retourne dans l’espace utilisateur /home/ubuntu et on clone le dépôt de busybox.
cd /home/ubuntu git clone —depth 1 https://git.busybox.net/busybox cd busybox
C’est le même principe que pour le noyau, on configure et on compile.
pour initialiser la configuration par défaut on utilise make defconfig.
make defconfig
Nous on veut la version de busybox en mode static pour que tout soit dans un seul binaire. Donc on modifie la configuration dans settings, il faut décocher la section Build static binary (no shared libs) pour cela il faut lancer la commande :
make menuconfig
Une fois dans le menu, on va dans Settings (entrée).

une fois décoché ce n’est pas fini car avec les versions récentes de ubuntu il faut désactiver tc, pour ce faire on va dans Networking Utilities et on décoche tc (8.3 kb) (ça peut être une autre valeur Xkb).

une fois fait un fait exit et on sauvegarde la configuration. On build ensuite busybox de la même façon que le noyau.
make -j $(nproc)

Dans le répertoire que nous avons créé précédemment /boot-files on crée un répertoire initramfs et on copie le binaire de busybox dedans (mkdir /boot-files/initramfs).
On installe busybox dans ce répertoire en utilisant la commande make install avec la variable CONFIG_PREFIX qui pointe vers le répertoire d’installation.
make CONFIG_PREFIX=/boot-files/initramfs install

Notre système n’a pas encore de shell, on va créer un script init qui sera le premier processus lancé par le noyau. Ce qui est drôle c’est que dans le fichier init c’est qu’on lui dit de s’utiliser lui-même comme shell.
NOTEil faut bien créer le fichier
initdans le répertoire/boot-files/initramfset lui donner les droits d’exécution avec la commandechmod +x init.
Avant on crée les dossiers important dans le répertoire initramfs.
mkdir /boot-files/initramfs/{proc,sys,dev}
#!/bin/sh
mount -t proc proc /procmount -t sysfs sysfs /sysmount -t devtmpfs devtmpfs /dev
echo "Bienvenue sur ma distribution"
exec /bin/shToujours dans le répertoire /boot-files/initramfs on crée une archive cpio compressée qui sera utilisée par le noyau au démarrage.
cd /boot-files/initramfs find . | cpio -o -H newc > ../init.cpio
C’est fini pour l’espace utilisateur, on passe au bootloader.
Bootloader - Syslinux
Ici on va utiliser Syslinux comme bootloader, la doc officielle est ici.
on l’installe car il n’est pas installé par défaut.
cd /boot-files # on revient dans le répertoire boot-files apt install syslinux -y
Donc une fois installé, on va créer un fichier de 50Mo qui servira de disque dur virtuel pour notre distribution.
dd if=/dev/zero of=boot bs=1M count=50

On a besoin de dosfstools pour formater le fichier en FAT32.
apt install dosfstools -y mkfs -t fat boot syslinux boot
Ici on monte le disque dur virtuel, on le formate et on installe syslinux dessus.
mkdir m mount boot m
On copie les fichiers nécessaires cp bzImage m cp init.cpio m
Voila on a maintenant un fichier boot qui contient notre distribution linux minimale. Le but est de la lancer sur une machine virtuelle.
Vu que l’on est sur un container docker il faut transférer le fichier boot sur l’hôte. Pour ce faire on utilise la commande docker cp.
Dans un autre terminal sur l’hôte.
docker cp <container_id>:/boot-files/boot .

Il faut maintenant lancer la machine virtuelle avec QEMU en utilisant le fichier boot comme disque dur.
qemu-system-x86_64 boot

Mais on a un souci, ça nous dit No configuration file found. Pas de problème on va lui donner manuellement le fichier de configuration que l’on a créé précédemment.
donc dans boot on écrit :
WARNINGLe clavier est en QWERTY
/bzImage -initrd=/init.cpio
On appuie sur entrée et ça y est on a notre distribution linux minimale.

NOTEOn voit bien notre message customisé “Bienvenue sur ma distribution”
Vous pouvez maintenant jouer avec votre distribution linux minimale. Vous pouvez taper des commandes comme ls, cd, pwd, etc.
Voilà dans les grandes lignes comment ça fonctionne, biensûr il existe d’autres bootloaders, d’autres espaces utilisateurs, et plein d’autres choses à ajouter pour rendre la distribution plus complète mais pour commencer c’est pas mal.
Merci à Nir Lichtman pour l’inspiration.
Merci de m’avoir lu ! Si vous avez des questions n’hésitez pas à me les poser sur X.