1. Roles du système d'exploitation
Le système d'exploitation fait l'interface entre la machine, en particulier avec l'unité centrale (CPU).
Il donne des moyens à l'utilisateur de :
-
gérer les périphériques en fournissant une interface "haut niveau" pour les périphériques
-
lecture / écriture avec une interface commune (read / write)
-
fichiers
-
-
gérer les ressources
-
charger un programme (suite d'instructions) dans la mémoire pour lancer l'execution
-
chargement
-
liberer la mémoire lorsque le programme est terminé / planté
-
gérer l'execution de plusieurs programmes ("multiprogrammation", "parallèlisme")
-
-
assurer la sécurité pour les utilisateurs
-
vérifier les droits d'accès
-
répartir les ressources (système multi-utilisateur)
-
La partie principale du système d'exploitation est le noyau : il s'agit de la couche logiciel qui implante l'interface entre les applications (programmes "haut niveau") et le matériel.
Les applications accèdent aux matériel à travers le noyau en utilisant des appels systèmes. Voici quelques exemples d'appels systèmes :
-
lire des octets dans un fichier
-
afficher un message à l'écran
-
executer un programme
-
stopper (de force) un programme
Les appels systèmes sont disponibles à travers des bibliothèques pour les langages de programmation (libc, etc.) ou en passant par le l'invite de commande.
1.1. Les acteurs
Les principaux systèmes d'exploitation actuels sont
-
Windows et dérivés, essentiellement sur les ordinateurs personnels (90% des ordinateurs???)
-
dérivés de Unix (Linux, BSD, Android), essentiellement sur les serveurs (plus de 90% des serveurs) et les tablettes / portables (entre 80% et 90%)
-
MacOS et dérivés (IOS), essentiellement sur les ordinateurs personnels (10%) et tablettes ou portables (10%)
Vocabulaire
-
noyau : c'est la partie principale du système d'exploitation, qui gère l'allocation des resources et les "appels systèmes"
-
système d'exploitation : noyau + utilitaires bas niveau (bibliothèques de programmation, commandes de bases) pour pouvoir utiliser l'ordinateur
-
distribution (essentiellement pour les systèmes Linux) : c'est un système d'exploitation avec un ecosystème de programmes utilisateurs (traitements de texte, navigateurs, etc.) qui rendent l'ordinateur utilisable par un utilisateur non informaticien
-
gestionnaire de fenêtres : logiciel qui offre une interface graphique pour lancer et utiliser les programmes
-
environnement de bureau : ensemble de logiciels intégrés avec un gestionnaire de fenêtres, avec un uniformité de présentation
-
gestionnaire de paquets (essentiellement pour les systèmes Linux) : programme qui permet de chercher / installer / desinstaller des logiciels facilement
Windows est un système d'exploitation avec un environnement de bureau.
MacOSX est un système d'exploitation avec un environnement de bureau.
Linux est un noyau.
GNU est un système d'exploitation (avec Linux comme noyau)
Ubuntu est une distribution (avec GNU comme système d'exploitation)
Gnome, KDE, XFCE, LXDE, ... sont des environnements de bureau
Norme POSIX
POSIX (Portable Operating System Interface) est une norme qui décrit les fonctionnalités de systèmes d'exploitation. En théorie les systèmes d'exploitation "compatibles POSIX" offrent tous une interface similaire avec l'ordinateur.
Cette interface décrit par exemple
-
la gestion des processus
-
la gestion des entrées / sorties
-
des bibliothèques standards de programmation (en C)
-
le shell (interpréteur de commandes)
-
des utilitaires du système
Les systèmes POSIX sont essentiellement
-
systèmes Unix commerciaux
-
systèmes Linux
-
systèmes BSD
-
macOS
-
Android
-
iOS
Une partie de la compatibilité POSIX est accessible sous Windows en installant une couche logicielle supplémentaire (Cygwin par exemple)
La compatibilité POSIX ne parle pas de la couche graphique, mais seulement de la partie système d'exploitation.
1.2. Intermède : invite de commandes
L'invite de commandes (aussi appelée "shell") permet de faire des appels systèmes sans passer par un langage de programmation "bas niveau". La plupart des appels systèmes sont appelés à travers des commandes. Ces commandes sont elle mêmes des programmes écrits dans un langage de programmation (typiquement le langage C).
Le shell par défaut sous la plupart des distributions Linux s'appelle "bash", mais il y en a plusieurs autres : "zsh", "sh", "tcsh", "ksh", "csh". Sous Windows, le shell s'appelle "powershell".
Savoir utiliser l'invite de commande est une étape clé : l'apprentissage est dur au début, mais les possibilités offertes sont à la hauteur de l'investissement. Là où la souris et les menus gesticulent pour faire passer de l'information, le shell offre un véritable langage pour communiquer avec le système.
Chaque processus (le shell y compris) a un répertoire de travail,
aussi appelé répertoire courant. La commande ls
par
exemple permet de récupérer la liste les fichiers / dossiers dans le
répertoire courant du shell et de l'afficher.
La commande cd
permet de changer le répertoire courant du
shell. (Comme cette commande n'agit sur rien à part le répertoire courant du
shell, il s'agit en fait d'une commande interne au shell qui ne correspond pas
à un programme externe.)
La plupart des commandes accessibles depuis le shell sont paramétrables en les invoquant avec des options. Par exemple :
-
ls
pour la liste brute des fichiers -
ls --color
pour la liste des fichiers, avec de la couleur, -
ls -X
pour trier les fichiers par extension, -
...
De nombreuses commandes ont une option -h
ou --help
pour afficher un petit message d'aide. Si ce n'est pas le cas, vous pouvez
utiliser la commande man CMD
pour obtenir le manuel d'utilisation
de la commande CMD
. Apprendre à lire ces pages de manuel est une
partie importante dans l'apprentissage des systèmes Unix.
Pour les commandes simples, l'interaction se fait :
-
par un affichage sur l'écran (
stdout
) :ls
par exemple, -
par la saisie au clavier (
stdin
) : le shell lui même par exemple,
L'interaction peut aussi se faire :
-
par des fichiers ouverts en lecture sur le disque :
grep
par exemple -
par des fichiers ouverts en écriture sur le disque :
wget
par exemple
L'invite de commande offre un moyen très simple pour remplacer les lectures
sur stdin
par des lectures dans un fichier, et pour remplacer les
écriture sur stdout
par des écritures dans un fichier.
$ CMD > NOM_FICHIER
$ CMD >> NOM_FICHIER
$ CMD < NOM_FICHIER
Error: no such file "%s -- %s" Error: no such file "" Error: no such file "shell"
De nombreuses commandes peuvent agir aussi bien sur des fichiers que sur
stdin
: par exemple, si on ne donne aucun nom de fichier à
grep
, alors la commande utilise automatiquement
stdin
.
Le shell offre également un moyen de "faire suivre" un flux de données : les
informations qui sortent sur stdout
d'une commande peuvent être
envoyées directement comme information d'entrée d'une autre commande :
$ CMD1 | CMD2 | CMD3
Error: no such file "%s -- %s" Error: no such file "" Error: no such file
"shell" Les informations données par CMD1
(stdout
)
sont envoyées à la commande CMD2
, et les informations obtenues
sont alors envoyées à la commande CMD3
.
Ceci permet de combiner plusieurs commandes simples pour effectuer des taches
complexes : on peut ainsi utiliser la commande find
(qui
recherche des fichiers par critères sur les méta informations : nom, taille,
etc.), la commande grep
(qui recherche les occurrences d'une
chaine dans un fichier) avec la commande rm
pour "supprimer les
fichiers html dont la taille est supérieures à 1Kio et qui contiennent la
chaine info202
."
1.3. Processus et ordonnancement
Un programme est une suite d'instruction dans l'ISA du processeur. Un programme est (en général) stocké dans une mémoire secondaire (disque, clé, réseau, ...)
Pour pouvoir l'exécuter, il faut :
1. le charger en mémoire et initialiser les registres nécessaires (en particulier le PC : program counter) 2. interpréter les instructions une par une (en particulier, incrémenter le PC) 3. gérer les resources (mémoire, périphériques, fichiers utilisés) 4. libérer la mémoire lorsque le programme est terminé.
On parle de processus pour le programme en execution (dans la RAM) avec toutes les informations annexes (registres, etc.)
Historiquement, le système d'exploitation executait un unique processus jusqu'au bout avant de passer au suivant. Cela posait des problèmes lorsque le processus en question plantait, ou ne terminait pas.
Les systèmes d'exploitation "récents" font de la multiprogrammation : plusieurs processus sont exécutés "en même temp". Ceci est possible, même lorsque l'ordinateur ne possède qu'un seul CPU. Mon ordinateur a actuellement 215 processus actifs !
Pour cela, chacun des processus ne s'exécute que pendant une durée très courte (quelques centièmes de secondes), puis les données nécessaires (registres, CP, etc.) sont sauvegardés dans la RAM, et un nouveau processus prend la place du premier (il faut pour cela récupérer les donnés nécessaire du nouveau processus...)
Le choix de l'ordre dans lequel exécuter les processus est important et dépend beaucoup du système d'exploitation. On parle d'algorithme d'ordonnancement. La partie du noyau qui gère ceci s'appelle l'ordonnanceur et doit se débrouiller pour :
-
les processus importants ne doivent pas attendre trop longtemps,
-
les processus temps réels (audio / vidéo, etc.) ne doivent pas attendre trop longtemps,
-
les processus intéractifs (gestion de la souris, du clavier, de l'affichage) ne doivent pas attendre trop longtemps
-
...
Le choix de priorités n'est pas facile, et une mauvaise conception amène des problèmes. On parle de famine lorsque des processus n'ont jamais accès au processeur.
Les systèmes d'exploitations utilisent un mélange de
-
priorités statiques : les processus temps réels / processus systèmes sont plus prioritaires
-
des priorités dynamiques : les processus interactifs deviennent plus prioritaire (ces priorités sont dynamiques car on ne peut pas savoir à l'avance si un processus est vraiment interactif)
-
différents modes de préemption : pour qu'un processus prioritaire puisse prendre la place d'un processus en execution
-
...
Il est important de noter qu'un processus actif (dans la mémoire) peut être en attente d'un évènement externe. L'ordonnanceur ne donne jamais le processeur à ce type de processus. C'est par exemple le cas des processus interactifs : l'appui sur une touche (et sa gestion bas niveau) est très lent par rapport au CPU. Un traitement de texte est donc bloqué la plupart du temps et n'occupe presque pas le processeur.
Remarque : chaque processus est identifié par un numéro unique appelé PID ("Process Identification"). Dans le monde Unix, les processus sont organisés en arbre : chaque processus est le "père" des processus qu'il a créé. (cf commandes "ps" et "pstree")
Sous Windows, tous les processus sont ou même niveau...