diff --git a/config.toml b/config.toml index 70c80c7..2bdb473 100644 --- a/config.toml +++ b/config.toml @@ -1,21 +1,29 @@ baseURL = "https://lpro.epha.se" languageCode = "fr" defaultContentLanguage = "fr" -title = "Licence pro ADSILLH - Cours et TD" +title = "Note de cours et TD" pygmentsCodeFences = true pygmentsUseClasses = false theme = "mainroad" rssLimit = 10 paginate = 10 -enableRobotsTXT = true +enableRobotsTXT = false + +[Author] # Used in authorbox + name = "ephase" + bio = "Adminstrateur système, j'ai d'abord intégré la Licence Pro ADSILLH et mainrenant le Master IDI à l'Université de Bodreaux" + avatar = "assets/images/souris.svg" + [taxonomies] - category = "categories" + category = "categories" tag = "tags" [Params] + description = "Licence ADSILLH et Master IDI, mes notes de cours et de TD" toc = true post_navigation = true - postSections = ["reseau", "progsys", "installations", "bdd", "securite"] + mainSections = ["reseau", "progsys", "installations", "bdd", "securite", "systemes_exploitation"] + post_meta = ["author", "date", "categories", "translations"] [Params.sidebar] home = "right" # Configure layout for home page diff --git a/content/assets/images/souris.svg b/content/assets/images/souris.svg new file mode 100644 index 0000000..ed26978 --- /dev/null +++ b/content/assets/images/souris.svg @@ -0,0 +1,340 @@ + + + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/content/systemes_exploitation/1-introduction/index.md b/content/systemes_exploitation/1-introduction/index.md new file mode 100644 index 0000000..a8d3f0a --- /dev/null +++ b/content/systemes_exploitation/1-introduction/index.md @@ -0,0 +1,100 @@ +--- +title: "Systèmes d'exploitation : Introduction" +date: 2021-09-10 +tags: ["système", "appels système", "interruption"] +categories: ["Systèmes d'exploitation", "Cours"] +--- + +## Qu'est ce que c'est? + +D'après +[Wikipedia](https://fr.wikipedia.org/wiki/Syst%C3%A8me_d%27exploitation), "un +système d'exploitation est est un ensemble de programmes qui dirige +l'utilisation des ressources d'un ordinateur par des logiciels applicatifs." + +Il permet l'abstraction matérielle *(via les pilotes de périphériques)*, la +gestion des processus *(et leur séparation, permettant à un processus défectueux +de ne pas impacter les autres)*, la gestion fine des ressources... + +Le systèmes d'exploitation prend en charge la gestion du processeur, de la +mémoire, des accès disques, de la pile réseau, les services et souvent aussi +l'interface graphique. Il peut-être *(rarement)* mono-utilisateur ou +multi-utilisateur. + +Il est donc important de ne pas confondre **Noyau** et système d'exploitation, +le premier étant une partie du second. + +## Les interruptions + +D'après [Wikipedia](https://fr.wikipedia.org/wiki/Interruption_(informatique)), +"une interruption est une suspension temporaire de l'exécution d'un programme +informatique par le microprocesseur afin d'exécuter un programme prioritaire +(appelé service d'interruption)." + + +Les interruptions peuvent être envoyées par les périphériques ou le CPU +lui-même. Lors de l'envoi d'une interruption, aucun message n'est envoyé, +seulement son numéro, le CPU fait alors un saut vers une routine définie par +**la table d'interruption**. Cette table est mise en place par le *noyau* en +RAM. Cette table contient une entrée par interruption. + +Il existe deux grand type +d'interruption: + + * Celle basées sur le matériel + * Celle basée sur le temps (horloge) + +La routine propre à l'interruption appellen ensuite une *iret* afin de reprendre +l'exécution précédente. + +sous certaines conditions, certaines interruptions sont "masquable" *(mais elle +ne peuvent pas être ignorées)*. + +### Le cas du timer + +C'est une interruption déclenchée à intervalle régulier, en général toutes les +10ms. Ainsi un processus ne peut pas monopoliser indéfiniment le CPU. Ainsi le +noyau peut stopper, voire tuer un processus trop gourmand. + +## Les privilèges + +Nous avons besoin de contrôler ce que font les processus, seult le noyau doit +être tout-puissant. Le contrôle des instructions autorisée ou non ne peut se +faire **qu'au niveau du matériel** et donc du CPU. + +Ainsi ce dernier disponse de deux modes de fonctionnement: + + * **protégé**: seul un nombre restreint d'instruction sont disponibles + * **réel** (ou noyau) toutes les instructions sont disponibles. + +Si une instruction privilégiée est exécutées par un processus, une exception +(sorte d'interruption) est lancée. + +Pour des questions de sécurité, un processus ne doit pas pouvoir exécuter des +instructions privilegiées. En effet le rôle du noyau ets aussi de faire +abstraction du matériel, lui seul y a accès. Cependant certains processus ont +besoin d'y accéder **un affichage** avec `printf` ou la **saisie d'un texte au +clavier** ou encore **créer un processus**. + +### Les appels systèmes + +Pour celà le noyau dispose d'un mécanisme : **les appels systèmes**. ainsi le +noyau contient des routines pouvant être utiles aux processus. Ces routines sont +appelés par des interruptions logicielles. Le processus positionne le numéro de +l'appel un registre (`%eax` sur les processeurs Intel) et lance l'interruption. + +Côté noyau, une table contenant la liste des appels systèmes est positionnée en +RAM. + +L'utilisation des appels systèmes est sécurisée : les processus ne joue pas avec +des adresse mémoires contenant des routines, mais ne connaissent seulement son +numéro. Les paramètres necessaires aux appels sont eux stockés sur la pile. + +### Dans les systèmes modernes. + +Ils sont nombreux : on en compte environ 330 dans Linux et plus de 500 dans +MacOSX. + +Sour Linux, certaines routines sont inclues dans la `libc` et ne sont donc pas +des appels système. Par exemple `printf` qui affiche des éléments à l'écran et +inclu dans la `libc` utilise l'appel système `write`. diff --git a/content/systemes_exploitation/2-processus/index.md b/content/systemes_exploitation/2-processus/index.md new file mode 100644 index 0000000..9b56f6e --- /dev/null +++ b/content/systemes_exploitation/2-processus/index.md @@ -0,0 +1,199 @@ +--- +title: "Systèmes d'exploitation : Les processus" +date: 2021-09-17 +tags: ["système", "appels système", "processus"] +categories: ["Systèmes d'exploitation", "Cours"] +--- + +Les processus sont des instances vivants de programmes. Un programme représente +du code binaire stocké sur un support de stockage. + +Un processus est un espace d'adressage en mémoire et d'un contexte d'exécution. +Plus d'information est disponible [dans les cours de prog. système]({{< ref +"../../progsys/3-processus/index.md">}} "Les processus") + +## Accès à la mémoire + +L'espace d'adressage contient des segments mémoire : + + * le *segment de texte* / de code: les instructions optimisées par le + compilateur, souvent en lecture seule dans les systèmes modernes. + * le *segment data* contenant lui même le segment des *données initialisées* et + le BSS (données non-initialisées) + * le *tas*, zone de mémoire dynamique gérée par la `libc` par l'utilisation de + `malloc()` et `free()`. Le système ne peut détecter un accès en dehors de + la plage définie par un `malloc()`. Lorsque le tas n'a plus d'espace alors + la `libc` effectue un appel système (mais le noyau peut refuser d'allouer) + * la *pile d'exécution*, sa taille est de 8MiB maximum sous Linux. Ce segment + contient les paramètres des fonctions et leurs variables locales. + * les *librairies partagées* mappees à la demande. + + +Il est possible de voir les espaces de mémoire alloués pour un processus donné : + +``` +cat /proc/self/maps +55fee9705000-55fee9707000 r--p 00000000 fe:01 1979024 /usr/bin/cat +55fee9707000-55fee970c000 r-xp 00002000 fe:01 1979024 /usr/bin/cat +55fee970c000-55fee970f000 r--p 00007000 fe:01 1979024 /usr/bin/cat +55fee970f000-55fee9710000 r--p 00009000 fe:01 1979024 /usr/bin/cat +55fee9710000-55fee9711000 rw-p 0000a000 fe:01 1979024 /usr/bin/cat +55feead5a000-55feead7b000 rw-p 00000000 00:00 0 [heap] +7fbcfa322000-7fbcfa344000 rw-p 00000000 00:00 0 +7fbcfa344000-7fbcfa62c000 r--p 00000000 fe:01 1987533 /usr/lib/locale/locale-archive +7fbcfa62c000-7fbcfa62e000 rw-p 00000000 00:00 0 +7fbcfa62e000-7fbcfa654000 r--p 00000000 fe:01 1969528 /usr/lib/libc-2.33.so +7fbcfa654000-7fbcfa79f000 r-xp 00026000 fe:01 1969528 /usr/lib/libc-2.33.so +7fbcfa79f000-7fbcfa7eb000 r--p 00171000 fe:01 1969528 /usr/lib/libc-2.33.so +7fbcfa7eb000-7fbcfa7ee000 r--p 001bc000 fe:01 1969528 /usr/lib/libc-2.33.so +7fbcfa7ee000-7fbcfa7f1000 rw-p 001bf000 fe:01 1969528 /usr/lib/libc-2.33.so +7fbcfa7f1000-7fbcfa7fc000 rw-p 00000000 00:00 0 +7fbcfa80f000-7fbcfa810000 r--p 00000000 fe:01 1969517 /usr/lib/ld-2.33.so +7fbcfa810000-7fbcfa834000 r-xp 00001000 fe:01 1969517 /usr/lib/ld-2.33.so +7fbcfa834000-7fbcfa83d000 r--p 00025000 fe:01 1969517 /usr/lib/ld-2.33.so +7fbcfa83d000-7fbcfa83f000 r--p 0002d000 fe:01 1969517 /usr/lib/ld-2.33.so +7fbcfa83f000-7fbcfa841000 rw-p 0002f000 fe:01 1969517 /usr/lib/ld-2.33.so +7ffccf574000-7ffccf595000 rw-p 00000000 00:00 0 [stack] +7ffccf5c8000-7ffccf5cc000 r--p 00000000 00:00 0 [vvar] +7ffccf5cc000-7ffccf5ce000 r-xp 00000000 00:00 0 [vdso] +ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall] +``` + +On y voit biens les adresses de début, ceux de fin, les droits (`r`ead, +`w`rite, e`x`ecute, `p`rivate) + +L'accès par un processus à un espace mémoire invalide donne lieu à la fameuse +`segmentation fault`. Mais il est tout à fait possible de lire et écrire vers +une zone non allouée du tas. Par exemple j'initialise un tableau de 10 éléments +et les rmpli avec une boule de 15 itérations. + +## Attributs d'un processus + +en plus de l'espace mémoire alloué pour le processus, le noyau stocke en mémoire +un ensemble d'attributs : son identitiants (`PID`), sa priorité, l'`UID` +(réel/effectif), la table des descripteurs de fichiers, la table des signaux, un +espace pour sauvegarder les registres (changement de contexte, reprise sur +interruption). + +## Création et vie des processus + +Un processus voulant en créer un autre doit faire un appel système `fork`. Lors +du changement de contexte, les registres du processus `p0` sont sauvegardés puis +remplacés par ceux de `p1`. + +Les signaux sont délivrés au processus lors du passage du noyau à l'exécution. + +### Processus bloquants + +Lorsqu'un processus attends un appel bloquant (par exemple `read()`) il est muse +en sommeil. Lorque l'interruption est lancée, alors le noyau réveille le +processus. + +## Ordonnancement + +L'ordonnancement essaye définir un **fonctionnement universel** visant à +organiser l'exécution concurente de processus sur un CPU. Un fonctionnement +universel, convenant donc à tous les usages, *est impossible à obtenir*. Il +dépend en effet de l'utilisation qui en est fait : interactif, temps-réel etc. + +Dans le cadre d'un système interactif, la réactivité est la caractéristique la +plus importante. + +### Stratégie + +Le type de système influe donc sur la stratégie à adopter. nous allons en +détailler certaines. + +#### FIFO - First In First Out + +Une liste chainée de processus, on exécute le premier jusquà la fin de son +exécution ou qu'il soit bloqué puis le second et ainsi de suite. + +C'est une technique facile à implémenter, il est très peu couteux en temps +processeur (le noyau intervient peu, peu de changement de contexte) mais +comporte un gand risque de **famine** : un processus en boucle ne rendrai jamais +la main. + +#### Round-Robin + +Un **temporisateur** valable pour tous: le changent de contexte intervient toute +les 10ms par exemple. C'est une technique facile à implementer, il y a plus de +famine mais on ne **gère pas de priorité**. S'il y a beaucoup de processus, +alors notre éditeut de texte sera moind réactif. + +#### Priorité stricte + +Les processus sont triés par priorité et les plus important son exécutés en +premier. contrairement au *Round-Robin* on gère la priorité mais ette technique +est discriminatoire. Comment **assigner les priorités**? Au faciès? + +#### Priorité dynamique + +La priorité change au cours de la vie du processus car il change de +comportement. + +Dans le cas d'une **opération de compilation** par exemple, le +compilateur lit les fichiers sources effectuant beaucoup de `read` et se +bloauqnt donc. Ensuite il compile et utilise beaucoup de CPU. + +L'ordonnanceur observe donc les métriques du passé pour prévoir l'avenir. Dans +l'example du compilateur, le noyau observe que sur les 10ms de temporisation, +notre processus **s'est bloqué (et change de contexte) au bout de 1ms**. Puis +losqu'il compile, notre compilateur va rester sur le CPU **pour toute sa +tempotisation**. + +Mais comment choisir la bonne priorité en fonction de ces métriques? Tout +simplement **en choisissant d'abord les processus les plus courts**. C'est la +stratégie utilisée en général dans les **système interactifs**. + +#### La stratégie utilisée dans le noyau Linux 2.4 + +Cette version du noyau Linux, la gestion de l'ordonnancement se fait par +l'attribution de crédits. Un processus utilisant l'UC le fait en dépensant des +crédits, plus il l'utilise plus il en dépense. + +Lorqu'un processus n'a plus de crédit, il ne peut plus utiliser l'UC jusqu'à ce +que le noyau en redistribue. Il le fait lorque aucun processus prêt n'a de +crédit. + +Les processus n'ayant pas dépensé tous ses crédits se voit prélever un +"impots": + +``` +Crédit = Cn + (Cn-1/2) + (Cn-2/4) + (Cn-3/8) + ... +``` + +Dans la limite de 2C. + +### Et pour les système multi-cœur + +Chaque cœur exécute un ordonnanceur de façon asynchrone, la liste de processus +peut-être : + + * partagée entre tous les cœurs + * distribuée par cœur + +Il est bon de noter qu'une **UC peut envoyer une interruption à un autre UC**. + +## Threads et processus + +Un processus est un espace d'adressage plus une pile d'exécution. Un thread est +juste un **autre flow d'exécution dans le même espace d'adressage**. La création +de threads (aussi appelés processus légers) est dons plus efficace : il n'y a +pas de création d'espace d'adressage. + +Dans les noyaux modernes, tout est thread. + +### Accès concurents à la mémoire + +Les threads partagent donc des espace commun de mémoire, il est donc important +de gérer des accès concurrent. En effet l'accès aux mêmes cases mémoires par +plusieurs threads peut conduire à des fonctionnements arbitraires. + +Il est à noter que les accès à la mémoire sont de toute façon atomique: *une +opération de lecture ou écriture à la fois*. Mais ce n'est pas suffisant, un +example de code est disponible [dans les cours de prog. système]({{< ref +"../../progsys/5_les-processus_legers/index.md">}} "Les processus légers") + + +Le noyau doit donc mettre en place des primitive de synchronisation. diff --git a/themes/mainroad b/themes/mainroad index 6167552..fbd4163 160000 --- a/themes/mainroad +++ b/themes/mainroad @@ -1 +1 @@ -Subproject commit 6167552546f60f5a22344909061afa5b62754555 +Subproject commit fbd4163bd076a82adf430116ac4e5f165df86c8f