<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
    <title>La Forge - virtualisation</title>
    <subtitle>Le blog de la Forge</subtitle>
    <link rel="self" type="application/atom+xml" href="https://staging.lafor.ge/tags/virtualisation/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://staging.lafor.ge"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2023-07-12T00:00:00+00:00</updated>
    <id>https://staging.lafor.ge/tags/virtualisation/atom.xml</id>
    <entry xml:lang="fr">
        <title>Introduction à la Virtualisation (Partie 1)</title>
        <published>2023-07-12T00:00:00+00:00</published>
        <updated>2023-07-12T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://staging.lafor.ge/virtualization-1/"/>
        <id>https://staging.lafor.ge/virtualization-1/</id>
        
        <content type="html" xml:base="https://staging.lafor.ge/virtualization-1/">&lt;p&gt;Bonjour à toutes et tous 🙂&lt;/p&gt;
&lt;p&gt;Bienvenue dans un article encore une fois bien trop long.&lt;/p&gt;
&lt;p&gt;Ce devait être l’introduction d’un article sur la création d’image disque dans un pipeline Gitlab CI, je vais pas
vous le cacher, ça a un peu dérapé… 🤭&lt;/p&gt;
&lt;p&gt;Je vous propose un tour d’horizon des concepts de la virtualisation que j’utiliserai par la suite dans l’article prévu au début.&lt;/p&gt;
&lt;p&gt;Mais comme je sais pas m’arrêter et que j’aime que n’importe qui puisse comprendre quelque soit son niveau de départ, il y aura de l’extra 😁&lt;/p&gt;
&lt;p&gt;Avant de commencer.&lt;/p&gt;
&lt;p&gt;D’abord, un grand merci à &lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://twitter.com/sameo&quot;&gt;Samuel Ortez&lt;/a&gt;, &lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://twitter.com/juuduu&quot;&gt;Julien Durillon&lt;/a&gt; et &lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://twitter.com/zepag&quot;&gt;Pierre-Antoine Grégoire&lt;/a&gt; pour la &lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://www.youtube.com/watch?v=As44YzdnqqE&quot;&gt;présentation&lt;/a&gt; que je vais tenter de résumer et compléter sans déformer dans les lignes qui vont suivre.&lt;/p&gt;
&lt;p&gt;Prenez une inspiration, on descends ! 🤿&lt;/p&gt;
&lt;h2 id=&quot;code-machine-et-hardware&quot;&gt;Code Machine et Hardware&lt;/h2&gt;
&lt;p&gt;Oui, comme ça direct. ^^&lt;/p&gt;
&lt;p&gt;Ne vous inquietez pas je vais vous guider.&lt;/p&gt;
&lt;h3 id=&quot;code-machine&quot;&gt;Code Machine&lt;/h3&gt;
&lt;p&gt;Premièrement ce qu’il faut savoir, c’est qu’un ordinateur est extrêment idiot, il ne parle ni français ni anglais, il ne connais qu’un langage, le
Code Machine, basiquement des &lt;code&gt;0&lt;/code&gt; et des &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Impossible de lui donner à manger du C, du Java ou du JavaScript, il n’est pas fait pour ça.&lt;/p&gt;
&lt;p&gt;Dans un ordinateur, ce qui est responsable de comprendre et d’exécuter du code se nomme un CPU (Central Processing Unit).&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;60%&quot; alt=&quot;le CPU ne prend que du code machine&quot; src=&quot;/assets/images/rust/why/cpu1.png&quot; /&gt;
&lt;p&gt;De même, un CPU parle un Code Machine bien spécifique et ne saura comprendre un Code Machine différent.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;60%&quot; alt=&quot;Ce code machine doit être adapté au CPU&quot; src=&quot;/assets/images/rust/why/cpu2.png&quot; /&gt;
&lt;p&gt; &lt;/p&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;J’ai fait abstraction de l’interprétation et de la semi-compilation, plus de détail &lt;a href=&quot;/rust/pourquoi/#executer-du-code&quot;&gt;dans cet article&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;cpu&quot;&gt;CPU&lt;/h3&gt;
&lt;p&gt;Voyons un peu plus en détail les différents composants d’un ordinateur.&lt;/p&gt;
&lt;p&gt;Le premier, nous l’avons déjà nommé est le CPU.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;60%&quot; alt=&quot;Anatomie d&#39;un CPU&quot; src=&quot;/assets/images/virtualization/cpu.png&quot; /&gt;
&lt;p&gt;Il est composé de deux parties principales (je fais abstraction de ce qui nous intéresse pas ).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Les &lt;strong&gt;Registres&lt;/strong&gt; : R1, R2, … et Acc&lt;/li&gt;
&lt;li&gt;L’ &lt;strong&gt;A&lt;/strong&gt;rithmetic &lt;strong&gt;L&lt;/strong&gt;ogic &lt;strong&gt;U&lt;/strong&gt;nit ou ALU ou UAL en français (Unité Arithmétique et Logique)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Les &lt;strong&gt;Registres&lt;/strong&gt; sont des petites mémoires qui ne permettent (en simplifiant) que de stocker une valeur.&lt;/p&gt;
&lt;p&gt;Plus d’infos dans &lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://medium.com/@nafisanaznin24cse041/microprocessor-i-general-purpose-registers-31cd43f3d6bd&quot;&gt;cet article&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ils sont en quelques sortes l’établi utiliser par un artisan pour poser ses planches avant la découpe.&lt;/p&gt;
&lt;p&gt;Dans ces registres, un est un peu spécial et se nomme l’Accumulateur, ici je le représente par un &lt;strong&gt;Acc&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Si les registres sont l’établi, alors l’&lt;strong&gt;ALU&lt;/strong&gt; sont les outils de l’artisan, son travail est de manipuler les registres pour
faire des opérations mathématique ou des transferts de données.&lt;/p&gt;
&lt;h3 id=&quot;ram&quot;&gt;RAM&lt;/h3&gt;
&lt;p&gt;Mais je l’ai dit plus haut, un registre ne contient qu’une seule valeur, ici on a 5 registres, donc on peut stocker 5 valeurs, nos programmes vont
être courts 🤭&lt;/p&gt;
&lt;p&gt;L’idée est alors de stocker ailleurs la donnée, la place sur le CPU étant limitée, on vient stocker dans un autre composant appelé la &lt;a href=&quot;/physical_memory/&quot;&gt;RAM&lt;/a&gt;.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;60%&quot; alt=&quot;Connexion entre le CPU et la RAM&quot; src=&quot;/assets/images/virtualization/cpu2.png&quot; /&gt;
&lt;p&gt;Le CPU communique avec la RAM au moyen de deux canaux :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;bus d’adresse : défini ce que le CPU veut atteindre&lt;/li&gt;
&lt;li&gt;bus de données : transfert les données dans le sens CPU -&amp;gt; RAM ou RAM -&amp;gt; CPU&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;&lt;strong&gt;Précisions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Ici je fais abstraction du cache CPU, d’ailleurs c’est en partie pour ça que les Apple M1 sont très rapides, ils ont beaucoup de cache ^^&lt;/p&gt;
&lt;p&gt;J’assimile toute mémoire de travail à de la RAM pour plus de facilité.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img class=&quot;&quot; width=&quot;80%&quot; alt=&quot;Le programme dans la RAM&quot; src=&quot;/assets/images/virtualization/cpu4.png&quot; /&gt;
&lt;p&gt;On peut globalement y stocker n’importe quoi, tant que ce sont des &lt;code&gt;0&lt;/code&gt; et des &lt;code&gt;1&lt;/code&gt;. Et ça tombe bien notre programme est du Code Machine pouvant se représenter par du &lt;a href=&quot;/rust/annex_bases/#base-2&quot;&gt;binaire&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Chaque donnée est adressée par un nombre.&lt;/p&gt;
&lt;p&gt;Dans cet exemple le CPU demande le contenu de l’adresse &lt;code&gt;@500&lt;/code&gt; à la RAM.&lt;/p&gt;
&lt;p&gt;Chouette on peut stocker plus de 5 valeurs. 🙂&lt;/p&gt;
&lt;h3 id=&quot;peripheriques&quot;&gt;Périphériques&lt;/h3&gt;
&lt;p&gt;Mais le CPU à part faire des calculs, il ne sert pas à grand chose, il faut au moins une imprimante comme dans l’ancien temps pour lire le résultat.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;60%&quot; src=&quot;https://c7.alamy.com/compfr/cmrr74/1960-programmation-de-l-ordinateur-central-grand-homme-entoure-par-une-bande-de-donnees-cmrr74.jpg&quot; /&gt;
&lt;p&gt;C’est pour cela que l’on a inventé les &lt;strong&gt;Périphériques&lt;/strong&gt;. Ceux-ci peuvent être n’importe quoi: un disque dur, la carte graphique, la carte réseau, l’imprimante
qui marche jamais quand vous en avez besoin, etc …&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;70%&quot; alt=&quot;Périphériques&quot; src=&quot;/assets/images/virtualization/cpu3.png&quot; /&gt;
&lt;h2 id=&quot;assembleur-et-instructions&quot;&gt;Assembleur et Instructions&lt;/h2&gt;
&lt;p&gt;C’est bien beau tout ça mais le binaire et l’esprit humain cela fait 2 (sans mauvais jeu de mots ^^’), c’est pour cela que l’on ne manipule pas directement les &lt;code&gt;0&lt;/code&gt; et les &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On le remplace par une sorte de langage qui est transcriptible en &lt;code&gt;0&lt;/code&gt; et &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;assembleur&quot;&gt;Assembleur&lt;/h3&gt;
&lt;p&gt;Ce langage se nomme de l’&lt;strong&gt;Assembleur&lt;/strong&gt; ou &lt;strong&gt;ASM&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;Il existe autant d’assembleur qu’il y a de de Code Machine différents et plusieurs Assembleur différents peuvent
mener au même Code Machine.&lt;/p&gt;
&lt;p&gt;Cet assembleur est la première abstraction créé par l’Humain pour l’aider à parler le Machine sans devenir fou!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Un exemple d’assembleur (rassurez-vous on détaille après 🙂).&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;LOD @&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-14&quot;&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Va être transcrit en utilisant le Code Machine de notre CPU fictif en &lt;code&gt;0101010&lt;/code&gt;&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;100%&quot; alt=&quot;Load opcode&quot; src=&quot;/assets/images/virtualization/opcode1.png&quot; /&gt;
&lt;p&gt;Notre ligne de programme en Assembleur peut alors se décomposer en deux parties&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;OpCode&lt;/strong&gt; : ce que l’on doit faire&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Opérandes&lt;/strong&gt; : avec quoi ?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Un autre exemple d’instruction&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-d-3&quot;&gt;STD&lt;/span&gt;&lt;span&gt; @&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-14&quot;&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Qui devient&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;90%&quot; alt=&quot;Store opcode&quot; src=&quot;/assets/images/virtualization/opcode2.png&quot; /&gt;
&lt;p&gt;On voit ici que le OpCode change la transcription binaire, il aurait été de même si l’opérande avait également évolué.&lt;/p&gt;
&lt;p&gt;La langue du Code Machine est appelé un set d’instructions.&lt;/p&gt;
&lt;h3 id=&quot;instructions&quot;&gt;Instructions&lt;/h3&gt;
&lt;p&gt;Nous avons l’alphabet attaquons-nous aux mots.&lt;/p&gt;
&lt;p&gt;La langue du CPU est décomposé en instructions, voici celle de notre CPU fictif.&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th style=&quot;text-align: center&quot;&gt;OpCode&lt;/th&gt;&lt;th style=&quot;text-align: center&quot;&gt;Operande 1&lt;/th&gt;&lt;th style=&quot;text-align: center&quot;&gt;Operande 2&lt;/th&gt;&lt;th style=&quot;text-align: left&quot;&gt;Signification&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;MOV&lt;/td&gt;&lt;td style=&quot;text-align: center&quot;&gt;RX&lt;/td&gt;&lt;td style=&quot;text-align: center&quot;&gt;D&lt;/td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Déplace la valeur D vers le registre RX, D peut être un autre registre&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;LOD&lt;/td&gt;&lt;td style=&quot;text-align: center&quot;&gt;RX&lt;/td&gt;&lt;td style=&quot;text-align: center&quot;&gt;@A&lt;/td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Charge la valeur à l’adresse @A depuis la RAM vers le registre RX&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;STD&lt;/td&gt;&lt;td style=&quot;text-align: center&quot;&gt;RX&lt;/td&gt;&lt;td style=&quot;text-align: center&quot;&gt;@A&lt;/td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Stocke la valeur contenu dans le registre RX à l’adresse @A de la RAM&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;ADD&lt;/td&gt;&lt;td style=&quot;text-align: center&quot;&gt;X&lt;/td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;/td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Ajoute la valeur X à Acc, X peut être un registre&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;OUT&lt;/td&gt;&lt;td style=&quot;text-align: center&quot;&gt;X&lt;/td&gt;&lt;td style=&quot;text-align: center&quot;&gt;#VX&lt;/td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Ecrire X sur le périphérique #VX&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;JMP&lt;/td&gt;&lt;td style=&quot;text-align: center&quot;&gt;@A&lt;/td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;/td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Sauter à l’instruction à l’adresse @A&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;JNZ&lt;/td&gt;&lt;td style=&quot;text-align: center&quot;&gt;RX&lt;/td&gt;&lt;td style=&quot;text-align: center&quot;&gt;@A&lt;/td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Sauter à l’instruction à l’adresse @A, si la valeur dans le registre RX n’est pas 0&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center&quot;&gt;HLT&lt;/td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;/td&gt;&lt;td style=&quot;text-align: center&quot;&gt;&lt;/td&gt;&lt;td style=&quot;text-align: left&quot;&gt;Stop le CPU et met fin au programme&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Maintenant que nous avons des mots, nous allons pouvoir faire des phrases.&lt;/p&gt;
&lt;h2 id=&quot;execution-d-un-programme&quot;&gt;Exécution d’un programme&lt;/h2&gt;
&lt;p&gt;Ces phrases vont être notre programme.&lt;/p&gt;
&lt;p&gt;Je vous propose celui-ci.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;90%&quot; alt=&quot;Programme d&#39;exemple&quot; src=&quot;/assets/images/virtualization/programme1.png&quot; /&gt;
&lt;p&gt;Chaque ligne du programme est stockée à une adresse, ici on débute à l’adresse &lt;code&gt;@500&lt;/code&gt;, biensûr c’est la représentation binaire qui est stockée
et non l’assembleur.&lt;/p&gt;
&lt;p&gt;Nous avons donc 3 questions à résoudre :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;La ligne du programme est dans la RAM, comment la transmettre au CPU ?&lt;/li&gt;
&lt;li&gt;Une fois dans le CPU, comment fait-il pour comprendre la ligne ?&lt;/li&gt;
&lt;li&gt;Que se passe-t-il à l’exécution de la ligne ?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pour cela, nous allons introduire 3 notions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fetch&lt;/li&gt;
&lt;li&gt;Decode&lt;/li&gt;
&lt;li&gt;Exec&lt;/li&gt;
&lt;/ul&gt;
&lt;img class=&quot;&quot; width=&quot;60%&quot; alt=&quot;Fetch - Decode - Execute qui se chaînent avec des flèches&quot; src=&quot;/assets/images/virtualization/fetch_decode_exec.png&quot; /&gt;
&lt;p&gt;Notre curseur d’exécution est à l’adresse &lt;code&gt;@500&lt;/code&gt;, ce qui veut dire que la ligne d’instruction à rechercher dans la RAM est à l’adresse &lt;code&gt;@500&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Le CPU demande donc le contenu de l’adresse  &lt;code&gt;@500&lt;/code&gt; à la RAM au travers du bus d’adresses, la RAM lui renvoie ce contenu.&lt;/p&gt;
&lt;p&gt;Cette opération est appelée le &lt;code&gt;Fetch&lt;/code&gt;.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;80%&quot; alt=&quot;Opération de Fetch&quot; src=&quot;/assets/images/virtualization/programme2.png&quot; /&gt;
&lt;p&gt;Une fois le contenu binaire de l’adresse &lt;code&gt;@500&lt;/code&gt; en main, celui-ci est décodé.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;60%&quot; alt=&quot;Opération de Decode&quot; src=&quot;/assets/images/virtualization/programme3.png&quot; /&gt;
&lt;p&gt;Ici le décodage nous annonce que l’opération à réaliser de mettre la valeur &lt;code&gt;1&lt;/code&gt; dans le registre &lt;code&gt;Acc&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-d-3&quot;&gt;MOV&lt;/span&gt;&lt;span&gt; ACC, &lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-14&quot;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Maintenant que le CPU, sait quoi faire, il va pouvoir l’exécuter.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;70%&quot; alt=&quot;Opération de Decode&quot; src=&quot;/assets/images/virtualization/programme4.png&quot; /&gt;
&lt;p&gt;Dans le cas présent, mettre un &lt;code&gt;1&lt;/code&gt; dans le registre &lt;code&gt;Acc&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On passe alors à la ligne suivante en incrémentant le curseur d’exécution.&lt;/p&gt;
&lt;p&gt;Et du coup, fetch de l’adresse &lt;code&gt;@501&lt;/code&gt; cette fois-ci.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;70%&quot; alt=&quot;Opération de Fetch&quot; src=&quot;/assets/images/virtualization/programme6.png&quot; /&gt;
&lt;p&gt;Décodage&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;60%&quot; alt=&quot;Opération de Decode&quot; src=&quot;/assets/images/virtualization/programme7.png&quot; /&gt;
&lt;p&gt;en&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-d-3&quot;&gt;MOV&lt;/span&gt;&lt;span&gt; R1, &lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-14&quot;&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Puis exécution&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;70%&quot; alt=&quot;Opération d&#39;Execute MOV&quot; src=&quot;/assets/images/virtualization/programme8.png&quot; /&gt;
&lt;p&gt;Nous avons maintenant un &lt;code&gt;1&lt;/code&gt; dans l’accumulateur et un &lt;code&gt;4&lt;/code&gt; dans le registre &lt;code&gt;R1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On déroule le programme.&lt;/p&gt;
&lt;p&gt;Celui-ci nous demande d’additionner le contenu de l’accumulateur avec le contenu du registre &lt;code&gt;R1&lt;/code&gt; et de mettre
le résultat dans l’accumulateur.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-d-3&quot;&gt;ADD&lt;/span&gt;&lt;span&gt; R1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;img class=&quot;&quot; width=&quot;70%&quot; alt=&quot;Opération d&#39;Execute ADD&quot; src=&quot;/assets/images/virtualization/programme9.png&quot; /&gt;
&lt;p&gt;Nous avons maintenant &lt;code&gt;5&lt;/code&gt; dans l’accumulateur.&lt;/p&gt;
&lt;p&gt;On continue.&lt;/p&gt;
&lt;p&gt;Plus compliqué, on nous demande de stocker le contenu de l’accumulateur dans la RAM à l’adresse &lt;code&gt;@15&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-d-3&quot;&gt;STD&lt;/span&gt;&lt;span&gt; ACC, @&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-14&quot;&gt;15&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;img class=&quot;&quot; width=&quot;90%&quot; alt=&quot;Opération d&#39;Execute STD&quot; src=&quot;/assets/images/virtualization/programme10.png&quot; /&gt;
&lt;p&gt;Le CPU va adresser la RAM pour que la valeur &lt;code&gt;5&lt;/code&gt; contenue dans l’accumulateur soit stockée à l’adresse &lt;code&gt;@15&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Ligne suivante, on fait le chemin inverse, on demande de charger le contenu de l’adresse &lt;code&gt;@15&lt;/code&gt; dans le registre &lt;code&gt;R1&lt;/code&gt;.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;90%&quot; alt=&quot;Opération d&#39;Execute LOD&quot; src=&quot;/assets/images/virtualization/programme11.png&quot; /&gt;
&lt;p&gt;Nous avons maintenant &lt;code&gt;5&lt;/code&gt; à la place de &lt;code&gt;1&lt;/code&gt; dans le registre &lt;code&gt;R1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;On déroule.&lt;/p&gt;
&lt;p&gt;Nous devons déplacer ce qui est dans &lt;code&gt;R1&lt;/code&gt; dans &lt;code&gt;R2&lt;/code&gt;. Facile.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-d-3&quot;&gt;MOV&lt;/span&gt;&lt;span&gt; R2, R1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;img class=&quot;&quot; width=&quot;90%&quot; alt=&quot;Opération d&#39;Execute MOV&quot; src=&quot;/assets/images/virtualization/programme12.png&quot; /&gt;
&lt;p&gt;Nous avons maintenant &lt;code&gt;5&lt;/code&gt; dans le registre &lt;code&gt;R2&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Plus difficile, nous avons utilisé les registres, l’ALU, la RAM, mais pas encore les périphériques.&lt;/p&gt;
&lt;p&gt;Nous allons demander d’écrire le contenu du registre &lt;code&gt;R2&lt;/code&gt; sur le périphérique &lt;code&gt;#12&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Ici, nous allons dire que c’est du disque dur.&lt;/p&gt;
&lt;p&gt;Chaque périphérique est un micro ordinateur, qui possède également des registres.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-d-3&quot;&gt;OUT&lt;/span&gt;&lt;span&gt; R2, #&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-14&quot;&gt;12&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Vient écrire sur le périphérique en &lt;code&gt;voie 1&lt;/code&gt; dans le registre &lt;code&gt;X2&lt;/code&gt;, la valeur contenue par le registre &lt;code&gt;R2&lt;/code&gt;.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;100%&quot; alt=&quot;Opération d&#39;Execute OUT&quot; src=&quot;/assets/images/virtualization/programme13.png&quot; /&gt;
&lt;p&gt;&lt;code&gt;5&lt;/code&gt; est maintenant écrit dans le registre, le disque viendra alors faire quelque chose avec cette valeur, mais ceci est hors scope de
notre article.&lt;/p&gt;
&lt;p&gt;La dernière instruction, éteint le CPU.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-d-3&quot;&gt;HLT&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;multi-processus&quot;&gt;Multi-Processus&lt;/h2&gt;
&lt;h3 id=&quot;race-condition&quot;&gt;Race condition&lt;/h3&gt;
&lt;p&gt;Généralement, nous n’avons pas qu’un seul programme qui tourne sur un ordinateur.&lt;/p&gt;
&lt;p&gt;Chacun de ces programmes sont stockés dans la RAM à des addresses différentes.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Notre programme 1 débute à l’adresse &lt;code&gt;@126&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Tandis que le programme 2 à l’adresse &lt;code&gt;@500&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;img class=&quot;&quot; width=&quot;80%&quot; alt=&quot;Deux programme en RAM&quot; src=&quot;/assets/images/virtualization/programme14.png&quot; /&gt;
&lt;p&gt;Comme nous n’avons qu’un seul CPU, et qu’il ne peut pas faire deux choses en même temps, il faut faire les choses de manière séquentielle.&lt;/p&gt;
&lt;p&gt;Nous allons départager le temps que nous passons dans chaque programme.&lt;/p&gt;
&lt;p&gt;D’ailleurs lorsqu’un programme tourne, nous allons l’appeler un &lt;strong&gt;processus&lt;/strong&gt;.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;80%&quot; alt=&quot;Schedule&quot; src=&quot;/assets/images/virtualization/programme15.png&quot; /&gt;
&lt;p&gt;Chaque passage entre processus sera appelé un &lt;code&gt;context switch&lt;/code&gt;, on verra par la suite de quoi il en retourne.&lt;/p&gt;
&lt;p&gt;Voici les deux programmes en questions.&lt;/p&gt;
&lt;p&gt;Maintenant expert en assembleur, vous devriez les comprendre. ^^&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;90%&quot; alt=&quot;Deux programmes&quot; src=&quot;/assets/images/virtualization/programme16.png&quot; /&gt;
&lt;p&gt;On accélère la montre pour se placer à l’instruction&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-d-3&quot;&gt;STD&lt;/span&gt;&lt;span&gt; ACC, @&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-14&quot;&gt;15&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;du programme 1, celle-ci écrit comme tout à l’heure la valeur &lt;code&gt;5&lt;/code&gt; à l’adresse &lt;code&gt;@15&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;C’est alors qu’intervient le context switch, le processus 1 doit laisser la main au processus 2.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;90%&quot; alt=&quot;Instruction STD processus 1&quot; src=&quot;/assets/images/virtualization/programme17.png&quot; /&gt;
&lt;p&gt;Nous sommes juste avant le début du programme 2, le switch de contexte ne peut pas faire grand chose, il est sensé remettre les
valeurs du contexte d’exécution du processus 2.&lt;/p&gt;
&lt;p&gt;Mais comme le programme n’a jamais tourné, c’est plus du bruit qui est défini ou bien les valeurs précédentes restent inchangées.&lt;/p&gt;
&lt;p&gt;En tout cas, en l’état le processus 2, ne sait pas ce qu’il y a dans les registres.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;90%&quot; alt=&quot;Context switch entre processus 1 et processus 2&quot; src=&quot;/assets/images/virtualization/programme18.png&quot; /&gt;
&lt;p&gt;Le programme 2 se déroule et atteint une instruction étrangement familière.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-d-3&quot;&gt;STD&lt;/span&gt;&lt;span&gt; R1, @&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-14&quot;&gt;15&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Comme un ordinateur est déterministe, une même action, provoque le même résultat.&lt;/p&gt;
&lt;p&gt;A ceci prêt que l’opération précédente avait défini la valeur de &lt;code&gt;R1&lt;/code&gt; comme étant &lt;code&gt;0&lt;/code&gt;&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;90%&quot; alt=&quot;Instruction STD processus 2&quot; src=&quot;/assets/images/virtualization/programme19.png&quot; /&gt;
&lt;p&gt;Donc maintenant l’adresse &lt;code&gt;@15&lt;/code&gt; vaut &lt;code&gt;0&lt;/code&gt; !!!&lt;/p&gt;
&lt;p&gt;Nous venons de créer une &lt;code&gt;race condition&lt;/code&gt; : deux acteurs qui utilisent la même ressources sans se synchroniser sur l’écriture.&lt;/p&gt;
&lt;p&gt;Temps écoulé pour le processus 2, il passe la main.&lt;/p&gt;
&lt;p&gt;Le context switch restaure les états des registres pour que le processus 1 puisse de nouveau travailler.&lt;/p&gt;
&lt;p&gt;On remet :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;4 dans le registre R1&lt;/li&gt;
&lt;li&gt;5 dans l’accumulateur&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On restaure également le pointeur d’exécution.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;90%&quot; alt=&quot;Context switch entre processus 2 et processus 1&quot; src=&quot;/assets/images/virtualization/programme20.png&quot; /&gt;
&lt;p&gt;On incrémente le curseur d’exécution.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;LOD R1, @&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-14&quot;&gt;15&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;img class=&quot;&quot; width=&quot;90%&quot; alt=&quot;LOD processus 1&quot; src=&quot;/assets/images/virtualization/programme21.png&quot; /&gt;
&lt;p&gt;Ah bah oui, mais non …&lt;/p&gt;
&lt;p&gt;Le &lt;code&gt;5&lt;/code&gt; n’est plus là. Il a été précédemment remplacé.&lt;/p&gt;
&lt;p&gt;Le programme 1, n’est désormais plus déterministe, il est capable de faire n’importe quoi.&lt;/p&gt;
&lt;p&gt;Echec et mat !&lt;/p&gt;
&lt;p&gt;Sommes-nous condamner à n’exécuter qu’un seul programme par CPU.&lt;/p&gt;
&lt;p&gt;Non, biensûr que non.&lt;/p&gt;
&lt;p&gt;Mais pour ça, nous allons avoir besoin de plus de choses.&lt;/p&gt;
&lt;h3 id=&quot;kernel-et-mmu&quot;&gt;Kernel et MMU&lt;/h3&gt;
&lt;p&gt;Il va nous falloir un chef de gare pour gérer un peu la discipline dans les rangs.&lt;/p&gt;
&lt;p&gt;Je vous le présente, il s’agit du &lt;strong&gt;Kernel&lt;/strong&gt;.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;70%&quot; alt=&quot;Kernel&quot; src=&quot;/assets/images/virtualization/programme22.png&quot; /&gt;
&lt;p&gt;Son rôle va être de gérer les processus et de les empêcher de faire n’importe quoi.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;70%&quot; alt=&quot;Kernel et processus&quot; src=&quot;/assets/images/virtualization/programme23.png&quot; /&gt;
&lt;p&gt;Et par n’importe quoi, je veux dire écrire n’importe où dans la mémoire.&lt;/p&gt;
&lt;p&gt;Le but étant d’éviter la race condition, mais plus généralement que chaque processus reste chez lui et ne puisse
pas aller taper de la mémoire qui ne lui appartient pas ou qui est déjà utilisée.&lt;/p&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;Il a encore un milliard de rôles différents supplémentaires, mais on reste simple, c’est de la vulgarisation, pas un cours.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Pour l’aider dans sa tâche de cloisonnement, le Kernel peut faire appel à un outil.&lt;/p&gt;
&lt;p&gt;Celui-ci se nomme la &lt;strong&gt;M&lt;/strong&gt;emory &lt;strong&gt;M&lt;/strong&gt;anagement &lt;strong&gt;U&lt;/strong&gt;nit.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;70%&quot; alt=&quot;MMU&quot; src=&quot;/assets/images/virtualization/programme24.png&quot; /&gt;
&lt;p&gt;Il s’agit globalement d’une liste d’adresse virtuelles qui pointent sur des adresses physique.&lt;/p&gt;
&lt;p&gt;Pourquoi virtuelle ? Parce qu’elles n’ont aucune existence physique, elle n’existent pas dans la RAM, au contraire de l’adresse physique, qui est et bien
physiquement présente dans le silicium.&lt;/p&gt;
&lt;p&gt;Pour permettre de s’y retrouver et aussi d’avoir plusieurs fois la même adresse virtuelle pour deux adresses physiques différentes, on découpe la MMU en tables.&lt;/p&gt;
&lt;p&gt;Ici par exemple on a deux tables, dans ces deux tables l’adresses virtuelle &lt;code&gt;15&lt;/code&gt; existe, mais ne pointe pas vers la même adresse physique.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;70%&quot; alt=&quot;Table du MMU&quot; src=&quot;/assets/images/virtualization/programme25.png&quot; /&gt;
&lt;p&gt;Dans la table 1&lt;/p&gt;
&lt;p&gt;$$15 \Rightarrow 1005$$&lt;/p&gt;
&lt;p&gt;Dans la table 2&lt;/p&gt;
&lt;p&gt;$$15 \Rightarrow 22$$&lt;/p&gt;
&lt;blockquote class=&quot;markdown-alert-warning&quot;&gt;
	&lt;p&gt;La MMU est un composant physique à la différence du Kernel qui est du logicielle.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;la-mmu-en-action&quot;&gt;La MMU en action&lt;/h3&gt;
