diff --git a/bac2/os/synthèse/process_diag.png b/bac2/os/synthèse/process_diag.png new file mode 100644 index 0000000..7424660 Binary files /dev/null and b/bac2/os/synthèse/process_diag.png differ diff --git a/bac2/os/synthèse/process_exe.png b/bac2/os/synthèse/process_exe.png new file mode 100644 index 0000000..d370cc3 Binary files /dev/null and b/bac2/os/synthèse/process_exe.png differ diff --git a/bac2/os/synthèse/prog_components.png b/bac2/os/synthèse/prog_components.png new file mode 100644 index 0000000..5bbe029 Binary files /dev/null and b/bac2/os/synthèse/prog_components.png differ diff --git a/bac2/os/synthèse/syllabus-umons-2022-12-22.pdf b/bac2/os/synthèse/syllabus-umons-2022-12-22.pdf new file mode 100644 index 0000000..a0aaafc Binary files /dev/null and b/bac2/os/synthèse/syllabus-umons-2022-12-22.pdf differ diff --git a/bac2/os/synthèse/syntheses.tex b/bac2/os/synthèse/syntheses.tex new file mode 100644 index 0000000..34a0cf4 --- /dev/null +++ b/bac2/os/synthèse/syntheses.tex @@ -0,0 +1,389 @@ +\documentclass{article} + +\usepackage[utf8]{inputenc} +\usepackage[T1]{fontenc} +\usepackage[french]{babel} +\usepackage{graphicx} +\usepackage{amsmath, amsfonts, amssymb, amsthm} + +\title{Synthèse Système d'éxploitation} +\author{Debucquoy Anthony} + +\begin{document} + +\maketitle +\tableofcontents +\newpage + +Ce document est une synthèse du cours de système d'exploitation. Il n'est pas complet et ne +peut pas se substituer à une lecture du document originale. Il permet toutefois de lister les +diffèrents points et d'y accompagner une brève explication. + +\section{Events} + +Un programme est composé: +\begin{itemize} + \item \textbf{Du code machine}: exécuté par la machine + \item \textbf{D'un espace de données}: Stock les données statiques et dynamiques + \item \textbf{D'une stack}: Stoque les variables locales et les appels +\end{itemize} +Ces composants se trouvent dans un "espace d'adresssage" commun et sont liés logiquements par le +biais d'appels (lw, j, ...) + +\begin{figure}[h] + \centering + \includegraphics[width=0.8\textwidth]{prog_components.png} + \caption{Composents d'un programme} +\end{figure} + +Lors de l'éxécution, les composents sont placés dans la mémoire afin d'y être accésible par le processeur. +L'entièretée d'un programme est alors définie par 4 éléments: + +\begin{enumerate} + \item La valeur des registres + \item le contenu de la stack (et le pointeur vers son sommet) + \item L'espaces de données utilisés + \item L'IP (instruction pointer) +\end{enumerate} + +Nous pouvons alors sauvegarder l'état (instantané) du programme. + + +\subsection{Gestion d'évènements} + +Nous distingons 2 types d'évènements traités par le processeur: +\begin{enumerate} + \item erreur / exceptions: ayant une origine \textbf{interne} au processeur + ex: division par zero, op-code invalide, right-fault, ... + \item evènement / interuptions: ayant une origine \textbf{externe} au processeur + ex: clavier, fichier pret, packet, clk, ... +\end{enumerate} + +Suite à ces évènements, le programme sera mis en pause pour pouvoir traiter l'évènement. Puis +le programme pourra (ou non) reprendre son cours. Dans le cas d'un évènement \textbf{récupérable}, +le programme continue. Dans l'un cas d'un évènement \textbf{irécupérable}, le programme s'arrète. +Pour que le programme puisse poursuivre, il faut sauvegarder son contexte. cette "snapshot" est +placée sur la stack. (cette stack peut basculer vers une autre pendant l'évènement pour éviter +de laisser la posibilitée au programme de récupérer des informations sur l'évent sans autorisation). +Cette sauvegarde sert à la fois pour les programmes récupérable pour la reprise/poursuite mais également +pour les programmes irécupérables, ces informations sont utiles au dévelopeur pour le debug de l'app. +Il est également nécéssaire de libèrer les resources aloués. + +\subsection{Reprise ou poursuite} +Lors que l'évènement à été pris en charge par le processeur, nous envisageons deux scénario. +\begin{enumerate} + \item \textbf{reprise}: retente l'éxécution du IP + \item \textbf{pouruite}: passe à l'instruction suivante +\end{enumerate} + +En générale, les intéruptions constituent tous des évènements récupérables avec poursuite. + +\subsection{Déroutement} + +Chaques architectures implémente sa propre méthode de déroutement. voici quelques examples: +\begin{itemize} + \item \textbf{Registre de cause}: C'est un registre mis à jours lors d'une exception ou d'une + intéruption. au terme du cycle d'éxécution, le processeur consulte ce registre pour savoir + si un déroutement est nécéssaire et dans ce cas vers quel adresse. + \item \textbf{Vectorisation}: chaques évent est un numéro dans une table de descripteur(IDT). Ce + descripteur est l'adresse de la fonction de gestion de l'évènement. +\end{itemize} + +\subsection{Niveau de privilège} + +Le jeu d'instruction du processeur contient des instructions "système" qui ne sont pas accésibles en +principe à tout les utilisateurs. Un programme typiquement fait appel à l'OS qui à son tours fait +les appels systèmes. on parle de ring 3/0 (0 étant le plus privilégié/OS) + +\subsection{Basculement de stack} + +Lors d'un déroutement, L'os utilise son propre stack. (après avoir sauvegardé le contexte du +programme) ainsi, le programme ne peu pas accéder a son contenu lors de la continuation. + +\subsection{Multiple évènements} +Lorsque plusieurs évènements surviennents, la prioritée est : Abandon > Reprise > Poursuite. +Il est également envisageable qu'un évènement survienne pendant la gestin d'un autre évènement. Dans +ce cas, étant donné que nous utilisons le stack pour le stockage du contexte du programme, il est +tout à fait envisageable d'utiliser ce même stack pour le stockage du contexte de la gestion du dit +évènement. Nous avons alors une imbrication des évènement à la manière de fonctions récursives. +Dans le cas ou nous authorisons plusierus évènements à dérouter en même temps, il peut être +nécéssaire d'implémenter un ordre de priorité. Pour ce faire une solution est d'utiliser un masque +d'interruption. Un évènement place alors les bits de sa prioritée. un évènement postèrieur est +déclencher ou non selon son propre masque de priorité. + +\section{Memoire} + +Nous avons vu qu'un programme étais composé de trois compostantes: le code machine, l'espace de +données et le stack. Ces composantes sont liées logiquement au sein du programme à l'aide d'adresse. +(branchements, ...). Deux problèmes se posent alors: + +\begin{enumerate} + \item \textbf{La concurence d'adresse}: Il est possible que les adresses choisies soient déjà + utilisées par un autre programme. Il est également important de vérifier quelles mémoires + sont accédées pour éviter qu'un programme accède à des donnes ne lui appartenant pas. + \item \textbf{Gestion de la mémoire disponible}: L'OS doit savoir quelle partie de la mémoire + est libre et quelle partie est utilisé. +\end{enumerate} + +Il nous faut résoudre ces problèmes de manière efficace et performante. car ces opérations sont les +plus utilisées + +\subsection{Projection et protection} + +\begin{itemize} + \item \textbf{Adressage absolu}: Cas de figure le plus directe. Les adresses du programmes sont + copiées précisément aux adresses de la mémoire choisies au moment de la compilation. + Le programme fonctionne alors parfaitement. Si certaine des adresses du programme ne sont + pas libres, Nous pourions comprometre l'intègritée du système. Il n'est également pas + possible de vérifier si le programme accède a des adresse qui ne sont pas autorisées. + \item \textbf{Adressage relatif}: Nous définissons un décalage (offset) au démarage du + programme. Cet offset sera appliqué à tout les adresse utilisées dans le programme. + \begin{itemize} + \item \textbf{static}: Modifie les adresse en y ajoutant l'offset (adresse de base) à la + volée lors de la mise en mémoire. Pour celà, l'éxécutable doit contenir une table + contenant les emplacement des adresse à modifier. Cette aproche n'empèche toujours + pas l'accés à des adresse hors mémoire. De plus, les adresse générées pendant le + déroulement du programme ne seront pas corigées + \item \textbf{dynamique}: L'ajout de l'offset se fait à chaques accés mémoires pendant + l'éxécution. nous stockong également la \textbf{limite} (la taille du programme) qui + permet de vérifier, lors d'un accès mémoire, si cette addresse est inférieur à + limite. si ça n'est pas le cas c'est que le programme tente de d'accèder à une + adresse ne lui appartenant pas. dans le cas contraire, l'adresse est additionée à + \textbf{base}. Un avantage de cette aproche est que le programme peut à tout moment + être déplacer dans la mémoire en métant à jour \textbf{base} et \textbf{limit}. A + contrario, chaques appel mémoire demande deux opérations (une comparaison et une + addition). ajout non négligable même si ces opérations font partie des plus rapides + du procésseur + \end{itemize} + \item \textbf{Segmentation}: Le programme est ségmenté dans la mémoire physique. chaques + ségments est encodé dans un \textbf{déscripteur de ségment} à l'aide de sa \textbf{base} et + \textbf{limit} (il est également possible de stocker le type, la permission, la direction, + la présence et un champ pour savoir si l'adresse a été modifiée ultérieurement). ces + déscripteurs sont stocké dans une \textbf{table de segments} en mémoire physique. Pour + gagner du temps cette table est stocké dans un registre de sélécteur de ségment. + Ces ségments sont crées à la compilation et la table de segments est liée au programme. + + Un avantage de la ségmentation est \textbf{le partage de segment}. En effet, il est possible + pour plusieurs programmes de partager un segment de mémoire physique commun (ex: librairies). + \item \textbf{Pagination}: Meilleure solution pour la souplesse dans la gestion de mémoire. Nous + considérons deux espaces. La pagination repose sur un découpage uniforme de ces deux espaces (e.g. 4Kib, 4Mib). + \begin{itemize} + \item \textbf{espace physique} : dont la taille dépend de l'architecture du processeur + (16/32/64 bits). Cet espace sera découpé en \textbf{pages} + \item \textbf{espace virtuel} : dont la taille dépend du controlleur et de la quantitée + de mémoire disponible. Cet espace sera découpé en \textbf{cadre} + \end{itemize} + Par conséquent, une page peut être contenue dans un cadre. Pour localiser l'endroit où une + page réside en mémoire physique, nous utilisons une \textbf{table des pages} (propre à + chaques programmes) \textbf{exhaustive} (contient une entrée pour chaques pages) et est + stockée dans la mémoire physique. L'MMU (\textit{Memory Management Unit}) s'occupe de la + traduction d'une page vers un cadre. La taille de la table des pages peut être trouvé par + \[\text{Taille} = \frac{\text{Espace virtuel}}{\text{Taille de page}} \times \text{Taille d'une + entrée}\] + Chaques entrées dans la table des pages contient un numéro de cadre qui identifie l'adresse + du cadre occupé par la page en question.(Nous y accompagnons un bit de présence, permission, + référencée, modifiée). + Un accés mémoire par le procésseur sépare l'adresse virtuelle en deux parties, suivant la + taille de découpage. Nous avons donc une portion qui encode le numéro de page (utilisé en + indice dans la table des pages) ainsi que l'offset qui sera apliqué une fois l'adresse + physique trouvée. L'utilisation du bit de présence est expliqué ci-dessous, il permet en + effet l'éxécution d'un programme quelque soit la quantité de mémoire physique disponible + pour le stocker. +\end{itemize} + +Les méthodes utilisant le \textbf{bit de présence} permetent l'éxistance partielle d'un programme en mémoire. +Dans le cas d'un appel vers une mémoire non présente, le processeur déclanche une \textbf{excéption} +de type défaut de page qui va recharger la partie concernée en mémoire physique. Si au moins un +cadre est disponible, il peut être pris. Si ça n'est pas le cas, un remplacmeent doit être +effectué \ref{sec:Eviction} Eviction de page +Il devra alors modifier les entrées base et limites en conséquence ainsi que mettre le bit de +présence à 1. + +\label{sec:Eviction} +L'éviction d'une entrée dans la table des pages prends en compte le bit \textbf{modifié}. Celà +permet d'éviter de perdre du temps d'écriture car si la page n'est pas modifiée, elle est encore +accècible. IL existe alors plusieurs stratégies d'évicitions: +\begin{itemize} + \item \textbf{Least Recently Used}: Eviction de la page la moins utilisée. nécéssite de + connaitre le temps depuis le dernier accès + \item \textbf{Not Recently Used} permet une simplification du LRU, un simple bit est tenu à + jours à la place du temps. + \item \textbf{First In First Out}: la page la plus ancienne est choisie. une structure de type + \textit{FIFO} peut être utilisée. Il est également possible d'implémenter la stratégie de la + \textbf{dernière change}. C'est à dire, d'implémenter l'utilisation du bit de référence + (régulièrement mis à jours par l'os) pour garder les pages régulièrement chargées. Il est + finalement possible d'implémenter une structure circulaire. +\end{itemize} + +la \textbf{Préemption} est le fait de libèrer de la mémoire d'un programme qui ne s'éxécute pas à +l'instant pour la donner à un autre programme en cours. + +\subsection{Gestion de la mémoire physique} + +Le système d'exploitation doit pouvoir, à tout moment, connaitre l'état d'occupation de la mémoire +physique. L'allocation de mémoire est alors plus dynamique. +\begin{itemize} + \item \textbf{Bitmap}: tableau de bits, la mémoire physique est découpée en unités d'allocation + de taille constante. on place les bits respectifs selon si l'espace est aloué ou non. + \[\text{Nombres d'unités} = \frac{\text{Mémoire physique}}{\text{Taille d'une unité}}\] + \[\text{Taille du bitmap} = \frac{\text{Nombres d'unités}}{8}\] + Nous pouvons alors trouver le bit corespondant à une unitée en divisant l'adresse par la + taille d'une unitée. Il suffit alors à l'os de trouver des suites de bits consécutifs libre + pour alouer de la mémoire en conséquence. + \item \textbf{Liste chainée}: chaques noed est une plage d'adresse particulière. un champ + contient: + \begin{itemize} + \item état: libre ou aloué + \item base + \item longeur + \item suivant + \end{itemize} + Nous avons finalement une chaine d'état alternant entre libre et aloué. lorsqu'un programme + souhaite alouer une plage, il parcours la liste afin de trouver une plage libre dont la + taille est supérieur à celle demandée. et de crée une maille de la chaine avec l'état + aloué. lorsque nous avons deux états consécutifs, nous pouvons les fusioner en gardant + l'adresse du premier mayon et en sommant les longeurs. + +\end{itemize} + +\section{Processus} + +Un processus représente la mise en activité d'un programme qui réside en mémoire. (complétement ou +partiellement). Ce processus va occuper un processeur en utilisant le context de sa stack lorsque +son code sera en cours d'éxécution. Ces processus auront la capacitée de faire des appels systems +(syscall) qui seront transmis à l'OS pour exécution. Il est donc nécéssaire d'alterner entre +l'éxécution du processus et celui de l'os (notament pour les évènements/syscall). + +\begin{figure}[h] + \center + \includegraphics[width=0.8\textwidth]{process_exe.png} + \caption{Temps d'éxécution d'un processus} +\end{figure} + +Le temps d'éxécution du programme augmente donc. Il est même souvent nécéssaire de partager le +processeur avec d'autre programmes en cours d'éxécution. (\textit{interleaving}) + +Tout les processus sont stockés dans la \textbf{table des processus} attaché à leurs état. Cet état +peut être: \textbf{éxécution, pret, bloqué, zombie} et chaques processus contient un context +nécéssaire à son fonctionnement. Il est également nécéssaire de sauvegarder l'état de la mémoire. +(avec sa table des segments ou la table des pages). Finalement nous devons garder les divers +descripteurs de resources (fichiers ouvers, ... et leurs status, décalage dans le fichiers, ...) + +L'\textbf{état} est un élément éssentiel pour le processus. Celui-ci est constament dans l'un des +états décrits ci-dessous. Celà permet de savoir comment le processus est censé se comporter à un +instant t. + +\begin{itemize} + \item \textbf{éxécution}: Le processus suis son éxécution courante. peut être utilisateur, où + les instructions du programme s'enchainent et passe en éxécution système lors d'un + évènement. Une fois cet évènement traité, le système redonne la main à l'utilisateur qui + peut continuer l'éxécution du programme. Il est également possible que l'évènement soit + irrécupérable. dans ce cas, le programme se termine est passe à l'état \textbf{zombie} + \item \textbf{prêt}: le processus est pret à etre éxécuté mais le processeur est actuellement + occupé. une fois celui-ci libéré, il choisit (en fonction de méthodes discutés plus tard) un + processus à l'état prêt et commence son éxécution. + \item \textbf{bloqué}: Le processus ne peux pas continuer car il n'a pas les resources + nécéssaire. Il peut par example attendre un signal réseau, une touche clavier, ... une fois + cet élément reçu, le processus passe à l'état \textbf{prèt}. Le tout se fait pendant + l'éxécution d'un évènement. ce qui implique que le procéssus en cours donne la main au + système. + \item \textbf{Zombie}: Un processus à l'état zombie ne peux plus rien faire. Il donne son état à + son processus parent qui peut, une fois cet état reçu, terminer le processus. +\end{itemize} + +Un procéssus peut créer à son tours d'autre processus (parents/enfants) Le système fonctionne alors +sous forme d'arborescence de processus, tous défini par leurs entrée dans la table des processus. + +\begin{figure}[h] + \centering + \includegraphics[width=0.8\textwidth]{process_diag.png} + \caption{cycles de vie des processus} +\end{figure} + +Suite à cet agencement, il est nécéssaire de trouver des méthode d'ordonnancement. Ces méthodes +doivent s'assurer la bonne répartition du temps processeur qui sont pret. Nous en étudierons sous 3 +type des systèmes différents. + +Un point important à éviter est la \textbf{famine}. c'est à dire qu'une tache resterait à pret sans +jammais se voir éxécuter. + + +\subsection{systèmes batch} + +éxécute des taches de manière régulière. chaques tache est simples mais effectuée sur une quantitée +importante de données. Les taches sont garantie de terminer et il est possible d'estimer le temps +d'une tache donnée. +Il faut alors une équité dans les resources distribuées. + +Nous regardons deux unitées. le \textit{Throughput}: nombre de taches par unité de temps, à +maximiser; le \textit{Turnaround}: temps moyen entre création et terminaison, à minimiser. + +\begin{itemize} + \item \textbf{First come first served (FCFS)}: Par ordre d'arrivé à l'état pret. Peut + s'implémenter à l'aide d'une file. cette méthode est équitable et évite la famine car toutes + les taches finirons par s'éxécuter. Mais ne garantis pas une utilisation optimale des + \item \textbf{Shortest job first (SJF)}: Nous pouvons éstimer la durée des tache (car batch) + donc nous pouvons priorisé les taches courtes. Cette stratégie minimise le turnaround mais + n'est pas équitable vis à vis des tache longues. nous avons un risque de famines. + \item \textbf{Shortest Remaining Task First (SRTF)}: Nous gardons le temps restant d'éxécution + de chaques processus. l'ordre d'éxécution suis alors cette liste. +\end{itemize} + +\subsection{Systèmes intéractifs} + +Centré autours de l'utilisateur et l'intéraction. Nous voulons une équité entre les utilisateurs et +les resources utilisées. Nous utilisons les métriques suivantes: \textit{latence}: le temps qui +s'écoule entre une action de l'utilisateur et la réaction du système, \textit{Proportionalité} +en adéquation avec les attentes de l'utilisateur. + +\begin{itemize} + \item \textbf{Round-Robin}: Le temps CPU est divisé en \textit{quantum} de temps de durée fixe. + Ces quantums sont distribués aux processus prets. Nous pouvons l'implémenter à l'aide d'une + liste cylindrique. l'Os configure un timer pour générer une intérruption à la fin du quantum + de temps pour passer à l'éxécution suivante. Cette stratégie garantit une répartition + équitable du CPU entre les procéssus. Il ne faut pas que le quantum soit trop bas car au + final il y aurais plus de temps nécéssaire à la commutation qu'à l'éxécution des processus. + \item \textbf{Priority Schéduling}: Mise en place d'un niveau de priorité par processus. + \item \textbf{Guaranteed Scheduling}: A pour but une répartition du nombre de processs face à un + délai garanti. + \[\text{Délai garanti} = \frac{\text{Temps depuis sa création}}{\text{Nombre de processus}}\] + L'ordonnanceur réalise un suivi du temps d'éxécution par chaque processus. + \[\rho = \frac{\text{Temps reçu}}{\text{Délai garanti}}\] + L'ordonnancement se base alors sur la valeur minimale. + \item \textbf{Fair-share scheduling} : Deux niveau de round robin, un pour les utilisateurs et + un par processus d'un utilisateur. Celà permet une répartition équitable du temps CPU par + utilisateur. +\end{itemize} + +\subsection{Systèmes temps réel} + +Système nécéssitant un controle du temps (réel) critique. Il se doit de réagir dans un temps +déterminé. (example système de défense anti-missile scannant continuellement son périmètre.) +Dans ces système. chaques évènements est précisément calibré pour être traités dans un temps +impartis avec échéances strictes. Ce système est ordonnancable uniquement si +\[\sum_{i=1}^m \frac{C_i}{P_i} \leq 1\] +avec $P$ intervalle entre deux occurence d'évènements et $C$ Temps nécéssaire au traitement. + +\vspace{1cm}Un thread (processus léger) permet un découpage des traitement qui, au sein d'un processus, peuvent +être effectué de mainère indépendante les uns des autres (\textbf{multi-threading} ) +Le coup de la gestion d'un thread est moindre que celui d'un processus. car celui-ci prends toutes +les resources déjà alouées de son thread principal. Il suffit juste d'effectuer une allocation de +mémoire pour héberger le stack du thread engendré. La continuation est nest rendu également plus +simple. +L'implémentation d'un thread peut se faire à deux niveaux. +\begin{itemize} + \item \textbf{User-level}: l'os n'a pas conscience des threads, c'est à l'application de gérer + son ordonencement. Mais n'est pas très évicace faces aux évènements car un blocage + (ouverture de fichiers, ...) bloquera tout les autres threads + \item \textbf{Kernel-level}: la stratègie d'ordonencement apliqués aux processus est appliqué + aux threads. Le blocage n'a donc pas de conséquence sur les autres threads du même + processus. +\end{itemize} + +\section{Concurence} + +\section{Systèmes de fichiers} + +\section{Entrées-sorties} + +\end{document}