Pour ce qui sont intéressé à coder un système d'exploitation robuste et open source, qui a été démontré, son intérêt. On va étudier un peu Linux et les problèmes qu'à résolu Linus Torvalds. On peut trouver le code source de la version 0.01 sur internet, à cette addresse: https://github.com/zavg/linux-0.01
C'est généralement très didactique que d'étudier le code source et l'implémentation. Surtout si vous voulez coder un système d'exploitation de A à Z. Il y a des normes... Et méthodes, on retrouve souvent des concepts. Après vous pouvez adapter et vous amusez à coder dans un autre langage tel que le Narkanta.
Donc Linux? C'est quoi?
La première version de Linux, publiée par Linus Torvalds le 17 septembre 1991, portait le numéro de version 0.01. Cette version était très rudimentaire par rapport aux versions modernes (10 239 lignes de code), mais elle posait les fondations d’un système d’exploitation de type Unix libre et ouvert. Voici des détails sur son implémentation initiale, les fichiers principaux et l'architecture qu'il avait adoptée.
Architecture de la première version de Linux (v0.01)
-
Noyau monolithique : Le noyau de Linux 0.01 était un noyau monolithique. Cela signifie que toutes les fonctions principales du système, telles que la gestion des processus, de la mémoire, et des périphériques, étaient intégrées directement dans le noyau lui-même. Contrairement aux noyaux micro-kernel (comme Mach), Linux exécutait la plupart de ses services de manière centralisée, ce qui permettait une exécution plus rapide, mais rendait le développement plus complexe.
-
Gestion de la mémoire : La première version supportait un modèle de mémoire virtuelle rudimentaire. Le noyau utilisait le mécanisme de segmentation et de pagination offert par le processeur Intel 80386. Cela permettait d'isoler les espaces d'adressage des processus, ce qui garantissait une certaine sécurité et stabilité.
-
Modèle de processus : Linux 0.01 offrait la gestion de processus via des processus légers (un modèle proche des threads modernes), permettant aux programmes de s'exécuter de manière concurrente. Cette gestion comprenait des fonctions comme la création de processus via
fork
, l'ordonnancement simple des processus, et un modèle de priorité rudimentaire. -
Appels système : Linus a implémenté des appels système de base pour permettre aux processus d'interagir avec le noyau. Cela incluait des appels pour les opérations sur les fichiers (comme
read
,write
,open
,close
), la gestion des processus (fork
,exec
,exit
), et la gestion de la mémoire (mmap
,brk
). -
Gestion des périphériques : Linus a écrit des pilotes de périphériques pour des dispositifs de base comme le clavier et la console texte (affichage à l'écran), ainsi que les disques durs. Ces pilotes étaient directement intégrés dans le noyau.
Fichiers de la version 0.01
Le code source de la version 0.01 de Linux était distribué sous forme d'un fichier tar compressé, comprenant une structure de fichiers similaire à celle utilisée dans les systèmes Unix classiques. Voici quelques fichiers et répertoires clés de cette première version :
/boot
: Contenait le code de démarrage (bootloader) qui initialisait le noyau à partir du disque dur ou de la disquette./kernel
: Le cœur de la gestion des processus, de la mémoire et des interruptions. On y trouvait des fichiers comme :sched.c
: L’ordonnanceur, responsable de la gestion du passage de la tâche entre les processus.sys.c
: Définition des appels systèmes, leur implémentation et leur interface.fork.c
: Gère la création de processus via le mécanisme defork
.exit.c
: Définit la gestion de la terminaison de processus.
/mm
: Code pour la gestion de la mémoire :paging.c
: Implémentation du mécanisme de pagination.memory.c
: Allocation et libération de mémoire.
/fs
: Système de fichiers, qui permettait de lire et écrire sur les disques. Les fichiers notables incluent :buffer.c
: Gestion des tampons (buffers) pour les lectures/écritures sur disque.file_table.c
: Gère la table des fichiers ouverts.super.c
: Gère les superblocs, une structure de gestion pour les systèmes de fichiers Unix.
/drivers
: Pilotes pour différents périphériques (clavier, écran, disques durs). Par exemple :char
: Contenait les pilotes pour les périphériques de caractère (comme le clavier).block
: Contenait les pilotes pour les périphériques de bloc (comme les disques).
/include
: Contenait les en-têtes (.h
) pour les définitions communes, les structures de données, et les interfaces du noyau.
Fonctions principales dans le noyau
Certaines fonctions clés qui ont constitué la base de Linux 0.01 incluent :
init()
: Fonction principale qui initialisait le noyau, configurait les pilotes, et lançait le premier processus utilisateur (init
).schedule()
: La fonction d'ordonnancement qui gérait le passage entre les processus. C’était un élément essentiel pour le multitâche.sys_fork()
: Permettait de dupliquer un processus, une des pierres angulaires des systèmes Unix.sys_exec()
: Chargement et exécution d'un programme à partir d'un fichier exécutable.sys_read()
etsys_write()
: Gestion de la lecture et de l’écriture sur les fichiers et les périphériques.
Environnement de développement et compilateur
Linus a écrit Linux en C et en assembleur, en utilisant le compilateur GCC (GNU Compiler Collection), qui était déjà un outil clé pour les développeurs de l’époque. L'utilisation de GCC a permis à Linux de profiter de la portabilité de C tout en utilisant les optimisations spécifiques aux processeurs x86 à travers l'assembleur pour les opérations critiques.
Les limitations de Linux 0.01
- Pas de support réseau : La première version de Linux ne supportait pas les réseaux, ce qui est apparu plus tard dans les versions ultérieures.
- Systèmes de fichiers limités : Linux 0.01 supportait principalement le système de fichiers de Minix. Le support des systèmes de fichiers plus complexes, comme EXT, est venu plus tard.
- Plateforme unique : La version 0.01 était spécifiquement conçue pour les processeurs Intel 80386. Le support pour d'autres architectures matérielles (comme SPARC, ARM) est arrivé bien plus tard.
- Absence de modules : Le noyau monolithique ne supportait pas encore le chargement dynamique de modules, ce qui signifiait que tout devait être compilé dans le noyau à l'avance.
La version 0.01 de Linux, publiée par Linus Torvalds en septembre 1991, comportait environ 10 239 lignes de code. Ce chiffre inclut à la fois le code en C et en assembleur nécessaire au fonctionnement du noyau, ainsi que le code des pilotes et de la gestion des processus, de la mémoire et du système de fichiers.
Voici une estimation de la répartition des lignes de code dans cette version :
- Code en C : environ 8 000 lignes. La majorité de la gestion du noyau et des systèmes de fichiers était écrite en C, ce qui permettait une certaine portabilité et une gestion des abstractions plus simple.
- Code en assembleur : environ 2 000 lignes. L'assembleur était utilisé pour les parties critiques de bas niveau, telles que l'initialisation du système, la gestion des interruptions matérielles, et les opérations spécifiques au processeur x86 (Intel 80386).
Ce nombre de lignes de code est minime par rapport aux versions modernes de Linux, qui comptent des millions de lignes. Cependant, il montre bien le caractère simple et minimaliste des débuts du noyau Linux, ce qui le rendait adapté aux ressources limitées des PC de l'époque tout en offrant une base solide pour le développement et l'extension future.