&lt;p&gt;Nous allons utiliser cette propriété pour résoudre notre problème de tout à l’heure.&lt;/p&gt;
&lt;p&gt;Revenons dans le temps.&lt;/p&gt;
&lt;p&gt;Nous sommes dans le processus 1, juste avant le stockage de la valeur en RAM.&lt;/p&gt;
&lt;p&gt;Nous allons interposer la MMU sur le chemin du bus d’adressage.&lt;/p&gt;
&lt;p&gt;Le CPU fait ce qu’il faisait avant, demander de stocker à l’adresse &lt;code&gt;@15&lt;/code&gt;, mais la MMU est configurée par le Kernel pour utiliser
la table &lt;code&gt;p1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Ainsi, l’adresse subit la modification suivante:&lt;/p&gt;
&lt;p&gt;$$15 \Rightarrow 1013$$&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;100%&quot; alt=&quot;Translation d&#39;adresse&quot; src=&quot;/assets/images/virtualization/programme26.png&quot; /&gt;
&lt;p&gt;Notre &lt;code&gt;5&lt;/code&gt; est alors stocké à l’adresse physique &lt;code&gt;@1013&lt;/code&gt; et non &lt;code&gt;@15&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Cette fois-ci, c’est au processus 2 de vouloir stocker son &lt;code&gt;0&lt;/code&gt; à l’adresse &lt;code&gt;@15&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Mais même principe, le Kernel défini la table de la MMU sur &lt;code&gt;p2&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Ainsi, l’adresse réellement utilisée devient&lt;/p&gt;
&lt;p&gt;$$15 \Rightarrow 2862$$&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;100%&quot; alt=&quot;Translation d&#39;adresse&quot; src=&quot;/assets/images/virtualization/programme27.png&quot; /&gt;
&lt;p&gt;Son &lt;code&gt;0&lt;/code&gt; est alors stocké à l’adresse physique &lt;code&gt;@2862&lt;/code&gt; et non &lt;code&gt;@15&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Lorsque le processus 1 revient à la vie.&lt;/p&gt;
&lt;p&gt;Il va lors du chargement de l’adresse &lt;code&gt;@15&lt;/code&gt;, là aussi passer par le MMU.&lt;/p&gt;
&lt;p&gt;Ainsi ce n’est pas &lt;code&gt;@15&lt;/code&gt; mais à nouveau &lt;code&gt;@1013&lt;/code&gt; qui est utilisé pour adresser la RAM.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;100%&quot; alt=&quot;Translation d&#39;adresse&quot; src=&quot;/assets/images/virtualization/programme27_2.png&quot; /&gt;
&lt;p&gt;Et donc c’est bien un &lt;code&gt;5&lt;/code&gt; et non un &lt;code&gt;0&lt;/code&gt; qui est désormais stocké dans le registre &lt;code&gt;R1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Le programme peut de nouveau continuer. 🌞&lt;/p&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;La MMU est un composant physique.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;La MMU est une partie essentielle de la sécurité d’un ordinateur, sans lui un programme malveillant ou mal conçu pourrait réécrire la
mémoire d’un autre programme ou même le programme lui-même.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Du fait que l’isolation soit matérielle, cela rend très difficile le contournement de la sécurité.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;syscall&quot;&gt;Syscall&lt;/h3&gt;
&lt;p&gt;De la même manière que nous ne voulons pas qu’un processus prenne la main sur la mémoire de ses petits camarades, nous allons isoler nos processus de l’accès direct aux ressources physiques.&lt;/p&gt;
&lt;p&gt;Pour 2 raisons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Un programme ne sait pas forcément parler “Disque dur”&lt;/li&gt;
&lt;li&gt;On veut pas qu’il puisse effacer ce qu’il veut le Kernel compris (oui les programmes sont sur disque avant d’arriver dans la RAM ^^)&lt;/li&gt;
&lt;/ul&gt;
&lt;img class=&quot;&quot; width=&quot;100%&quot; alt=&quot;Syscall&quot; src=&quot;/assets/images/virtualization/programme28.png&quot; /&gt;
&lt;p&gt;Lorsque qu’un processus désire réaliser une manipulation qui nécessite autre chose que de la RAM, ce processus va réaliser une doléance
au Kernel, cette demande est appelée un &lt;strong&gt;Syscall&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Le syscall que nous allons utiliser se nomme &lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://man7.org/linux/man-pages/man2/read.2.html&quot;&gt;read&lt;/a&gt;. Son boulot est demander la lecture d’une ressource
un fichier par exemple qui serait sur le disque dur.&lt;/p&gt;
&lt;p&gt;Mais de la même manière que le processus ne savait pas parler “Disque Dur”, le Kernel ne sait pas non plus.&lt;/p&gt;
&lt;p&gt;Heureusement, le &lt;strong&gt;Driver&lt;/strong&gt; lui parle à la fois Kernel et Disque Dur, se sera donc notre interprète dans la transaction.&lt;/p&gt;
&lt;blockquote class=&quot;markdown-alert-note&quot;&gt;
	&lt;p&gt;Pour les besoins du dessin je simplifie tout, mais il y a bien plus de chose à dire ^^&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Détaillons ce qu’il se passe lors de la lecture de ce fichier.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;100%&quot; alt=&quot;Syscall&quot; src=&quot;/assets/images/virtualization/programme29.png&quot; /&gt;
