 Bonjour à tous, je suis Pierre Sens, et bienvenue dans cette nouvelle édition du second semestre
 sur les principes d'ici-même exploitation.
 Si vous avez des questions, n'hésitez pas à me joindre via Moodle ou directement par l'adresse mail pierre.sens@lip6.fr
 En terme d'organisation de cette UE, je vous rappelle que les TD et TM commencent la semaine prochaine,
 donc la semaine du 1er février. Il y a 5 charges des TD pour les 8 groupes qui composent cette UE.
 Célia Mahamdi pour le groupe 2, donc moi pour les groupes 1 et 3,
 Luciana Rentes pour les groupes 4 et 8, Soane Dubois pour les groupes 5 et 6,
 et Jonathan Sinotman pour le groupe 6.
 En termes de notation, la note finale dépendra des TME, d'un partiel et de l'examen final,
 donc l'examen réparti 1 et l'examen réparti 2.
 Les TME compteront pour 10%, donc ce sera en fonction des rendus TME que vous ferez chaque semaine.
 Puis il y aura 30% pour le partiel, donc l'examen réparti 1, et enfin 50% pour l'examen réparti 2, l'examen final.
 Toujours en termes de l'UE, jusqu'à nouvelle heure, tout se fait à distance.
 Il y a le site de l'UE dans lequel je vais mettre des annales, des supports de cours,
 et aussi des packages pour que vous puissiez faire les TME à distance,
 ou vous aurez le choix pour faire les TME soit à distance chez vous,
 mais pour certains TME vous devrez vous contacter directement sur l'imagine de la ppd.
 Tout sera indiqué dans le Moodle et dans le site de l'UE.
 Vous allez aussi avoir un Moodle dans lequel vous êtes inscrit, dans lequel il y aura de nouveau
 les supports de cours, les instructions pour les accès à distance, tous les documents,
 les pdf des cours, et de la brochure de TD et de TME.
 Les cours, comme vous voyez actuellement, seront disponibles en vidéo sur Moodle.
 Et enfin, vos chargées TD vous donneront pour chacun des groupes les consignes
 pour les TD et les TME à distance.
 Donc ce sera soit du Discord, soit du Zoom ou du Jitsi.
 En termes de bibliographie pour ce cours, il n'y a pas de prérequis spécifiques en termes de livres.
 Un prérequis c'est d'avoir quelques notions de système,
 et aussi avoir fait un peu de C auparavant en E2 ou en E3.
 En termes de livres, il y a des livres qu'on trouve à la bibliothèque,
 il y a ces deux livres sur les principes des systèmes d'exploitation,
 il y a le livre de Galvin et Schibberschal, donc il y a différentes éditions,
 des fois il y a trois auteurs aussi dans ce livre,
 le nom change d'une édition à l'autre, mais en général on trouve les mêmes principes des systèmes d'exploitation.
 Il y a aussi le livre d'Andrew Tanenbaum, il y a plusieurs éditions,
 dont le titre varie un peu, mais à chaque fois dans le titre vous avez "Systèmes d'exploitation".
 Ce sont des livres très complets, qui ne sont pas forcément nécessaires,
 mais si vous voulez un peu plus approfondir ce qu'on voit en cours,
 vous pouvez jeter un œil sur ces livres.
 Le principe de cet UE, ce n'est pas une UE de programmation des systèmes,
 peut-être que vous avez déjà eu des UE de ce type là,
 ici on ne cherche pas à programmer au-dessus des systèmes,
 on cherche à comprendre les mécanismes internes des systèmes d'exploitation,
 soit Linux, Windows, BSD, et donc il y a une multitude de systèmes,
 soit iOS aussi, donc tous ces systèmes ont beaucoup de concepts communs.
 Le but c'est vraiment d'extraire ces concepts communs,
 comment les systèmes gèrent les différents programmes, la mémoire, le disque,
 ce sont des concepts qui ne sont pas spécifiques à un OS particulier,
 donc on ne pourra pas étudier en détail Linux, Windows ou BSD,
 ce sont des choses qu'on fait plus en M1, notamment dans le parcours SAR du master.
 Donc là c'est vraiment introduire les concepts de base qui régissent
 la plupart des systèmes d'exploitation.
 Donc là je vais commencer vraiment le premier cours,
 ce premier cours c'est une introduction au système d'exploitation,
 et à partir de la semaine prochaine on commencera à rentrer plus dans les détails.
 Alors pour nous, qu'est-ce que ça va être un système d'exploitation ?
 Ce qu'on appelle en anglais Operating System ou OS,
 donc je dirais souvent la chronique OS pour désigner système d'exploitation.
 Donc un système d'exploitation ce n'est pas du matériel,
 c'est un logiciel qu'il va falloir charger au démarrage de la machine,
 dont le but est de gérer la machine physique.
 Donc c'est un logiciel qui est spécifique, qui a des droits spécifiques,
 il permet de pouvoir accueillir les applications.
 Donc il offre aux applications une ligne, comme on voit dans ce schéma,
 qui est le matériel en dessous, avec la mémoire, le disque, le réseau et le processeur.
 On va revenir dessus, donc on va aller au-dessus de ce matériel.
 On a le système d'exploitation qui est lui-même en mémoire,
 et dont le but c'est d'accueillir les différents programmes,
 donc vos éditeurs de texte, votre Word, votre PowerPoint, votre navigateur,
 vos éditeurs, votre VI etc, les compilateurs,
 tout ça ce sont des programmes qui s'exécutent au-dessus du système d'exploitation.
 Donc les applications ne manipulent pas directement la machine physique,
 ils ne voient pas les détails de la machine physique,
 les blocs du disque, les différentes pages mémoire etc,
 les différents cœurs des processeurs,
 donc tout ça c'est masqué par le système d'exploitation,
 et le but justement du système d'exploitation c'est d'accueillir ces programmes
 et de les dispatcher sur le matériel.
 Donc ça donne vraiment une vision abstraite et de haut niveau du matériel.
 Et donc les applications ne sont pas dépendantes d'un matériel spécifique,
 elles sont dépendantes d'un système d'exploitation,
 dont le but est justement de répartir les ressources sur le matériel.
 Donc avant de voir plus en détail, c'est important d'avoir un peu une vision historique,
 de comment les systèmes d'exploitation ont évolué au cours de l'histoire,
 et en fait les systèmes d'exploitation ont vraiment suivi les évolutions des ordinateurs.
 Donc si on remonte assez loin dans le temps, donc dans les années 40,
 en fait là à ce moment là le transistor n'était pas encore inventé,
 donc c'était les ordinateurs à tube, qu'on appelait les ordinateurs à tube à vide,
 en gros un tube à vide faisait office de transistor.
 Donc c'était des ordinateurs très très volumineux,
 parce que la taille d'un tube ça fait une dizaine de centimètres,
 donc c'est l'équivalent d'un transistor.
 Donc très rarement il y a des ordinateurs de taille énorme,
 donc l'exemple typique qui est illustré ici c'est l'ENIAC,
 qui en 1946 était composé d'une puissance ridicule de 18 000 tubes,
 donc si vous faites l'analogie avec 20 000 transistors,
 c'est ridicule en termes de puissance et calcul,
 mais pour appuyer ces 18 000 tubes il fallait quand même 30 tonnes,
 comme c'était illustré dans cette image là.
 Donc à ce moment là il n'y avait pas...
 donc comment on exécutait un programme sur ce genre de machine ?
 Ben là il n'y avait pas de système d'exploitation,
 donc c'était vraiment la préhistoire des systèmes.
 Si vous vouliez exécuter un programme, il fallait remodifier le câblage,
 ce que faisait un opérateur comme on voit ici.
 Donc à chaque fois que vous vouliez exécuter un programme,
 automatiser un programme, il fallait remodifier le câblage
 de la machine physique directement.
 Donc là c'est vraiment la préhistoire.
 Ensuite il y a une grosse évolution,
 c'est qu'à partir de la fin des années 50,
 début des années 60,
 on a vu apparaître... le transistor a été inventé,
 et donc on a vu apparaître les premiers ordinateurs en transistor.
 Donc les ordinateurs à tubes ont disparu,
 ont été remplacés par des transistors,
 donc on gagnait énormément en termes d'intégration,
 en termes de miniaturisation.
 Donc ça c'était des machines, ce qu'on appelait...
 Donc là sont apparus vraiment tous les concepts des bases,
 des systèmes qui régissent actuellement, les systèmes modernes en fait.
 Donc c'était des gros systèmes,
 qu'on appelait des systèmes centraux ou mainframes.
 Donc les mainframes existent toujours.
 Et c'est à cette époque là qu'on a introduit tous les concepts,
 qu'on va voir dans cette queue,
 et qui restent actuellement, qui régissent également Linux, Windows actuellement.
 Donc si je zoome un petit peu sur les mainframes, en termes d'évolution,
 donc il y a eu un premier...
 il y a plusieurs mainframes qui ont fait date,
 dans l'histoire des systèmes.
 Notamment il y a le mainframe Atlas,
 qui au début des années 60,
 a été un des tout premiers systèmes à introduire beaucoup de notions,
 notamment celui qui a été un des premiers systèmes à introduire
 la notion de traitement par lot,
 ce qu'on appelle le batch.
 Donc là l'idée c'est que vous aviez plusieurs programmes,
 que vous pouviez exécuter en mémoire,
 et automatiquement, on pouvait lancer une série de programmes.
 Par exemple si j'ai trois programmes,
 ici donc là, dans tous nos schémas, on va l'égistrer très souvent,
 il reste ce type de diagramme,
 ce qu'on appelle un diagramme dans lequel,
 si on a du temps, un ordre dernier, on va retrouver les tâches.
 Ce qu'on appelle donc un diagramme de gantes.
 Donc imaginons que j'ai trois programmes à exécuter,
 on va de manière séquentielle,
 exécuter le premier programme,
 puis automatiquement lancer le deuxième programme,
 puis automatiquement lancer le troisième programme.
 C'était le système Atlas qui lançait
 cette exécution automatique,
 en séquence des programmes,
 P1, P2, P3.
 Donc c'était une première phase d'automatisation,
 par contre, en termes de temps de réponse et d'interactivité avec l'utilisateur,
 c'était extrêmement lourd.
 Par exemple, l'utilisateur qui attendait les résultats du programme P3,
 il devait attendre que P1 et P2 se terminent
 avant que son programme se lance.
 Donc imaginons qu'ici c'est un gros calcul matriciel,
 ici c'est un tout petit programme qui fait l'équivalent d'un LS,
 le LS va attendre plusieurs heures
 pour que les programmes matriciels qui le précèdent se terminent.
 Donc c'était vraiment dédié pour l'exécution de gros programmes,
 très peu adapté à des environnements interactifs tels qu'on les connaît dans les systèmes.
 Vous lancez plein de petits programmes,
 des commandes, des LS, des VIA, etc.
 et en parallèle avoir plusieurs aussi gros programmes.
 Donc pour essayer d'avoir un peu plus d'interactivité avec l'utilisateur,
 avoir des temps de réponse plus raisonnables,
 notamment pour l'utilisateur de programmes P3,
 le MIT a introduit en 1962, dans son ordinateur qui s'est appelé le CTSS,
 la notion de temps partagé, le time sharing en anglais.
 C'était vraiment le premier mainframe, gros système, à introduire cette notion là.
 Donc il y a d'un côté le traitement par lot, on ne partage pas le temps,
 et ensuite le temps partagé.
 Donc l'idée est simple du temps partagé,
 c'est vraiment la pratique qui régit tous les systèmes actuellement.
 Donc on va diviser le temps en petites unités, qu'on appelle un quantum.
 Et donc à chaque fois qu'on lance un programme, par exemple P1,
 je lui alloue une durée maximum d'exécution sur le processeur.
 Donc là par exemple, ici, vous avez votre programme P1 qui est lancé,
 il va s'exécuter une toute petite durée,
 typiquement une centaine, quelques centaines de millisecondes,
 et au bout de quelques centaines de millisecondes, on interrompt P1 pour lancer P2,
 qui va s'exécuter quelques centaines de millisecondes, puis P3, et ainsi de suite.
 Et on fait ça de manière très rapide.
 P1, P2, P3, P1, P2, P3, P1, P2, P3.
 Donc ici, votre diagramme de compte se transforme ici,
 et donc les pointillés sont tellement...
 L'astuce c'est d'avoir des pointillés tellement rapides que l'utilisateur ne les perçoit pas.
 On bascule tellement rapidement de processus que vous, vous avez l'illusion,
 donc là, c'est pour ça que j'ai représenté un oeil, c'est une illusion.
 En vérité, les programmes ne s'exécutent pas en parallèle,
 parce qu'on n'avait qu'un seul processeur à l'époque, sur ces machines-là,
 mais comme vous voyez que chaque utilisateur voyait ses programmes progresser,
 plus lentement, bien sûr, qu'ici, P1 y ralentit.
 Mais on a quand même... chacun voit que son programme progresse,
 donc on a une illusion de parallélisme, c'est ce qu'on appelle du pseudo-parallélisme.
 L'utilisateur, il voit les programmes qui sont plus lents, bien sûr,
 mais qui progressent tous en parallèle.
 C'est cette astuce, lorsque vous lancez deux programmes sur un même processeur,
 vous avez l'illusion que ces deux programmes s'exécutent en parallèle,
 alors bien sûr, ils s'exécutent à retour de Rho,
 mais dans des petites unités de temps qu'on appelle un quantum.
 C'est un peu le même système que pour les 24 images/seconde,
 en fait, on ne perçoit pas les pointillés,
 et vous avez l'illusion d'avoir des traits ici.
 C'est le principe du temps partagé.
 Il y a eu beaucoup de mainframes, une fois que ces concepts ont été posés,
 notamment de temps partagé, quand ils ont été développés.
 Là, ils étaient foisonnants dans les années 60.
 Deux mainframes qui ont fait date,
 il y a la série des OS 360 IBM, qui a été introduite à partir de midi des années 60,
 et Multics aussi, qui a été introduite par le MIT en 65,
 et qui était une machine construite par le département de la Défense américaine.
 La caractéristique de ces mainframes, c'est qu'ils étaient en temps partagé,
 ils pouvaient exécuter de nombreuses tâches,
 et ils pouvaient accueillir surtout un très grand nombre d'utilisateurs.
 C'était des machines puissantes qui occupaient une grande place.
 Ici, par exemple, c'est un exemple d'un Multics,
 qui s'occupait d'un petit gymnase, en fait,
 qui avait plusieurs dizaines de mètres cubes,
 et auquel était connecté un très grand nombre d'utilisateurs.
 Sur la même machine, il y avait directement plusieurs centaines de terminaux
 qui pouvaient être directement connectés sur la même machine physique.
 Donc, il y en avait peu, c'était des machines très coûteuses,
 tout le monde n'avait pas les moyens de s'offrir un mainframe comme ça,
 une machine aussi puissante qu'un Multics, avec de nombreux utilisateurs.
 Donc, avec les problèmes électroniques,
 on a commencé à réduire la taille de ces machines.
 Et donc, une évolution importante, c'est dans la fin des années 60,
 donc entre 65 et 66, on a vu apparaître des machines un peu moins coûteuses,
 moins puissantes, mais beaucoup plus petites,
 qu'on appelait des "Midi-ordinateurs".
 Donc, on passait de machines qui faisaient plusieurs mètres cubes,
 d'une bonne dizaine de mètres cubes, à des machines qui étaient proches de quelques mètres cubes.
 Donc, ce sont des machines beaucoup plus petites,
 donc beaucoup moins chères.
 Et donc, un exemple emblématique de cette époque,
 ce qu'on appelait des "Midi-ordinateurs",
 c'était toute la série des PDP qui ont été développées par la société DEC.
 Donc, c'était des opérateurs moins puissants,
 moins d'utilisateurs, mais beaucoup moins chers.
 Et donc, là ici, exécuter...
 Donc là, c'est un exemple d'ordinateur, un PDP.
 Donc là, vous voyez, c'est beaucoup plus petit qu'un cas Multics.
 Donc, sur ces machines-là,
 on ne pouvait pas exécuter directement un système comme le système Multics.
 Multics, lui, était conçu, sa conception même,
 était conçue pour gérer des centaines d'utilisateurs en parallèle.
 Là, on sait bien qu'on n'aura pas plusieurs centaines,
 on aura quelques dizaines d'utilisateurs en parallèle
 qui seront connectés à cette machine-là.
 Ça ne sert à rien d'avoir un système surdimensionné
 qui est trop coûteux pour une machine beaucoup plus petite.
 Donc, c'est l'idée de Ken Thompson, notamment au départ,
 qui travaillait au Bell Labs,
 Bell Labs qui est le laboratoire de recherche associé à AT&T,
 donc les télécoms américains.
 Ken Thompson a eu l'idée de concevoir un système
 beaucoup plus simple qu'un Multics, par exemple,
 de s'inspirer d'un système comme Multics,
 mais de le simplifier, de faire en sorte qu'il gère moins d'utilisateurs,
 qu'il soit beaucoup plus simple, mais plus performant.
 Avec son collègue Dennis Ritchie,
 ils conçoivent un nouveau système beaucoup plus léger
 qui va être créé au départ complètement en assembleur,
 et qu'ils vont appeler Unix.
 Donc ça, ils l'ont conçu en 1969.
 Unix était vraiment par opposition à Multics,
 il gérait moins d'utilisateurs, il faisait moins de tâches,
 mais de manière plus efficace.
 Donc ils l'ont appelé Unix en référence à Multics.
 Le X a disparu assez rapidement, au bout de deux ans,
 le CS s'est transformé en X et qui a donné naissance à Unix.
 C'est vraiment les concepteurs du tout premier Unix,
 Unix qu'on retrouve maintenant partout.
 La plupart des OS hors de Windows sont des Unix,
 que ce soit dans iOS, chez Apple, Linux, Android,
 la plupart des OS en dehors de la broche Windows sont des Unix.
 Donc ils viennent de cette branche initiale.
 Ce que je vous ai dit, c'est que ce système était multitâche,
 on pouvait en temps partagé,
 mais beaucoup plus simple qu'un mainframe.
 Par contre, il était créé en assembleur.
 Donc ça entraînait une certaine lourdeur.
 Donc à chaque fois qu'on ouvrait une nouvelle machine,
 un nouveau PDP, par exemple le 8, le 11, etc.,
 qui était créé avec un autre langage d'assemblage,
 il fallait récréer une bonne partie du système d'exploitation.
 Donc Thomson et Ritchie ont commencé à en avoir un peu assez
 de récréer leur système à chaque fois qu'on leur livrait une nouvelle machine.
 Donc ils se sont dit, est-ce qu'on ne pourrait pas inventer un langage
 qui nous servirait à écrire le système Unix,
 qui nous éviterait à chaque fois qu'on livre une nouvelle machine
 d'avoir à tout réécrire.
 Donc du coup, avec Ritchie,
 lui a inventé, inspiré d'un langage qui existait à l'époque,
 le langage B, il a inventé le langage C,
 qui est le langage vraiment qui a été conçu au départ
 pour récréer le système d'exploitation Unix.
 C'est un langage qui a des caractéristiques que vous connaissez,
 qui est un langage bas niveau,
 qui permet de faire des manipulations de pointeur,
 une manipulation de mémoire assez fine,
 mais c'est voulu, c'est fait exprès, parce que quand on écrit un système d'exploitation,
 on a besoin de faire ce genre de manipulation.
 Donc avec un contrôle un peu moins strict
 que d'autres par rapport à d'autres langages,
 selon les pointeurs, les types, etc.
 Donc c'est vraiment,
 C est emprunt de cette philosophie d'avoir un langage de bas niveau
 pour pouvoir écrire des systèmes d'exploitation.
 Donc à partir du moment où Ritchie a inventé le C,
 ils ont pu réécrire,
 Thomson et Ritchie alliés à Kerngame,
 ils ont pu réécrire Unix, leur Unix,
 la version courante de leur Unix, à 90%.
 À partir de la version 73,
 uniquement 10% du système d'exploitation
 était écrit en langage assembleur.
 Donc on avait un gag portage à chaque fois qui était énorme.
 Donc 90% n'était pas dépendant du langage,
 n'était pas dépendant du langage assemblage de bas niveau.
 Alors ensuite, si on continue l'évolution,
 donc il y a eu ces grosses évolutions,
 pour résumer on a les gros mainframes
 qui ont introduit les concepts comme le temps partagé,
 aussi d'autres concepts qu'on verra plus tard,
 qui est la mémoire virtuelle,
 donc tout ça s'était introduit dans les années 60.
 À partir de fin des années 60,
 on a commencé à avoir,
 début des années 70,
 on a eu les premiers systèmes d'exploitation écrits en C.
 Ensuite la miniaturisation a continué.
 Donc on a,
 puisque les mini ordinateurs, les PDP,
 restaient des machines assez coûteuses,
 beaucoup moins coûteuses qu'un mainframe,
 mais ça restait quand même des machines assez coûteuses.
 Donc pour pouvoir ouvrir un plus grand public,
 les ordinateurs,
 donc les constructeurs ont commencé à miniaturiser encore plus les machines
 et à offrir ce qu'on appelait,
 au milieu des années 70, des micro-ordinateurs,
 maintenant qu'on en a tous.
 Donc les micro-ordinateurs,
 ce sont des machines encore moins puissantes,
 beaucoup plus petites.
 Donc elles ont des machines,
 avec pas forcément un grand nombre de transistors par rapport aux mini,
 donc elles ont même moins de transistors par rapport à un mini,
 mais elles sont beaucoup plus petites.
 Donc du coup, comme elles sont moins puissantes,
 on ne peut pas,
 donc on avait déjà réduit le nombre d'utilisateurs sur les mini,
 et bien là on réduit encore plus le nombre d'utilisateurs à un seul utilisateur.
 Donc on dédie une machine pour un utilisateur.
 Donc c'est la notion de Personal Computing,
 qui a été introduite par IBM.
 Donc vraiment le côté personnel,
 WP de PC, c'est vraiment le côté
 "une machine pour un utilisateur" à l'origine.
 Donc à partir de ces micro-ordinateurs,
 il y a eu les Apple qui ont été créés,
 les PC qui ont été introduits par IBM,
 aussi fin des années 80.
 Donc du coup, vu que ces machines étaient dédiées à un seul utilisateur,
 ça ne servait à rien à l'époque d'avoir un Unix à exécuter dessus.
 Il fallait des OS encore plus simples,
 capables de gérer un seul utilisateur.
 Un seul utilisateur qui lancerait une seule tâche.
 Donc ce qu'on appelait, ce sont des systèmes très simples,
 donc il y a eu le CPM qui a été lancé au milieu des années 70,
 puis MS-DOS qui a été créé par Bill Gates.
 Donc ces systèmes étaient encore plus simples qu'un Unix,
 parce qu'ils étaient monotisateurs et monotaches.
 Donc typiquement, on lançait une tâche, un éditeur de texte, un jeu,
 et on ne pouvait pas lancer une autre tâche
 tant que l'éditeur de texte ou le jeu n'étaient pas terminés.
 Donc on séquentialisait l'exécution des programmes les uns après les autres.
 On n'avait qu'un seul programme en mémoire qu'on lançait,
 et on les séquentialisait.
 Donc ce sont des systèmes très rudimentaires.
 Donc là, à partir de la branche CPM qui a rapidement disparu,
 il restait essentiellement MS-DOS dans ce type d'ordinateur,
 pour le monde des PC en tout cas.
 Apple a continué son évolution en parallèle aussi.
 Et donc dans la branche MS-DOS,
 ça a été enrichi assez rapidement d'interfaces graphiques que vous connaissez,
 Windows.
 Donc la branche MS-DOS est morte maintenant depuis les années 2000.
 Elle a donné naissance à différentes versions de Windows,
 les confets date, Windows 3.11, Windows 95, Windows 98,
 et enfin la dernière version de cette branche DOS,
 qui est Windows Millennium.
 Donc là c'était vraiment des surcouches du système d'exploitation original MS-DOS,
 qui était un système d'exploitation très rudimentaire.
 Donc ils ont fait évoluer, mais à chaque fois,
 ils étaient limités parce qu'on était limité par cette brique de base de MS-DOS
 qui était fondamentalement plus monotâche et mono-utilisateur.
 Donc ils l'ont arrêtée en demi.
 On verra qu'il y a une autre branche,
 la branche actuelle n'est pas issue de cette branche MS-DOS.
 Ensuite, toujours sur ces PC, sur les micro-ordinateurs,
 jusque dans les années 90, c'était essentiellement du MS-DOS ou de l'Apple
 qui s'exécutait sur ces micro-ordinateurs.
 A partir de la fin de ces années 80, au début des années 90, on a vu apparaître,
 les gens ont commencé à vouloir... les PC montaient en puissance,
 donc on a commencé à avoir des systèmes d'exploitation de type Unix
 à s'exécuter sur ces micro-ordinateurs.
 C'était toute la série des Unix sur PC qui existe toujours.
 C'est à partir des années 90 et 91 pour Linux
 qu'ils sont apparus ces Unix qui étaient open source.
 Tout le monde pouvait les modifier, voir le code, les modifier, les comprendre.
 Et donc il y a maintenant toute une série d'Unix pour PC qui existe.
 Les branches les plus connues, il y a Minix, Linux, FreeBSD.
 Ce sont des systèmes open source, mais multitâches et multivetteurs.
 On était dans la philosophie des Unix de base.
 Et avec le succès qu'on connaît notamment pour Linux, ou les BSD aussi.
 Il y a beaucoup de machines qui exécutent les BSD, notamment dans le monde des réseaux.
 Donc ça c'est une évolution.
 A partir des années 90, les Unix existent sur PC.
 Une autre date aussi importante, qui est peut-être un peu moins connue,
 c'est en 93.
 Windows a décidé, notamment pour exécuter ses serveurs,
 de lancer une nouvelle branche.
 Il y avait la branche MS-DOS qui était pour la bureautique,
 ou les applications de jeux, qui continuent à évoluer.
 C'était un peu temps avant la naissance de Windows 95.
 Mais ils ont décidé de reconcevoir un système from scratch,
 un nouveau système d'exploitation,
 très inspiré d'un mainframe qui existait à l'époque,
 qui existe toujours, qu'ils appellent VMS.
 L'idée c'est qu'ils ont laissé tomber la branche MS-DOS,
 ils ont reconçu un système d'exploitation inspiré d'un mainframe,
 qui est très inspiré d'un Unix.
 C'est vraiment un vrai système multitâche, multitisateur.
 Ils ont créé cette nouvelle branche Windows NT.
 Windows NT est un noyau, un système d'exploitation qui n'a rien à voir avec Windows 3.11.
 C'est un système d'exploitation, même si l'interface était la même.
 En termes d'utilisateurs, on voyait la même interface.
 Le cœur du système d'exploitation a été complètement reconçu.
 C'est la branche NT, qui est la branche actuelle de Windows, qui est née en 1993.
 Elle a subi son évolution en parallèle de la branche "plus bureautique",
 qui était la branche MS-DOS.
 C'était la branche pour le grand public, et la branche pour les serveurs était ici.
 Il y a eu Windows, les premières versions de Windows NT, Windows NT 3, Windows NT 3,
 paru en 1993, il y a eu NT 4, NT 5, Windows 2000,
 qui était bien meilleur que Windows Millennium,
 parce que c'était vraiment conçu sur du multitâche multisateur, intrinsèquement.
 Elle a donné la branche actuelle de Windows,
 donc il y a eu différentes versions, Windows XP, Vista, 7, 8, et maintenant on en est arrivé à Windows 10.
 Tout ça, c'est vraiment le code qu'il y a derrière Windows 10,
 c'est vraiment le code qui a été conçu au départ en 1993,
 qui a été enrichi, bien sûr.
 Il y a eu beaucoup de modifications qui ont été faites,
 mais le cœur du système d'exploitation a été conçu en 1993.
 Voilà sur ces petits aspects historiques.
 Alors maintenant, on va rentrer un peu plus dans les détails, on va commencer.
 Je vous ai dit tout à l'heure que le système d'exploitation, c'est un logiciel,
 donc c'est un programme qu'on charge au démarrage, on va voir comment.
 Le but c'est de gérer une machine,
 donc il faut qu'on se mette d'accord sur qu'est-ce que c'est qu'une machine pour des gens de système.
 Nous, on n'est pas en cours d'architecture,
 donc on ne va pas voir les détails d'un processeur,
 ce n'est pas l'objet de ce cours,
 mais on a besoin de se mettre d'accord sur qu'est-ce que c'est qu'une machine pour des gens de système.
 De manière simplifiée, une machine, pour les concepteurs de système,
 vous avez d'abord un réseau.
 Pour chaque machine, il y a un réseau, un ensemble de bus qui forment un réseau,
 sur lequel on va pouvoir pluguer différents composants.
 Un des composants importants, c'est le processeur central, qu'on appelle le CPU,
 donc c'est votre Intel ou votre AMD.
 Ce sont des processeurs généralistes,
 dans lesquels vont s'exécuter les programmes utilisateurs et le système d'exploitation.
 Le système d'exploitation aussi, c'est un code qu'il faut qu'il s'exécute.
 Les programmes et les systèmes d'exploitation s'exécutent sur le CPU.
 Ce CPU a les différentes unités de calcul,
 les unités arithmétiques logiques, les unités flottantes, les unités de gestion de mémoire, etc.
 Tout ça, ce sont des transistors qui se trouvent ici.
 Tous les codes de programme, toutes les instructions de programme vont s'exécuter dans ce composant-là.
 Sur ce CPU, lorsque vous exécutez un programme ici, il a besoin de variables.
 Ces variables se trouvent dans une zone en mémoire.
 Vous avez ce qu'on appelle la mémoire vivante.
 C'est là-dedans qu'on va mettre toutes les variables des programmes et les codes des programmes.
 Lorsqu'un programme s'exécute, le système va lui allouer de l'espace en RAM, en mémoire vive.
 Lorsque le programme s'exécute, instruction par instruction,
 les variables vont être ramenées une à une sur le CPU pour s'exécuter.
 C'est important lorsque vous exécutez un programme qui soit en RAM,
 une fois qu'il est en RAM, on peut l'exécuter.
 Les instructions vont arriver sur le processeur et s'exécuter.
 La RAM contient le code et les variables des programmes et du système d'exploitation.
 Il y a un autre type de mémoire, ce qu'on appelle la mémoire vive.
 Il y a une autre type de mémoire qu'on appelle la ROM, ou la mémoire morte.
 C'est une mémoire particulière. On va voir à quoi elle nous est utile.
 Elle est utilisée essentiellement, pratiquement que là, au démarrage du système d'exploitation.
 Il y a une mémoire.
 Un des inconvénients de la mémoire de la RAM, c'est qu'elle est rapide,
 par contre, elle est vive, dans le sens où elle doit être en permanence alimentée.
 Pour rafraîchir les cycles de la mémoire, il faut qu'il y ait un courant qui l'alimente.
 C'est-à-dire que lorsque votre machine n'est pas sous tension, tout ce qui est en RAM est supprimé.
 La mémoire morte, c'est une mémoire qui est plus lente qu'une RAM,
 mais dans laquelle les données peuvent perdurer.
 Même lorsque votre machine n'est pas sous tension, un programme reste en ROM.
 On va se servir de la ROM pour mettre des programmes qui vont être utiles lorsqu'on démarre la machine.
 Je vais revenir tout à l'heure dessus.
 Vous avez la RAM qui contient le code des programmes et leurs variables,
 et la ROM qui contient les programmes de démarrage du système d'exploitation.
 On va appeler le BIOS.
 Lorsque vous lancez un programme, il n'est pas en RAM, il est sur le disque.
 Lorsque vous avez un exécutable, il se trouve sur le disque.
 Les disques sont ce qu'on appelle les périphériques.
 Pourquoi ? Parce qu'ils sont périphériques de la machine.
 Le disque n'est pas directement connecté sur le bus,
 les périphériques sont connectés à un processeur spécialisé qu'on appelle un contrôleur,
 ou une unité d'échange.
 Le but, c'est des processeurs assez puissants.
 Des fois, sur certains contrôleurs, il peut y avoir plus de transistors que sur le processeur central.
 Mais ces processeurs sont spécialisés pour une tâche particulière.
 Ce ne sont pas des processeurs généralisés comme un Intel ou un AMD,
 mais ce sont des processeurs dont les tâches sont limitées.
 Ils sont spécialisés, notamment pour nous, dans le cas d'un périphérique de type disque,
 pour transférer des données depuis leur périphérique en mémoire.
 On a un contrôleur par type de périphérique, par exemple on a un contrôleur pour un type de disque,
 mais je peux avoir d'autres contrôleurs.
 Je peux avoir un contrôleur qui va gérer tous les périphériques USB,
 le clavier, la souris, un contrôleur qui va gérer les cartes réseau, etc.
 Donc pour chaque type de périphérique, on a un contrôleur spécifique
 qui a un jeu d'instructions très limité,
 uniquement pour pouvoir faire les transferts entre les périphériques et la mémoire.
 Donc ces contrôleurs sont ce qu'on va appeler DMA.
 Un contrôleur de type DMA, par exemple tous les contrôleurs disques sont de type DMA,
 un contrôleur de type DMA a un accès direct à la mémoire,
 c'est-à-dire qu'il peut prendre une donnée,
 il peut lui donner un ordre pour qu'il prenne une donnée depuis le disque,
 par exemple un bloc du disque, il peut directement la recopier dans la mémoire.
 Donc ça de manière autonome, en parallèle du CPU.
 C'est-à-dire que pendant que le CPU exécute un programme,
 je peux très bien avoir un contrôleur qui, en parallèle du CPU,
 pendant que le CPU exécute un programme,
 transfère un bloc directement depuis le périphérique en RAM.
 Parce qu'il a un accès direct à la RAM.
 Donc ça c'est l'opération de transfert d'une donnée en RAM, en DMA,
 donc en accès direct à la mémoire, c'est ce qu'on appelle une entrée-sortie.
 L'entrée c'est la lecture,
 donc lorsqu'on lit une donnée, de ce sens-là c'est l'entrée,
 et lorsqu'on écrit une donnée, de ce sens-là, c'est ce qu'on appelle une sortie.
 Ce qu'on va appeler dans la suite une entrée-sortie, une ES.
 Donc là, ici, c'est un composant que j'ai indiqué ici, c'est le cache.
 En général, lorsque le CPU a besoin d'une donnée qui se trouve en RAM,
 vous voyez bien que ça prend du temps.
 Parce qu'il va falloir, si vous manipulez une variable qui se trouve en RAM,
 il va falloir passer par le bus pour pouvoir accéder à la RAM.
 Et donc là, dès que vous rallongez la distance,
 on ne peut pas aller plus vite que la lumière,
 donc du coup, dès que vous rallongez la distance pour accéder à une donnée en RAM,
 du coup, ça rajoute de la latence.
 Donc pour diminuer la distance d'accès aux variables,
 tous les processeurs maintenant ont une sorte de mémoire interne,
 qu'on appelle un cache, qui permet d'accélérer les accès aux données.
 Si la donnée, lorsque j'accède à une donnée, je vais voir si elle est dans mon cache,
 et c'est uniquement si ma variable IN est pas dans mon cache,
 que là j'accèderai à ma RAM.
 Donc c'est un composant important des processeurs.
 Donc là, toujours, qu'est-ce qu'il faut retenir sur les composants d'alignateur ?
 Donc nous, dans ce cours, on va simplifier un peu les choses.
 On va supposer d'abord que nos processeurs,
 on n'a qu'un seul CPU, on n'a pas plusieurs cœurs.
 Donc tous les aspects multicœurs, c'est plus vu en M1 et en M2,
 notamment dans Master SAR.
 Donc là, on fait une hypothèse simplificatrice,
 on suppose qu'on n'aura qu'un seul cœur.
 Donc ça veut dire, si vous n'avez qu'un seul cœur,
 vous ne pouvez pas avoir deux programmes qui s'exécutent en vrai parallélisme.
 Si je reprends ici, là on suppose qu'on n'a qu'un seul CPU avec un seul cœur,
 à un instant donné, je ne peux avoir qu'un seul programme qui s'exécute.
 Je ne peux avoir que P1 qui s'exécute.
 Et c'est une fois que P1 a fini de s'exécuter, que P2 pourra s'exécuter.
 Donc il n'y a pas de vrai parallélisme entre l'exécution des programmes.
 Par contre, vous voyez bien que même si j'ai qu'un seul cœur ici,
 on a quand même plusieurs processeurs.
 On a le processeur généraliste, votre IP,
 et les contrôleurs, qui sont les mêmes des processeurs, mais spécialisés.
 Donc ici, on n'aura pas de vrai parallélisme entre l'exécution des programmes.
 Je ne peux pas avoir P1 en vrai parallèle de P2, parce que j'ai qu'un seul cœur.
 Par contre, dès qu'il y en a un qui demande un transfert,
 qui demande une entrée-sortie, à ce moment-là, ce n'est plus le même processeur qui travaille.
 Donc là, je peux avoir du vrai parallélisme entre l'exécution d'un programme,
 par exemple PCP3, et un transfert de données.
 Dans ce petit exemple, imaginons que j'ai mes trois programmes,
 P1, P2, P3.
 Donc P1 s'est exécuté, puis P2.
 P2, au milieu de son exécution, demande un transfert,
 un lien de données, puis le disque.
 À ce moment-là, le système d'exploitation va donner un ordre au contrôleur.
 C'est le système d'exploitation qui va piloter le contrôleur
 via un programme spécifique qu'on appelle un pilote,
 pour faire le transfert.
 Le contrôleur s'active,
 c'est vraiment le processeur du contrôleur qui lance le transfert
 et qui fait la copie directe en mémoire.
 Ça, ça prend du temps.
 C'est la phase de transfert faite par le processeur du contrôleur.
 En parallèle, il n'y a aucune raison que le processeur ne fasse rien pendant ce temps-là.
 Le pilote va donner un ordre pour transférer la donnée de P2,
 et en parallèle, le système d'exploitation va donner la main à P3
 pour que P3 puisse exécuter.
 Il faut bien qu'il y ait un vrai parallélisme
 entre le transfert de données géré par le contrôleur
 et l'exécution d'un programme sur le processeur.
 Là, il n'y a pas de parallélisme, parce qu'on a un seul cœur.
 C'est un point important.
 Dès que vous faites une entrée-sortie, il n'y a aucune raison
 que vous fassiez un accès réseau ou un accès disque.
 Dès qu'un système attend un paquet sur le réseau
 ou attend une donnée depuis le disque,
 le système d'exploitation en profite pour donner la main à un autre programme
 et faire le transfert et l'exécution en parallèle.
 C'est un point important qu'il faut retenir.
 Un autre point aussi, c'est d'avoir en tête
 les ordres de grandeur sur les temps d'accès au processeur.
 Je vous ai dit, lorsqu'un programme a besoin d'une variable,
 ce qu'il y a de plus rapide, c'est d'y aller directement
 dans un registre interne du processeur.
 Là, c'est ce qu'il y a de plus rapide.
 Lorsque vous faites un move,
 vous manipulez un registre interne du processeur,
 l'accès est très rapide et se fait au niveau du cycle du programme.
 En gros, à 0,5 nanosecondes, si on a un 2 GHz,
 le cycle est régi par la fréquence du processeur.
 Donc là, si vous avez besoin d'accéder à une variable i,
 si votre variable i est dans un registre interne du processeur,
 on ne peut pas faire plus rapide.
 Là, on a un accès de 0,5 nanosecondes.
 Ça dépend bien sûr des processeurs.
 Ensuite, si votre variable i n'est pas dans un registre,
 elle est peut-être dans un cache interne du processeur.
 Donc, elle n'est pas en RAM.
 Il y a différents niveaux de cache qui existent dans les machines.
 L1, L2, L3, maintenant, selon ce qui est assez classique.
 Au moins, elle est à L2, de toute façon.
 Donc là, si votre donnée i n'est pas dans un registre,
 le processeur va tester si par hasard,
 elle est dans un cache proche des unités de calcul.
 Ce qu'on appelle les caches L1.
 Plus le chiffre est élevé, plus vous êtes dans le processeur,
 mais plus vous êtes vers l'extérieur du processeur.
 Donc, on ralentit un petit peu.
 On s'éloigne un peu.
 Donc, si jamais votre donnée n'est pas dans un registre,
 on va tester si par hasard, elle n'est pas dans le cache L1.
 Donc là aussi, il y a un petit facteur 4.
 Donc, ça va être 4 fois plus long d'accéder une donnée
 dans un registre par rapport à une donnée qui se trouve dans le cache L1.
 Donc, si la donnée n'est pas présente dans le cache L1,
 on va tester si elle est présente dans le cache L2.
 Donc, il y a un cache sur le processeur, mais qui est un peu plus éloigné.
 Donc là également, c'est deux fois plus long d'accéder une donnée en cache L2.
 C'est des ordres de grandeur.
 C'est deux fois plus long d'accéder une donnée en cache L2 qu'une donnée en cache L1.
 Donc là, tout de suite, on est au-dessous de 500.
 Donc là, on a un petit facteur 10 quand même par rapport au registre.
 On est déjà à 500 nanosecondes.
 Donc, on est à 10,9 secondes.
 Ensuite, si votre donnée n'est pas dans un registre ni dans les caches,
 c'est qu'elle n'est pas dans le processeur.
 À ce moment-là, il va falloir quitter le processeur
 et aller prendre la donnée en RAM.
 Donc là, on passe par les bus,
 ce petit réseau interne de la machine.
 Donc là, on se prend un bon petit facteur 10.
 Donc là, les ordres de grandeur sont un facteur même plus que 10,
 plutôt un facteur 50.
 Donc là, on a un facteur 20.
 Donc là, on est en gros à l'accès en RAM, c'est une centaine de nanosecondes.
 Ça dépend des technologies de RAM, mais c'est entre 50 et 100 nanosecondes.
 Donc on a un facteur entre 10 et 20, ici, entre cet accès-là et ici.
 Et enfin, la donnée, si elle n'est pas présente en RAM,
 il faut aller la chercher sur disque.
 Alors là, c'est là où on a un gap énorme.
 Donc là, le système d'exploitation, il va vous éviter au maximum d'accéder aux données sur disque
 puisque là, vous voyez, pour transférer un bloc depuis le disque,
 là, on ne parle plus de nanosecondes, mais je parle de millisecondes, 10 moins 6.
 Donc là, pour transférer un bloc depuis le disque en mémoire,
 ça prend 10 millisecondes, 0,01 seconde,
 ce qui est énorme par rapport aux 100 nanosecondes.
 Donc là, on a un facteur.
 C'est un million de fois plus long d'accéder à une donnée sur disque
 qu'à accéder à une donnée en RAM.
 Donc c'est là le gros gap.
 C'est ça qu'il faut avoir en tête.
 Ici, dans les premières couches, le système d'exploitation ne va pas avoir beaucoup de prises.
 Ça s'est fait de manière... par les processeurs, ces différents tests.
 Par contre, le système d'exploitation, c'est lui qui régule.
 C'est lui qui décide ce qu'on maintient en RAM, ce qu'on maintient sur disque.
 Donc le système d'exploitation va beaucoup intervenir ici
 pour essayer au maximum de réduire les accès,
 faire en sorte que lorsque vous accédez à une donnée,
 elle soit le plus possible en RAM et le moins possible sur le disque.
 Parce que dès que vous accédez à une donnée sur le disque,
 vous prenez un facteur 1 million en termes de ralentissement.
 Donc ça, on en reparlera lorsqu'on verra notamment
 tout ce qui est système de gestion de fichiers, etc.
 Ça sera un point important dont je vous reparlerai plus tard.
 Alors, maintenant, c'était notre petit rappel sur les notions d'architecture
 que vous avez dû voir dans d'autres lieux.
 Qu'est-ce que c'est le système d'exploitation ?
 Au bas niveau, on a vu en gros ces trois ressources,
 la mémoire, le processeur, le disque.
 Donc la RAM, processeur et disque.
 Ici, je ne vous parlerai pas de réseau dans ce cours
 parce qu'on n'est pas dans une unité de réseau.
 On se limitera en périphérique, on va se limiter au disque.
 Tout ce qui est réseau, on ne va pas le considérer.
 Donc là, tout en haut au-dessus, vous avez les programmes,
 les applications, toujours pareil, le même petit exemple.
 On a P1, P2, P3 qui s'exécutent.
 Et entre les deux, il y a le système d'exploitation.
 Le système d'exploitation, le but, c'est de rendre des services aux différents programmes.
 Dès qu'un programme a besoin d'allouer de nouveau de la mémoire,
 dès qu'un programme doit accéder au processeur,
 ou dès qu'un programme doit accéder au disque,
 dès qu'il a besoin de ses ressources matérielles,
 il doit passer par l'interface du système d'exploitation.
 C'est lui qui alloue les ressources.
 Donc il y a une notion de trac.
 À chaque fois qu'un programme veut accéder, a besoin de nouvelles ressources,
 il va être obligé de demander un service au système d'exploitation.
 Pour appeler ces services, on passe par une interface qu'on appelle les appels système.
 Il y a ces couches d'appels système que vous connaissez,
 que vous avez peut-être manipulées dans d'autres useurs,
 qui permettent d'allouer de la mémoire, d'accéder au disque.
 Quand vous faites read, write, etc.,
 ça te compte que ce sont des appels système qui permettent d'accéder au disque.
 Au départ, le système vous alloue de la mémoire,
 et vous donne une partie des ressources.
 Donc là, il y a vraiment deux mondes.
 Il y a le monde utilisateur,
 où vous, en tant que programmeur, vous n'avez vu que ce monde-là pour l'instant.
 Et nous, dans cette vidéo, on va s'intéresser à cette partie-là.
 Comment s'implémenter ici ?
 On va zoomer sur le système d'exploitation,
 qu'on appelle aussi noyau ou carnet en anglais.
 Donc, il y a un morceau de code qui s'exécute
 avec un mode d'exécution particulier,
 qui a plus de droits que les autres,
 et donc qui permet de réguler les ressources,
 de distribuer les ressources entre les programmes P1, P2, P3.
 Il y a une partie des carnets que vous connaissez aussi,
 des noyaux, ce qu'on appelle les pilotes de périphériques, dont j'ai déjà parlé.
 Ce sont des petits morceaux de code qui appartiennent aux noyaux,
 système d'exploitation,
 dont le rôle est de dialoguer directement avec les périphériques.
 Ce sont eux qui donnent des ordres aux contrôleurs,
 les pilotes, pour le terme "pilot", "driver" en anglais.
 Ils donnent des ordres aux contrôleurs pour pouvoir faire les transferts.
 Ils vont lui dire "transfère-moi tel bloc à telle adresse-là", etc.
 On reviendra dessus.
 Donc ça, c'est la vision globale d'un système d'exploitation.
 Donc ici, vous avez vu,
 je reviens en arrière,
 qu'il y a vraiment deux mondes.
 Le monde utilisateur, où s'exécutent les programmes,
 et le monde système, où s'exécutent les systèmes d'exploitation.
 C'est vraiment important, cette notion de mode d'exécution.
 En mode utilisateur, on n'a pas du tout les mêmes droits.
 Donc ça, c'est des modes,
 c'est offert par les fabricants de processeurs.
 Chaque processeur peut fonctionner soit en mode utilisateur, soit en mode système.
 Donc en mode utilisateur,
 c'est le mode d'exécution par défaut de vos programmes.
 Parce que vous lancez un programme, par défaut, il s'exécute en mode utilisateur.
 Donc à ce moment-là,
 chaque programme ne peut pas accéder à toute la mémoire.
 Il a un accès restreint aux ressources.
 Donc il y a une notion de confinement.
 Si j'ai P1 et P2,
 vous avez le droit de modifier les variables internes,
 vos variables locales, vos variables globales.
 Donc ça, vous avez le droit de les modifier.
 Par contre, dès que vous tentez de sortir de votre enveloppe,
 cette enveloppe qui va être allouée par le système d'exploitation,
 donc vous avez une véritable enveloppe,
 tout de suite, c'est interdit.
 On va voir que c'est un système d'exception,
 qui va vous interdire l'accès à toute ressource
 qui est extérieure à ce que le système vous a alloué.
 Donc le système va vous allouer de la mémoire
 pour pouvoir gérer votre programme.
 Votre code sera là-dedans, vos variables seront ici.
 Mais dès qu'un programme tente d'accéder
 soit à la mémoire du programme d'à côté,
 soit à la mémoire du système d'exploitation,
 le système d'exploitation lui-même, c'est un programme qui est lui-même en mémoire,
 à ce moment-là, il y a tout un mécanisme de protection qui vous interdit cet accès.
 Donc en mode utilisateur, on est restreint,
 on est vraiment confiné.
 Par contre, lorsque vous êtes en mode système,
 à ce moment-là, donc là vous exécutez,
 en mode utilisateur, on exécute les codes des programmes,
 les programmes utilisateurs.
 Par contre, lorsqu'un programme s'exécute en mode utilisateur,
 de temps en temps, il peut demander un service au noyau.
 Il peut lui demander "je veux accéder à tel fichier, à tel bloc du fichier".
 À ce moment-là, on va basculer en mode système.
 En mode système, il y a une trappe qui va s'ouvrir sous les pieds du programme,
 qui va vous faire basculer en mode système,
 et à ce moment-là, vous allez vous exécuter,
 non pas un morceau de code que vous avez codé vous,
 mais un morceau de code du noyau, un morceau de code de Linux.
 Donc à chaque fois qu'un système a besoin
 de ressources particulières en mémoire, disques, etc.,
 il va faire un appel système qui va lui ouvrir une trappe,
 et à ce moment-là, vous allez exécuter un morceau de code du noyau.
 Donc lorsque vous exécutez un morceau de code de Linux ou de Windows,
 vous êtes ce qu'on appelle en mode système,
 et là vous avez accès à toutes les ressources.
 Donc le système a le droit d'aller modifier toutes ses propres variables,
 un système d'exploitation a ses propres variables,
 donc il peut modifier ses variables,
 mais il a le droit aussi d'aller modifier vos variables à vous,
 les variables de n'importe quel programme.
 Il a un accès illimité à toutes les ressources de la machine.
 Il peut faire ce qu'il veut.
 Donc c'est pour ça que par défaut,
 lorsque vous lancez un programme, il n'est pas en mode système.
 Ça veut dire que si vous lancez P1 en mode système,
 c'est-à-dire que vous aurez le droit d'aller modifier
 toutes les variables de tous les autres programmes.
 Votre VI aurait le droit d'aller modifier votre mode ZIA, etc.
 C'est ce qui n'est pas le cas.
 Par défaut, les programmes, lorsqu'ils sont lancés,
 dans le mode utilisateur, ils ont un accès restreint
 uniquement à leurs propres variables.
 Par contre, dès que vous basculez en mode système,
 le système d'exploitation peut modifier ses variables à lui,
 puis les variables de n'importe quel autre programme.
 Mais bien sûr, ici, lorsqu'on est en mode système,
 on n'exécute jamais un programme utilisateur,
 on exécute un morceau de code du noyau.
 Sinon, ça serait trop dangereux.
 Donc là, maintenant, je vous ai indiqué
 que ce système-là,
 si je reviens en arrière,
 le noyau s'exécute en RAM.
 Il est présent au démarrage de la machine,
 et c'est lui qui accueille les demandes des programmes.
 Je veux avoir de la mémoire, je veux accéder au disque, etc.
 Donc à chaque fois, le programme est présent en mémoire,
 Linux est présent en mémoire, Windows est présent en mémoire,
 il attend que les programmes lui demandent des ressources.
 Alors, on peut se poser la question,
 comment le système d'exploitation s'est retrouvé en mémoire ?
 C'est un peu le problème de la faite de la poule.
 Le rôle du système d'exploitation, c'est de créer des espaces pour les programmes,
 mais qui a créé l'espace pour le système d'exploitation en RAM ?
 Donc là, on a besoin d'une aide supplémentaire,
 d'un petit programme qui va se retrouver en mémoire.
 Donc qui est toujours présent, même lorsqu'une machine n'est pas en tension.
 Et donc, c'est la phase d'amorçage du système.
 C'est lors de ces phases d'amorçage que vous connaissez,
 qu'est le bootstrap, le boot du système.
 C'est à ce moment-là que le système d'exploitation va être copié en mémoire.
 Une fois qu'il est copié en mémoire, il peut créer des programmes,
 et avouer des ressources au programme.
 Donc, lorsque vous mettez en tension, vous allumez votre machine,
 la RAM est vide.
 Parce que la RAM, au départ, lorsque votre machine n'est pas alimentée,
 votre RAM se vide.
 Parce qu'elle doit être alimentée en permanence
 pour pouvoir maintenir les données qui sont dedans.
 Donc, à la mise sous tension, lorsque vous allumez votre machine,
 votre RAM est vide.
 Le but, à ce moment-là, c'est de pouvoir charger
 le système d'exploitation en mémoire, en RAM.
 Donc là, on va utiliser un mini-OS,
 qui lui, est toujours présent en ROM.
 Même lorsque votre machine n'est pas alimentée,
 les programmes qui sont en ROM, en mémoire morte,
 eux, ne sont pas perdus.
 Donc, automatiquement, lorsque vous mettez en tension
 une machine, par exemple un PC,
 ça va lancer un petit programme en ROM,
 qu'on appelle le BIOS sous les PC.
 Donc, automatiquement, ça fait un saut,
 un morceau de code qui se roule en ROM, qui est le BIOS.
 Et donc, le rôle du BIOS, il intervient uniquement au démarrage,
 après, il n'intervient quasiment plus dans le système d'exploitation.
 Le but du BIOS, justement, c'est d'aller charger
 le système d'exploitation qui se trouve sur le disque,
 d'aller le ramener en RAM.
 Alors, comment ça se passe ?
 Donc, la mise sous tension, on exécute.
 Lorsque vous mettez en sous tension, il y a un jump,
 on saute directement un morceau de code en ROM,
 qu'on exécute.
 Donc, on exécute ce petit morceau.
 Vous le connaissez, le BIOS, vous pouvez régler ses paramètres,
 notamment dans les setup.
 Vous changez des paramètres dans le BIOS qui se trouve dans cette zone-là.
 Donc, on exécute le BIOS.
 Que va faire le BIOS ?
 Il va vérifier les périphériques,
 il va détecter les différents périphériques.
 C'est les affichages qui sont faits lorsque vous démarrez une machine.
 Il va dire "Ah, j'ai détecté telle carte réseau, tel disque, etc."
 À l'intérieur du BIOS, il y a des mini-pilotes
 qui permettent de dialoguer avec les périphériques.
 Donc, le BIOS détecte "Ah, il y a ce disque-là qui est présent."
 Une fois qu'il a détecté que le disque était présent,
 il va pouvoir lancer un chargement.
 Il va lancer le chargement d'un bloc spécifique
 qu'on appelle un boot-block,
 ou un MBR dans le monde Windows,
 Master Boot Record.
 Donc, ce boot-block, c'est une convention,
 c'est le premier bloc du premier disque.
 Le bloc zéro du disque,
 on suppose que c'est le boot-block.
 Il va lancer une entrée-sortie,
 il va prendre ce bloc-là,
 il va le recopier en RAM.
 Il donne un ordre au contrôleur
 pour recopier ce bloc-là, ce MBR, en RAM.
 Une fois qu'il est recopié en RAM, il l'exécute.
 Ce MBR est censé contenir un code,
 un code tout petit,
 parce qu'il doit contenir dans un bloc,
 512 octets, souvent.
 Donc, là, le rôle du BIOS,
 il vérifie, il détecte les périphériques,
 il lance une entrée-sortie,
 il ramène ça en RAM,
 puis après il exécute le petit programme
 qui est contenu dans le MBR.
 Ce programme contenu dans le MBR,
 c'est ce qu'on appelle un loader.
 Donc, ce MBR, lui, il est propre au système d'exploitation.
 Donc, ce qu'il faut voir, c'est que le BIOS,
 lui, il ne sait pas quel système il exécute,
 parce que sur votre machine, vous avez pu installer Windows,
 Linux, BSD.
 Donc, le BIOS, il ne sait pas quelle OS
 il doit exécuter.
 Il n'a aucune notion de ça.
 Par contre, le MBR, lui, il est spécifique à l'OS.
 Donc, lorsque vous installez une machine,
 un Linux ou un Windows,
 le Linux ou le Windows vont écraser le MBR
 pour mettre le programme qui permet de charger leur système d'exploitation.
 Donc, lorsqu'on exécute le MBR,
 ou le boot-block,
 le boot-block, lui, il sait que,
 c'est le boot-block de Linux,
 il sait que Linux se trouve à tel emplacement sur 10,
 il va lancer des entrées-sorties pour charger le système d'exploitation en RAM,
 et puis, après, commencer à exécuter le main du système d'exploitation.
 Donc, ça, c'est spécifique à l'OS.
 C'est le MBR, il est spécifique à l'OS qu'on a installé,
 dont le but est de charger la partie orange ici,
 marron, je crois,
 dont le but est vraiment de charger le système d'exploitation en RAM
 et de l'exécuter.
 Donc, voilà la séquence initiale.
 Alors, après, c'est un système assez souple,
 par exemple, si vous voulez faire ce qu'on faisait beaucoup avant,
 ce qu'on fait moins maintenant avec les machines virtuelles,
 c'est de faire du multi-boot.
 Si vous voulez, sur une machine, pouvoir accueillir plusieurs OS,
 il suffit d'aller modifier ce boot-block.
 Vous avez toujours votre programme en BIOS qui charge le boot-block, le MBR.
 Plutôt que de faire un aiguilleur,
 ce qu'on appelle un boot-manager,
 il y en a plein, il y a GRUB, Lilo, le boot-manager de Windows,
 il y a toute une série, il y en a plein qui existent.
 Ce que font ces boot-managers ?
 Ils écrasent le MBR pour changer le code.
 Ils changent le code du MBR,
 plutôt que de charger automatiquement le boot-block de Linux,
 plutôt que de charger automatiquement Linux ou Windows,
 ils vont faire un petit aiguillage.
 Dans ce boot-block, on va mettre un code qui va poser une petite question,
 qui va faire un petit affichage,
 saisir une réponse au clavier,
 et en fonction de la réponse saisie,
 il sait qu'il faut charger soit le boot-block de Windows,
 soit le boot-block de Linux.
 Comment je sais où se trouve le boot-block de Windows ?
 Dans ce petit boot-block, dans ce MBR,
 il y a le code qui permet de charger le système d'exploitation,
 et ce qu'on appelle la table des partitions,
 qui indique pour chaque partition Windows ou Linux,
 où elle commence.
 Là, vous avez le code qui est exécuté,
 c'est là qu'on va saisir quelle OS vous voulez booter,
 vous voulez démarrer,
 en fonction du numéro qui a été saisi,
 vous allez voir la table des partitions,
 vous allez dire "OK, il m'a demandé de charger Windows,
 donc je vais charger le boot-block de Windows,
 je save l'emplacement du boot-block de Windows grâce à la table des partitions,
 donc j'exécute le boot-block de Windows,
 et Windows va charger Windows,
 le reste du système d'exploitation.
 Pareil, si j'ai saisi Linux ici,
 je vais aller voir, l'IDO ou GRUB va aller voir dans la table des partitions,
 où commence Linux,
 va charger le boot-block de Linux,
 qui doit se trouver au début de la partition Linux,
 et une fois que le boot-block de Linux est chargé,
 on exécute ce petit boot-block qui va charger le reste de Linux.
 Voilà comment se passe le démarrage.
 Maintenant, on va supposer, dans la suite,
 que le système d'exploitation est chargé en mémoire grâce au BIOS et au boot-block.
 Donc tu vois, le BIOS charge le boot-block,
 il l'exécute, et le boot-block charge le système d'exploitation.
 Une fois que le système d'exploitation est chargé, il va s'initialiser,
 et le but est d'être au service des applications.
 La plupart du temps, le système d'exploitation ne fait pas grand-chose,
 il se met en attente,
 et on lui demande des services, d'allouer de la mémoire, etc.
 La plupart du temps, le système d'exploitation ne prend pas de temps sur le processeur.
 Le but du système d'exploitation, c'est de gérer et partager les différentes ressources,
 mémoire, disques, réseau, CPU, entre les programmes.
 Il doit gérer notamment le processeur,
 on va voir dans les cours suivants tous ces points-là en détail.
 Le but, c'est de gérer le processeur.
 Quand j'avais mes programmes P1, P2, P3,
 c'est le système d'exploitation qui va décider, c'est autour de P1 d'y aller,
 puis autour de P2, puis autour de P3.
 C'est ce qu'on appelle les algorithmes d'ordonnancement de tâche,
 qui permet de choisir quel programme allouer sur le processeur.
 C'est le système d'exploitation qui régulièrement évalue à qui c'est le tour.
 C'est ce qu'on appelle les algorithmes d'ordonnancement,
 qu'on va voir en détail, qu'on va commencer à voir à partir du prochain cours.
 Un autre point important aussi, lorsque vous avez P1, P2, P3,
 on sait à quel moment on va exécuter chaque programme, grâce à l'algorithme d'ordonnancement,
 c'est de savoir quelle est la mémoire que je vais allouer à chaque programme.
 Tout ce qui est allocation de mémoire,
 quelle est la taille de l'enveloppe que je donne au départ à chaque programme.
 Chaque programme, je vous ai dit, il va s'exécuter dans un monde confiné,
 au monde utilisateur, mais il faut bien que je lui alloue au départ une enveloppe
 pendant laquelle il va mettre son code et ses variables.
 Dans ça, il y a toute une partie d'allocation de mémoire,
 et après, vu que tous les programmes ici sont en compétition pour accéder à la mémoire,
 il va falloir gérer la mémoire, dire à qui je donne plus ou moins de mémoire.
 Tout ça, ça va être des stratégies de gestion qu'on va voir dans la gestion de la mémoire virtuelle.
 Il y aura plusieurs cours autour de la gestion de la mémoire virtuelle,
 qui est une partie importante des systèmes d'exécutation.
 Un autre composant, vu que nous, on ne va pas s'intéresser au réseau dans ce cours-là,
 c'est la gestion des disques.
 Les programmes ont besoin de processeurs, de puissants, de mémoire,
 mais ils ont également besoin d'accéder aux données qui sont sur le disque.
 Comme je vous ai dit, accéder aux données sur le disque,
 c'est un million de fois plus long que d'accéder à une donnée en mémoire.
 Le système met en place toute une série de stratégies,
 on en verra quelques-unes, qui permettent d'éviter d'accéder au maximum au disque.
 Donc, par exemple, lorsque vous accédez au fichier,
 la première fois que vous accédez à un fichier, il faut bien le charger en mémoire,
 et si vous accédez de nouveau peu de temps après,
 le système va cacher le fichier en mémoire,
 pour éviter que lorsque vous avez un second accès, vous ayez besoin d'accéder au disque.
 Ce qu'on appelle une stratégie de cache disque, qui permet d'éviter cet accès.
 Le premier accès est lent, parce qu'il faut bien ramener le fichier depuis le disque en mémoire,
 on ne peut pas y échapper, mais après, tous les accès futurs,
 on va essayer de maintenir au maximum le fichier en mémoire,
 pour éviter d'accéder au disque.
 Donc, il y a toute une série de stratégies qu'on appelle la stratégie de cache, qui permet de faire ça.
 Il y a aussi un point important, c'est que si vous regardez un disque de bas niveau,
 c'est juste une suite de blocs, qui sont stockés.
 Vous, en tant qu'utilisateur, vous ne voyez pas une suite de blocs, vous voyez des fichiers.
 Des fichiers, des répertoires, avec des droits, etc.
 Donc, c'est ce qu'on appelle les systèmes de gestion de fichiers.
 Comment le système d'exploitation transforme la vision de bas niveau,
 qui est juste une série de blocs, en arbre, en arborescence, en système de fichiers, etc.
 Donc, ça, c'est la partie système de fichiers.
 Il y aura plusieurs cours autour de ça, qui montreront comment on fait la correspondance
 entre la vision bloc, la vision bas niveau, et la vision fichier, que vous avez que les programmes.
 Donc là, aussi, pour conclure ce premier cours, on a besoin de se mettre d'accord sur quelques définitions.
 Pour l'instant, j'ai été un peu vague sur la notion de programme utilisateur.
 Donc là, on va être un peu plus précis.
 Pour nous, ce que je vais appeler dans la suite, un programme, c'est un programme qui ne prend pas forcément des ressources en mémoire.
 Par défaut, vous avez beaucoup de programmes, tout ce qui est exécutable, vous avez des milliers d'exécutables,
 mais ils sont au départ stockés sur le disk.
 Donc, ils ne prennent que des ressources sur le disk.
 Par contre, dès que vous lancez un programme, vous double cliquez dessus, ou vous le lancez depuis le chef,
 là il se transforme en ce qu'on appelle un processus minitâche.
 Donc, dès que vous lancez un programme, un point exé ou un point out, ou dès que vous double cliquez sur un exécutable,
 en fait, le programme exécutable va être chargé en mémoire.
 On va lui créer un contexte mémoire, avec des registres, et il va s'exécuter.
 Donc, un programme qui a été lancé, c'est ce qu'on appelle une tâche ou un processus.
 Pour nous, on ne fera pas de distinction dans ce cours entre un tâche, on ne fera pas de différence entre tâche et processus,
 et j'utiliserai indifféremment le terme tâche ou processus.
 Donc, un processus, c'est un programme qui a été lancé, simplement.
 Et un programme, c'est juste un exécutable, de manière plus simple.
 Après, il y a deux modèles dans les systèmes, soit les modèles qu'on appelle de monoprogrammation,
 dans lequel il ne peut y avoir qu'une seule tâche présente en mémoire à un instant donné.
 En gros, c'est les modèles qu'il y avait dans les vieux systèmes d'exploitation comme MS-DOS,
 où on ne lançait qu'un seul programme à la fois.
 On lance P1, et une fois que P1 est terminé, on lance P2.
 Une fois que P2 est terminé, on lance P3.
 Dans les vieux systèmes d'exploitation, c'est ce qu'on faisait.
 Nous, on ne s'intéressera assez peu à la monoprogrammation,
 on s'intéresse surtout à ce qu'on appelle la multiprogrammation, c'est juste le côté multitâche.
 On peut avoir plusieurs tâches présentes en mémoire à un instant donné.
 Dès que vous avez P1, P2, P3, ça se trouve, on peut donner un petit peu de temps au processeur à P1,
 puis au bout d'un certain temps, rebasculer sur P2, puis rebasculer sur P1, etc.
 Ça change beaucoup les stratégies.
 Quand on est en multiprogrammation, on a plusieurs tâches qui sont présentes en mémoire,
 qui peuvent tous être exécutées à un instant donné.
 C'est au système d'exploitation de choisir, via l'ordonnancement, quelles tâches je vais exécuter.
 À partir de maintenant, je vais parler de processus ou tâches.
 Un processus, c'est un programme qui a été lancé.
 Ce programme, en fait, dans un système, peut être dans différents états.
 On distingue, dans la plupart des OS, trois états de base.
 L'état "prêt", c'est lorsque le processus est prêt à s'exécuter.
 Il est prêt en mémoire, il ne s'exécute pas, il a été chargé en mémoire,
 le système lui a donné de la place pour stocker son code.
 Le code a été recopié depuis le disque, donc il est prêt à s'exécuter.
 Il attend avant de s'exécuter, mais il n'y a rien qui le bloque.
 Ensuite, parmi les programmes prêts, il y en a un qui va être élu.
 Ici, vu qu'on n'a qu'un seul cœur, on est en mono-cœur,
 à un instant donné, il n'y a qu'un seul élu, pas plusieurs.
 Vu que j'ai un seul CPU, je ne peux avoir qu'un seul processus élu.
 Parmi les tâches prêtes, il y en a un qui va être élu.
 Après, une fois que votre programme est élu, il peut se bloquer.
 On verra, il y a toute une série d'événements qui entraînent le blocage d'un processeur.
 Par exemple, lorsque je vous demande un transfert depuis le disque,
 je vous ai dit qu'un transfert depuis le disque, c'est très lent.
 Ça prend au minimum 10 millisecondes.
 Pendant ces 10 millisecondes, on ne va pas bloquer tout le monde.
 À ce moment-là, lorsqu'un processus élu demande un transfert depuis le disque,
 on va le mettre hors jeu juste le temps de son transfert,
 et on va pouvoir donner la main à un autre processus.
 Là, c'est un exemple. Lorsque je vous demande un transfert, vous le passez.
 On met hors jeu le processus en passant à l'état bloqué.
 De même, lorsque vous faites un scanf, il s'hésite depuis le clavier.
 Ou lorsque vous attendez un pack à réseau.
 Ou lorsque vous voulez vous synchroniser avec un autre processus.
 Tout ça, ce sont des raisons dans lesquelles le processus ne peut plus continuer à s'exécuter.
 On le met hors jeu temporairement, tant que ce qui est attendu n'est pas arrivé.
 Donc, ces trois états, prêt, élu, bloqué, comment on passe d'un état à l'autre ?
 Je vous donne la description lorsqu'on est en mode batch.
 En mode batch, je vous rappelle, c'est un traitement par lot, il n'y a pas de notion de temps partagé.
 C'est-à-dire qu'un programme, on ne partage pas le temps, il n'y a pas de notion de quantum.
 Lorsque vous êtes en mode batch, lorsque le programme est créé,
 on le verra, c'est un appel système dans les Unix qui permet de créer un processus.
 Lorsqu'un processus, pas un programme, est créé,
 c'est le fork qui permet de faire ça dans les Unix, notamment.
 Donc, il est créé, ça prend un certain temps.
 Au bout d'un moment, une fois qu'il est alloué en mémoire,
 c'est le système qui prend en charge la phase de création.
 Il vous crée l'état prêt.
 Donc, il n'y a pas de raison que lorsque vous créez un processus,
 que le processus que vous venez de créer double tout le monde
 et ait accès direct au processeur.
 Quand vous créez un processus, il faut qu'il attende son tour.
 Donc, par défaut, à la création, vous êtes créé à l'état prêt.
 Parmi tous les processus qui ont été créés, il y en a un qui va être élu.
 On verra, on zoomera sur les algorithmes d'élection, à partir du cours prochain déjà.
 Le but, c'est de choisir, on a peut-être créé des dizaines de processus,
 ils sont tous prêts à s'exécuter, ils sont tous en mémoire.
 Parmi ceux-là, le système d'exploitation va en choisir un.
 Celui-là va être ce qu'on appelle l'élu.
 Une fois qu'il est élu en mode batch, il va prendre...
 On ne partage pas le temps. Il reste sur le processeur.
 Il exécute son code, il se termine.
 Lorsqu'il est fin, il est hors-jeu, il n'existe plus.
 À ce moment-là, on va élire quelqu'un d'autre.
 Un processus se termine, il est expulsé, et un autre va être élu.
 Ou alors, il y a une autre condition pour quitter le processeur.
 C'est si jamais il se met en blocage, par exemple,
 s'il demande une entrée-sortie ou une saisie clavier.
 À ce moment-là, dès qu'il demande une entrée-sortie, une saisie clavier,
 ou un paquet sur le réseau, il y a toutes ces conditions.
 Nous, ce sera essentiellement des entrées-sorties, dans le cas de ce cours.
 Donc, des accès entrées-sorties, c'est accès disque.
 Dès qu'il demande un transfert depuis le disque,
 le système d'exploitation va le basculer à l'état bloqué.
 À ce moment-là, un nouveau processus va être élu.
 Donc, vous voyez bien qu'on ne revient pas directement de l'état bloqué à l'état élu.
 Donc, lorsque vous êtes bloqué, vous ne pouvez pas être élu.
 C'est impossible.
 Parce que là, c'est normal, puisque le programme doit attendre
 la saisie ou le clavier, ou que l'entrée-sortie se termine.
 Donc, le programme qui a demandé une entrée-sortie, un transfert disque,
 il est bloqué, et il va être débloqué dès que le transfert est terminé.
 Donc, il y a une phase de réveil. Il y a le blocage et le réveil.
 Dès que le transfert est terminé, à ce moment-là, on rebascule le processus à l'état prêt,
 et de nouveau, il pourra être élu au prochain tour.
 Donc, un processus qui demande une entrée-sortie, il était prêt au départ,
 il s'exécute, il demande un transfert, il est hors-jeu.
 Dans l'exemple de tout à l'heure, j'avais P2 qui demandait un transfert,
 donc il était hors-jeu, à ce moment-là, P3 pouvait passer.
 Donc, le P2 est hors-jeu, et lorsque l'entrée-sortie est terminée,
 de nouveau, il est prêt à s'exécuter, il pourra de nouveau être élu
 par le système d'exploitation.
 Donc, ça, c'est l'exécution en mode batch.
 Si on fait le même schéma en mode en temps partagé,
 donc en temps partagé, je vous rappelle, on rajoute la notion de quantum.
 C'est juste ça en plus, sinon c'est un schéma qui est très très proche.
 Donc là, on retrouve ce qu'on appelle un graph d'état,
 les états du processus.
 Donc, à la création, ça ne change pas, on est créé à l'état prêt.
 Parmi les processus P1, P2, P3 qui ont été créés, il y en a un qui est élu.
 Si ce processus élu se termine, on en prend un autre.
 De même, s'il se bloque, s'il demande une entrée-sortie,
 il passe à l'état bloqué.
 Mais, il y a une troisième condition pour quitter le processeur,
 c'est si jamais il a atteint la fin de quantum.
 Donc, même s'il ne se termine pas, il ne demande aucune entrée-sortie,
 il fait simplement du CPU, il fait une boucle de calcul simplement,
 d'autorité le système pour partager le temps avec les autres,
 de manière plus équitable, d'autorité au bout de 100 ms par exemple,
 qui est une taille de quantum assez classique.
 En Linux, c'est de 100 ms, pour longtemps c'était 100 ms.
 Donc, au bout de 100 ms, il a atteint son quantum,
 à ce moment-là, le processus n'est pas mis à l'état bloqué,
 puisqu'il n'est pas bloqué, il n'y a rien qui le bloque,
 il ne demande pas d'entrée-sortie.
 Par contre, on le rebascule à l'état prêt pour en élire un autre.
 Donc, le processus, à la fin de quantum, il est rebasculé à l'état prêt.
 Donc, par exemple, si j'avais P1, lorsque P1 a fini son quantum,
 il est rebasculé à l'état prêt, donc du coup, P2 va pouvoir passer.
 Puis P2, lorsqu'il a fini son quantum, il est rebasculé à l'état prêt,
 donc P3 passe, ainsi que P1, P2, P3.
 Donc, on voit un mouvement un peu circulaire des processus,
 où à toutes deux rôles, ils vont s'exécuter.
 Ici, si on revoit le schéma qu'on avait vu juste ici,
 donc là, c'est ce qui était fait ici.
 Donc là, lorsque P1 est élu, P2, P3 sont prêts uniquement.
 Lui, c'est l'élu, à ce moment là, ici, P1 est rebasculé à l'état prêt,
 et c'est P2 qui devient l'élu.
 À ce moment là, ensuite, P2 est rebasculé à l'état prêt,
 et c'est P3 l'élu.
 Donc, élu, élu, élu, élu, élu, élu, élu,
 et c'est de manière cyclique, qui vous donne l'illusion, en fait,
 cette illusion de parallélisme.
 Et par contre, pour les entrées sorties, pour revenir dessus,
 pour illustrer l'état bloqué,
 ici c'est l'exemple où j'ai P2 qui était,
 imaginons que là, on soit en mode batch,
 donc il n'y a pas de notion de quantum, pour simplifier.
 Donc, P2 qui est élu, il demande une entrée sortie,
 à ce moment là, P2 bascule à l'état bloqué,
 et c'est P3 qui était prêt, qui passe à l'état élu.
 Lorsque l'entrée sortie de P2 est terminée,
 on voit bien que P2 est réinjecté dans la liste des processus prêts,
 donc lorsque P3 a terminé, il peut de nouveau être élu.
 Donc là, à cet endroit là, ici, c'est là où,
 dans cette flèche là, c'est là où P2 est basculé à l'état bloqué,
 et c'est à cette flèche là, lorsque l'entrée sortie est terminée,
 c'est à ce moment là que P2 est réinjecté dans la liste des processus prêts.
 Donc du coup, le système peut l'élire, on verra quand.
 Il peut de nouveau être élu, c'est pour ça que P2,
 on peut reprendre la main, une fois que P3 a terminé.
 Donc, on va arrêter ce premier cours ici.
 Ce premier cours est disponible sur le Moodle,
 vous pouvez m'envoyer, mettre des commentaires,
 je répondrai aux commentaires dessus,
 et n'hésitez pas à me poser des questions.
 Et donc, dans le prochain cours, on verra un peu de matériel aussi
 pour les gestion des interruptions, qui est un composant important,
 et on commencera à voir, à zoomer sur,
 une fois qu'on a introduit la notion d'interruption,
 on commencera à zoomer sur cette brique de l'élection,
 qui est un point stratégique des systèmes d'exploitation.
 Voilà, je vous remercie, au revoir.