&lt;p&gt;Le processus vient définir qu’il a besoin en mettant l’information dans un registre (ici pour l’exemple R2 ), le nombre est ce qu’on appelle un &lt;em&gt;file descriptor&lt;/em&gt;, c’est un identifiant qui est connu du Kernel et qu’il associe à une ressource, ici un fichier déjà ouvert par un précédent syscall &lt;a rel=&quot;nofollow noreferrer external&quot; href=&quot;https://man7.org/linux/man-pages/man2/open.2.html&quot;&gt;open&lt;/a&gt;.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;100%&quot; alt=&quot;Syscall&quot; src=&quot;/assets/images/virtualization/programme30.png&quot; /&gt;
&lt;p&gt;Un &lt;strong&gt;JMP&lt;/strong&gt; est une instruction appelée un Jump, celui-ci vient déplacer le curseur d’exécution à l’adresse définie ici &lt;code&gt;@809&lt;/code&gt; qui correspond
au début de notre syscall imaginaire et simplifié &lt;em&gt;read_fd&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Le syscall fait des trucs, dont stocker de la donnée à l’adresse &lt;code&gt;@10005&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;C’est alors que des mécanismes un peu complexes et que je n’ai pas totalement saisis vont aller réveiller le Kernel qui piquait une sieste en attendant qu’il
se passe quelque chose d’intéressant.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;100%&quot; alt=&quot;Syscall&quot; src=&quot;/assets/images/virtualization/programme31.png&quot; /&gt;
&lt;p&gt;Cette magie noire se nomme une &lt;strong&gt;interruption&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Les instructions qui vont suivre sont appelées &lt;strong&gt;privilégiées&lt;/strong&gt; car elle ne peuvent être exécuté que dans un mode spécifique du CPU, mode qui ne peut être
atteint que par le Kernel et ses modules dont les drivers.&lt;/p&gt;
&lt;p&gt;Il va alors faire ce que le syscall lui demande, lire le fichier, mais comme il ne sait toujours pas parler Disque dur, il fait appel
au &lt;strong&gt;Driver&lt;/strong&gt; qui lui sait.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;100%&quot; alt=&quot;Syscall&quot; src=&quot;/assets/images/virtualization/programme32.png&quot; /&gt;
&lt;p&gt;Finalement le Disque dur est lu, au travers de l’opération&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;asm&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-3 z-d-3&quot;&gt;OUT&lt;/span&gt;&lt;span&gt; R2, #&lt;/span&gt;&lt;span class=&quot;z-l-9 z-d-14&quot;&gt;12&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Le trajet de retour vers le processus est une autre histoire, peut-être un jour dans un autre article ^^“&lt;/p&gt;
&lt;p&gt;Petit récapitulatif de ce qui s’est déroulé.&lt;/p&gt;
&lt;img class=&quot;&quot; width=&quot;100%&quot; alt=&quot;Syscall&quot; src=&quot;/assets/images/virtualization/programme33.png&quot; /&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Ainsi s’achève la première partie de notre épopée dans la Virtualisation, vous avez l’intuition de ce qui se passe dans un ordinateur physique.&lt;/p&gt;
&lt;p&gt;Dans la seconde partie on commencera à esquisser le fonctionnement de la virtualisation elle même.&lt;/p&gt;
&lt;p&gt;Merci de votre lecture ♥️&lt;/p&gt;
</content>
        
    </entry>
</feed>
