1. Architecture des machines


    1. Introduction


      1. Structure par couches de l'ordinateur


    2. Architecture des ordinateurs


      1. Représentation des informations


      2. Une INFORMATION est une donnée en arithmétique binaire (0 où 1), au niveau le plus bas de la machine.

      3. Calcul binaire


      4. Addition
        Soustraction
        0 + 0 = 0
        0 - 0 = 0
        1 + 0 = 1
        1 - 0 = 1
        0 + 1 = 1
        0 - 1 = 1 avec retenue 1
        1 + 1 = 0 avec retenue 1
        1 - 1 = 0


      5. Passage binaire en décimal


      6. Pour s'en sortir, il est nécessaire de connaître les principales puissances de 2. Les bits sont indicés de la gauche vers la droite. exemple :

           (110101)2 -> 25 +24 +22 +20 = 53

      7. Passage décimal en binaire


      8. La méthode la plus simple reste la méthode de la division

      9. Représentation des nombres négatifs en binaire


        1. Complément à 1


        2. Il s'agit tout simplement d'inverser la valeur de chaque bit.
          • Avantage : le codage s'éffectue en une seul étape.
          • Inconveniant : l'addition se fait en deux étapes : il faut rajouter la retenue au resultat (si elle existe...)


        3. Complément à 2


        4. principe: On inverse les valeurs de chaque bit puis on rajoute 1.
          • Avantage : l'addition s'éffectue en une seul étape.
          • Inconveniant : le cogade s'éffectue en deux étapes.


    3. Codage de l'information

      1. Codage alphanumérique


      2. Code ASCII


      3. le code ASCII est codé sur 7 bits : 128 caractères possibles.

      4. Code HOLLERITH


      5. Cartes perforées.

      6. Code UNICODE


      7. 16 bits
        => 38885 caractères
        Contient tous les caractères du monde.
        Standard de JAVA.
        http://www.unicode.org


    4. Les nombres réels

      1. 3 représentations possibles


      2. Virgule fixe : toujours le même nombre de chiffres après la virgule

        Couple (numérateur, dénominateur) :
        Avantage : les calculs sont justes.
        Inconvenient : pas de représentation de réels.

        Virgule flottante : c'est le plus utilisé
        Un nombre est représenté par :
        1. le signe S
        2. sa mantisse M
        3. son exposant E

        Normalisation de la représentation
        La mantisse sera dans l'intervalle [ 1,10 [
        La norme IEEE 754 définit la manière de représenter en m´moire les nombres à virgule flottante normalisés
        Les nombres normalisés ont une matisse entre [ 1,10 [. Le seul chiffre à gauche de la virgule sera 1 en binaire. (sauf pour 0)

        3 représentations

        Simple précision sur 32 bits
      3. mantisse sur 23 bits
      4. exposant sur 8 bits
      5. signe 1 bit


      6. Double précision sur 64 bits
      7. mantisse sur 52 bits
      8. exposant sur 11 bits
      9. signe sur 1 bit


      10. Pour faciliter les opérations de comparaison entre exposants, on utitlise des exposants positifs ou nuls.
        => On utilise une représentation avec excès de 127 pour la simple précision. (1023 pour la double précision).

        Représentation d'un nombre IEEE754

        (-1)S.(1+M).2E-127

      11. Exemples


      12. Exemple 1


        S= 1 (bit de poids fort)
        E= 100 0000 1 = 129
        M= 010 0000 0000 0000 0000 = (0,01)2 = (1 * 2-2)10 = (0,25)10
        =>Représentation :
        (-1)1.(1+0,25).2129-127 = (-1)1.(1,25).22 = -1,25 . 22 = -5


        Exemple 2

        (432)10 en IEEE754 ?
        S= 0 car 432>0
        Le reste = 28*1,6875 car 432=256*1,6875
        => E=127+8=135 = 10000111
        => M=0,6875 = 0,5 + 0,1875 = 0,5 + 0,125 + 0,0625 = 2-1 + 2-3 + 2-4 = 0,10110000000000000000000

        => (432)10 = 0100 0011 1101 1000 0000 0000 0000 0000



      13. Logique combinatoire et séquentielle

        1. Algèbre de Boole


        2. Les variables ne prennent que les valeurs 0 ou 1

          1. Les fonctions élémentaires


            1. Les fonctions unaires


            2. identité

              négation : opérateur NON (NOT)

                  

            3. Les fonctions binaires





          2. Les fonctions logiques


          3. Une fonction logique complexe peut se matérialiser par un circuit combinatoire.




        3. Multiplexeur


        4. C'est un circuit combinatoire qui accepte en entrée plusieurs données (signaux logiques), et n'autorise la sortie que d'un seul d'entre eux. (appelé aussi Sélecteur de données).

        5. Démultiplexeur


        6. C'est un circuit combinatoire qui accepte une ligne d'entrée et de nombreuses lignes de sortie.

        7. Codeurs, Décodeur, Transcodeur


        8. decodeur
          fait correspondre à un code en entrée (à n_lignes), une seule sortie active (=1)

          codeur
          à une entrée active (=1), il fait correspondre en sortie un code sur n_lignes.

          transcodeur
          fait correspondre à un code A en entrée un code B en sortie

        9. Horloges


        10. L'ordre d'apparition des variables dans les systèmes logiques peut être important. Pour respecter des relations de séquentialité contraignantes, on utilise des horloges qui assurent la synchronisation temporelle.
          Une horloge est un système logique qui émet régulièrement une suite d'impulsions. Il se peut que plusieurs évènements se produisent durant la même impulsion. On réduit donc le cycle d'horloge grâce à un circuit de retardement.




        11. Circuits Séquentiels


        12. Les Circuits Combinatoires sont des circuits idéaux. Il n'y a pas de délais, et pas de rétroaction (i.e pas de retour dans les entrées et les sorties).
          Les Circuits Séquentiels possedent des rétroactions et les signaux de sortie ne dépendent pas uniquement des entrées mais aussi de leurs séquences.













        13. Bascules


          1. Bascule RS





          2. Bascule JK


          3. Ne présente plus d'indétermination quand R=S=1




          4. Bascule D


          5. Le cas R=S=1 est résolu en faisant en sorte qu'il ne se présente jamais.




            D est une mémoire de 1 bit, ce bit mémorisé étant à tout moment disponible sur la sortie.
            La mémorisation prend effet dès qu'une impulsion arrive de l'horloge.


            Variantes des bascules D

          6. LATCH
            mémorisation au top de l'horloge.





          7. FLIP-FLOP

          8. pour des raisons de précision, les flip-flop mémorisent selon les transitions, c'est-à-dire les passages de 0 à 1 (phases montantes) ou de 1 à 0 (phases descendantes).





      14. Les Registres

      15. Un registre est un assemblage de cellules de base qui jouent un rôle de cellules mémoires capables de conserver une information binaire sur leur sortie.

        2 types de registres

        Les registres à cellules non interconnectées, qui servent pour le stockage des données.





        Les registres à décallage : la sortie d'une cellule mé:moire est reliée à l'entrée de la suivante.





      16. Les mémoires

      17. C'est un dispositif capable d'enregistrer, conserver, et restituer des données.

        HIERARCHIE

        On peut les classer selon certaines caracteristiques :

      18. capacité
      19. temps d'accès
      20. coût par bit






      21. ANTEMEMOIRE

        C'est la mémoire cache dans le microprocesseur
        coût élevé
        capacité faible
        temps d'accès très faible

        Tampon entre le microprocesseur et la mémoire centrale.


        MEMOIRE CENTRALE

        C'est l'organe principal de rangement des informations utilisées.
        coût relativement bon marché.
        temps d'accès supérieur à l'antemémoire.


        MEMOIRE TAMPON

        Accélère les transferts de données entre la mémoire centrale et la mémoire de masse.

        MEMOIRE DE MASSE

        Concerne les périphériques de stockage :
      22. disques
      23. cartouches
      24. bandes...



      25. La mémoire centrale

      26. Y sont stockées les informations que l'on utilise et une partie du systè du systè d'exploitation.
        On accède aux données par leurs adresses.
        accès direct ou accès aléatoire appelé RAM : Random Access Memory
        par opposition à ROM : Read Only Memory

        On distingue deux types de RAM:
        SRAM : Statique : un point mémoire = 1 bascule : très rapide.
        DRAM : Dynamique : nécéssite un rafraîchissement : moins rapide.


      27. Le processeur

      28. C'est une structure qui contient divers circuits qui éffectuent des opérations logiques et arithmétiques. C'est aussi la partie de l'ordinateur qui exécute les opérations indiquées par les instructions.
        C'est l'Unité de Commande (UC) qui pilote le processeur en lui envoyant, par exemple, un certain nombre de commandes à exécuter. En réponse, le processeur peut envoyer des informations concernant la commande (résultat, retenue,etc...).
        Il contient plusieurs éléments dont l'UAL (Unité Arithmétique et Logique), et plusieurs registres.

        ATTENTION : Ne pas confondre le microprocesseur qui est lui-même un processeur associé à une UC (i.e c'est une unité de traitement complet).


      29. L'unité arithmétique et logique(UAL)

      30. Unité combinatoire permettant de réaliser plusieurs fonctions sur un couple d'entrées.
        les fonctions arithmétiques +,-,...
        les fonctions logiques ET, OU,...





        A et B : Données d'entrées sur n-bits
        F : Sortie sur n-bits
        Cin : retenue entrante
        Cout : retenue sortante
        Fonction : sur le bit, indique une des 2k fonctions possibles.

        Exemple de fonctions sur 3 bits S2 S1 S0





        L'UAL est constitué en général de 4 bits qui ont le rôle de flags :
        V : permet de détecter un dépassement (overflow) pour la rprésentation d u résultat.
        Z : permet de détecter les résultats nuls.
        S :permet de détecter le signe du résultat.
        C : la retenue sortante (Carry).


      31. Le décaleur

      32. Effectue différents décalages.
        Le type de décalage est donné par un nom de commande.





        1. Décalages possibles


        a3 a2 a1 a0
        à droite
        à gauche
        LOGIQUES
        0 a3 a2 a1
        a2 a1 a0 0
        ARITHMETIQUES
        a3 a3 a2 a1
        a3 a1 a0 0
        CIRCULAIRES
        a0 a3 a2 a1
        a2 a1 a0 a3
        CIRCULAIRES avec C (retenue)
        C a3 a2 a1
        a2 a1 a0 C




      33. L'unité centrale de traitement(CPU)


      34. C'est l'élément moteur de la machine qui exécute et interprète les instructions du programme.
        • On distingue deux parties:
          • le processeur
          • l'unité de commande(UC)
        L'ensemble CPU + mémoire centrale est appellé l'unité centrale.




      35. l'unité de commande


      36. C'est l'ensemble des dispositifs coordonnant le fonctionnement de l'ordinateur pour lui faire exécuter la suite d'opérations spécifiées dans le programme.
        L'unité de commande dirige le fonctionnement de toutes les autres unités : processeur, mémoire, E/S grâce à des signaux de cadence (horloge) et des commandes.
          Fonctionnement:
        1. l'UC va chercher une instruction en mémoire centrale en envoyant une adresse et une commande.
        2. l'instruction lui est transféré.
        3. l'UC décode l'instruction et détermine la suite d'opérations à effectuer.
        4. l'UC cherche les données à traiter et les transfère vers le processeur.
        5. la suite d'opérations est utilisée par l'UC pour générer les signaux nécessaires au processeur pour exécuter l'instruction.
        6. Les données en sortie du processeur sont transférées en mémoire.
        Les dispositifs intervenant dans ce processus sont:
        1. le Compteur Ordinal (CO):registre contenant l'adresse en mémoire où est stockée l'instruction
        2. le Registre Instruction (RI):reçoit l'instruction à exécuter
        3. le Décodeur:détermine l'opération à effectuer
        4. le Séquenceur:génère les signaux de commande
        5. l'Horloge:permet la synchronisation.



        Légende:
        1 :Le CO transfère l'adresse de l'instruction vers le Registre Adresse(RA).
        2 :La mémoire transfère l'instruction vers le Registre Mot(RM).
        3 :L'instruction est envoy&eacue;e au Registre Instruction(RI).
        4 :L'adresse de l'opérande est envoyée dans le RA.
        4' :Le code de l'opération est envoyé au décodeur.
        5 :Le décodeur détermine le type d'opération et le transmet au séquenceur.
        6 :Le séquenceur fait incrémenter le CO.

        A :Le séquenceur envoie des signaux à la mémoirepour lire l'opérande à l'adresse stockée dans le RA et la faire parvenir dans le RM.
        B :Transfert du contenu du RM vers le processeur entant que données externes.
        C :L'opération est effectuée via les mots de commandes du séquenceur.


        Synchronisation des opérations

        Les circuits qui synchronisent et controlent toutes les opérations de l'ordinateur sont dans l'UC.
        Le cycle de base (cycle machine) est généré par l'horloge. Un cycle instruction (=cycle recherche +cycle exécution) dépend du type d'opération et peut s'étendre sur plusieurs cycles machines.



        Séquenceur:automate générant les signaux de commande nécessaires pour actionner et contrôler les unités participant à l'exécution d'une instruction.




    5. Présentation du système d'exploitation



      1. Introduction
        1. Définition:


        2. Un ordinateur:c'est un ensemble de composants d'E/S, la CPU...Le matériel est utilisé par le logiciel.
          3 types de logiciels:
            -logiciel d'application (utilisable par l'utilisateur...)
            -logiciel de développement (qui construit les logiciels d'application)
            -logiciel d'exploitation
          Le système d'exploitation (SE) permet de s'affranchir de la gestion des périphériques par exemple, de la mémoire et des ressources en général. Le SE est l'intermédiaire entre la machine et l'utilisateur.


          Les logiciels de développement ainsi que le SE constituent une machine virtuelle débarassée des contraintes matérielles.
          Le SE coordonne toutes les tâces nécessaires au bon fonctionnement de l'ensemble des composants matériels. Il assure la gestion des ressources disponibles. Il permet la communication entre l'utilisateur et la machine de façon plus ou moins conviviale grâce à une interface adaptée.

        3. Historique


        4. les débuts (1945-1955)

          ENIAC
            
        5. 20 tonnes, 160 m2
            
        6. calculateur unique : une équipe pour tout faire
            
        7. pas de mémoire
            
        8. un programme à la fois
            
        9. méthode de chargement des données : cartes perforées.

        10. transistors (1955-1965)

          Invention de la mémoire
            
        11. industrialisation et construction
            
        12. programmation :
          écriture des cartes par le programmeur
          chargement des cartes compilateur (par l'opérateur)
          chargement des cartes programme
          création du code intermédiaire : l'ASSEMBLAGE
          chargement des cartes assembleur
          création des codes machine
          exécution du programme.
          Problème : à chaque erreur, le programmeur doit faire un listing de l'image mémoire. Cela entraine une perte de temps.
          Solution :
        13. traitement par lots (bacth processing) : On regroupe et on exécute ensemble les travaux similaires.
        14. moniteur résident : enchaine automatiquement les travaux : création d'un nouveau type de cartes qui donnera des instructions au moniteur (charger, exécuter,...)
          Le moniteur est l'ancêtre des systèmes d'exploitation. (la mémoire est d'ailleurs découpée en deux parties : moniteur et utilisateur.

        15. VSLI et multiprogrammation (1965-1980)
        16. Circuits intégrés :
        17. réduction des coûts
        18. évolution rapide
        19. vente aux entreprises
        20. Les disques magnétiques
          Multiprogrammation : plusieurs programmes en mémoire; si le programme en cours d'exécution demande une opération d'entrée/sortie (va voir le disque dur, par exemple...), alors un autre programme s'exécute en même temps;


        21. UNIX


        22. Le SE UNIX est écrit dans un langage de haut niveau:le C. Il comprend une interface simple mais puissante:le shell. Ce système est multiutilisateur et multitâche. UNIX comprend également un système de fichiers hiérarchiques et cache complètement l'architecture de la machine à l'utilisateur.

          1. Points forts:

          2.   -ouverture par la diffusion des sources
              -langage de haut niveau
              -facilité de communication inter-système
              -langage de commande puissant
              -interface graphique X11
              -multiutilisateurs
              -parallélisme.

          3. Points faibles:
          4.   -sécurité
              -fragilité du système de gestion de fichiers
              -gestion des interruptions:pas de temps réel.

        23. Achitecture d'UNIX

        24. C'est une architecture en couches.





            -les utilisateurs communiquent avec la couche la plus haute.
            -le programmeur en fonction de ses besoins, va utiliser les couches plus ou moins profondes.
            -on peut utiliser chaque couche sans savoir ce qui se passe dans les couches inférieures.
            -plus une application est écrite dans une couche haute, plus elle sera portable.
            -si la rapidité est plus importante que la portabilité, il vaut mieux utiliser les couches les plus basses.

        25. Achitecture du noyau






      2. Le système de gestion des fichiers (SGF)


      3. C'est un outil de manipulation des fichiers et de la structure d'arborescence sur disque. Il permet sous UNIX de conserver la pérénnité des informations vitales du système: tous les objets importants (mémoire, terminaux, périphériques,...) y sont référencés.
        De plus, il permet d'utiliser les fichiers de manière transparente en ce qui concerne les problèmes d'accès(partage, droits,...)

        1. Qu'est-ce qu'un fichier ?


        2. C'est une unité de base.
          C'est l'unité logique de base du SGF.
          Les fichiers ne sont pas typés :
          Un fichier UNIX est une suite d'octets (finis).
          Il est matérialisé sur le disque par une inode et des blocs disque.
          INODE : contient toutes les informations nécéssaires pour reconnaître les fichiers.
          Une inode définit le fichier par:
        3. le nom du propriétaire
        4. le nom du groupe du propriétaire
        5. le type de fichier
        6. les droits d'accès
        7. la date du dernier accès
        8. la date de dernière modification de l'inode
        9. la taille du fichier
        10. les adresses des blocs disque contenant le fichier.


        11. Différents types de fichiers


        12. Deux grandes familles :
          Standard
          tout ce qui est manipulé et créé par les utilisateurs (.txt, les exécutables,...)

          Spéciaux
          ne sont manipulables que par le système, ou via le système. Ils gèrent les périphériques, la mémoire... On peut ranger aussi les répertoires. on distingue:

          les fichiers physiques : /dev
              character devices : terminaux(clavier et ecran),imprimantes...
              blocks devices : mémoire, disques, bandes...

          les fichiers logiques :
              liens symboliques
              les pseudo-terminaux
              les sockets
              les tubes

          les catalogues.
              C'est une arborescence organis&eaucte;e comme un graphe acyclique, avec une racine /.
              Le répertoire courant peut être appelé .
              Le répertoire père est appelé ..
              On peut acceder à n'importe quel endroit de l'arborescence par une référence relative ou absolue.

          absolue : on donne tout le chemin pour s'y rendre
          relative : on y va nœud par nœud à partir du point où on est.


        13. Organisation des disques


        14.     Disque logique





        15. Boot Block : utilisé au chargement du système.
        16. Super Block : contient toutes les informations générales du disque logique.
        17. Inode List : table des inodes.

          On peut avoir plusieurs disques logiques sur un disque physique.





          Quand un fichier est en cours d'utilisation, son inode contient trois nouveaux champs :
        18. son statut
        19. son numero de disque logique
        20. son numero d'inode sur le disque.

        21. Adressage des blocs dans les inodes


        22. Le système d'adressage des blocs dans les inodes consiste en 13 adresses de bloc :
        23. 10 à adressage direct sur les blocs de donées
        24. 3 à adressage indirect vers des blocs contenant des adresses à 1,2 ou 3 degré d'indirection.





          Ce système permet d'économiser sur la taille des inodes, tout en permettant un temps d'accès rapide aux petits fichiers(les majoritaires), tout en permettant d'avoir de gros fichiers.

        25. Allocation des inodes d'un disque


        26. Elle est réalisée en recherchant dans la liste des inodes une inode libre. Pour accelerer cette recherche, dans le Super bloc, est géré un tampon d'inodes libres et est conservée l'indice de la première inode libre.

        27. Allocation des blocs-disques


        28. Pour allouer plus facilement, on les a chaînés. Ce chainage est réalisé ar blocs d'adresses pour accelerer les accès et profiter du buffer-cache. Il existe un bloc d'adresses dans le Super bloc qui est utilisé par l'allocateur de blocs.


      4. Le Buffer Cache

        1. Définition


        2. C'est un ensemble de structures de données et d'algorithmes qui permettent de minimiser le nombre d'accès disque.
          Le buffer cache a un rôle très important:
          -les disques sont très lents par rapport à la CPU, donc un noyau se chargeant des Entrées/Sorties serait trop lent et surtout l'unité de traitement serait utilisée à un trop faible pourcentage. Pour réduire les accès disque :
          on bufferise les commandes d'écriture et de lecture et on fait un accès disque uniquement pour une quantité de données raisonnable.
          on écrit des données uniquement lorsqu'elles ne sont plus modifiées.


        3. Avantages et inconvénients


          1. Avantages
          2. Accès uniforme au disque : le noyau interagit uniquement avec le buffer cache, quelles que soient les données.
            Utilisation des Entrées/Sorties plus simple pour l'utilisateur.
            Réduction du trafic disque donc augmentation des ressources disponibles (ne pas trop réduire la taille de la mémoire centrale à cause des tampons).
            protection contre les écritures concurrentes.

          3. Inconvénients
          L'écriture différée occasionne la perte de données en mémoire an cas de crash machine. Les données non encore écrites sont perdues.
          Le buffer cache nécéssite une recopie (de la zone utilisateur au cache, et inversement) pour toute Entrée/Sortie. Si ces tranferts sont nombreux, cela ralentit les Entrées/Sorties.

        4. Structures de données


        5. Statut des blocs cache du buffer cache
          Verrouillé : accès réservé à un processus.
          Valide : données contenues dans le bloc valide.
          A écrire : données à écrire sur un disque avant de réallouer le bloc.
          Actif : le noyau est en train de lire ou d'écrire.
          Attendre : un processus attend que ce bloc soit libéré


        6. La bibliothèque standard C


          1. Les descripteurs de fichiers


          2. Les fichiers sont de type FILE, définis dans la bibliothèque stdio.h. C'est une structure contenant tout ce qui est nécessaire (les informations) à la manipulation d'un fichier ouvert.
            Toutes les fonctions de manipulation de fichiers prennent comme premier argument une variable de type FILE (plus exactement un pointeur sur une variable).

            Il existe 3 descripteurs prédéfinis :

            • stdin : entrée standard (par défaut le clavier)
            • stdout : sortie standard (par défaut l'écran)
            • stderr : sortie d'erreur standard (par défaut l'écran)

          3. Ouverture de fichier


          4. FILE fopen(const char * filename, const char * type)

            • filename : référence relative ou absolue du fichier à ouvrir.
            • type : mode d'ouverture du fichier :
              r : ouverture en lecture en DEBUT de fichier
              w : ouverture en écriture en DEBUT de fichier (avec écrasement)
              a : ouverture en écriture en FIN de fichier (ajoint)
            exemple

            FILE *f;
            f=fopen ("/home/usr/note.txt","r");

            ouvrir le fichier nommé /home/usr/note.txt en lecture en début de fichier.

            r+, w+, a+ : même mode que ci-dessus, mais avec ECRITURE et LECTURE.

            La fonction renvoie un descripteur de fichier si elle s'est exécutée correctement, ou sinon renvoie NULL.

          5. Écriture/Lecture non formaté


          6. Le contenu d'une zone mémoire est recopié tel quel dans le fichier.
            => avantage : rapidité
            => inconvénient : données illisibles si le type est inconnu.

          7. int fwrite(void * add, size_t ta, size_t nbobjets, FILE * f)

          8. écrit nbobjets de taille ta situé à l'adresse add dans le fichier f.

            exemple

            int n[3];
            fwrite (n,sizeof(int),2,f);

            copie les deux premières cases du tableau n.

            exemple

                 char c;
                 FILE * f;
                 
                 f=fopen("fichier.txt","w+");
                 getchar (c);
            
                 while(c != 'q')
                   {
                      fwrite(&c,sizeof(char),1,f);
            	  getchar (c);
                   }
            

            fwrite renvoie 0 en cas d'erreur.

          9. int fread(void * add, size_t ta, size_t nbobjets, FILE * f)

          10. lit nobjets de taille ta dans le fichier f et les range à l'adresse mémoire add.

            Si on essaye de lire au delà du fichier, fread renvoie 0.

            exemple

                 int n[2];
                 fread(n,sizeof(int),2,f);
            
          11. Accès séquentiel


          12. Fait partie de deux types d'accès aux données :
          13. séquentiel (bandes)
            les informations sont traitées dans l'ordre où elles apparaissent.
          14. direct (disque)
            On se place directement à l'endroit où se trouve l'information.
          15. En C, l'accès est séquentiel mais avec la possibilité de se placer où on veut.

          16. Manipulation du pointeur de fichier


          17. C'est un entier qui permet de spécifier où se fera la prochaine opération de lecture/écriture.
            On peut le manipuler avec :

          18. int fseek(FILE * f, long pos, int direction);

            SEEK_SET : placement sur l'octet pos
            SEEK_CUR : positionnement pos octets apr`s la position courante.
            SEEK_END : placement pos octets après la fin du fichier.

            exemple

            fseek(f, 5, SEEK_SET) : on se place sur le 5ème de f.
            fseek(f, 3, SEEK_CUR) : on se place sur le 8ème de f.
            fseek(f, -2, SEEK_END) : on se place sur à deux octets avant la fin.

          19. int ftell(FILE * f) : retourne la position du pointeur du fichier.

            exemple

                 fseek(f, 0, SEEK_END);
                 printf("taille du fichier=%d", ftell(f));
            
          20. void rewind(FILE * f) : idem à fseek(f, 0, SEEK_SET);

          21. int fclose(FILE * f) : fermeture de fichier.
            Ferme le fichier, libère le tampon qui lui a été alloué, libère le descripteur.

        7. Appels système du SGF


        8. Ce sont les systèmes d'entrées/sorties de bas niveaux (gérés par le noyau).
          Les différents appels système :
          open/event
          read/write
          fseek : déplacement de pointeurs de fichier
          dup/dup2 : copie d'ouverture de fichier.
          close


          1. open


          2. int open(char * f, int mode, int permis);
            f : nom du fichier
            mode : mode d'ouverture
            O_RDONLY
            O_WRONLY
            O_RDWR
            O_APPEND
            O_CREAT
            O_EXCL
            permis : positionne les droits du fichier.

            exemple

                 open("f", O_RDWR | O_CREAT, 066);
            

            table de gestion de fichiers



            Déroulement interne d'un open:
            1. Le système détermine l'inode du fichier à ouvrir.
            2. Soit l'inode est dans la table des inodes en mémoire, soit elle n'y est pas, le système alloue alors une variable entrée et recopie l'inode du disque.
            3. Vérification des droits d'accès.
            4. Allocation d'une entrée dans la table des fichiers ouverts, positionnement du curseur de lecture/écriture.
            5. Allocation d'une place dans le tableau des descripteurs.
            6. Envoi au processus du numero de descripteur.


          3. creat


          4. int creat(char * f, int permis);

            Déroulement interne
            Le système détermine l'inode du catalogue où va être créé le fichier.
            S'il n'y a pas d'inode pour le fichier
            -> vérification des droits du catalogue
            -> allocation du nouvel inode
            -> allocation d'une entrée dans la table des inodes en méeacute;moire.
            S'il y a une inode :
            le noyau lit l'inode et vérifie que c'est un fichier ordinaire et que le propriétaire du processus a les droits d'écriture sur ce fichier.
            le système libère les blocs de données, réduit la taille ` 0, mais ne modifie pas les droits.


          5. read


          6. int nbcharlus = read(int d, char * tampon, int nb_à_lire);

            d : numéro du descripteur de fichier dans la table.
            tampon : tableau de caractères où sont placés les caractères lus.
            nb_à_lire : nombre de caractères à lire.
            nbcharlus : nombre de caractères effectivement lus.

            Quand nbcharlus < nb_à_lire, alors fin de fichier. attente.


        9. Les processus


          1. Introduction


          2. C'est un ensemble d'octets en cours d'exécution. C'est ce qui représente l'exécution d'un programme en mémoire.
            Il se compose de:
            1. un espace d'adressage (visible par l'utilisateur)
            2. un BCP : bloc de contrôle de processus:
              1. entrée dans la table des processus
              2. un structure appelée zone U
            Les processus UNIX permettent:
            1. la multiplicité des exécutions : plusieurs processus peuvent être l'exécution d'un même programe
            2. la protection des exécutions : un processus ne peut exécuter que ses propres instructions

            Les processus UNIX communiquent entre eux et avec le reste du système grâce aux appels-systèmes.



            Création d'un processus:
            1. se fait grâce à la commande int fork (void)
            2. fork crée un processus-fils du processus l'ayant appelé, dont le code sera identique
            3. tous les processus sont creés grâce à un fork sauf le processus d'identificateur (PID) 0, qui est creé au démarrage de la machine
            4. le processus de PID 0 va créer un processus de PID 1 qui est l'ancêtre de tous les autres processus
            5. le processus de PID 1 va recueillir tous les processus orphelins.


          3. Format d'un fichier exécutable


          4. Ils ont le format suivant, qui permet au noyau de les transformer en processus:
            1. une entête qui définit l'ensemble du fichier, ses attributs
            2. la taille à allouer en mémoire pour les variables non initialisées
            3. une zone TEXT qui contient le code du programme (en langage machine)
            4. une section DATA (en langage machine) qui contient les données initialisées
            5. données diverses (icones, données pour le débugueur,...)


          5. Chargement d'un exécutable


          6. L'appel système exec permet de charger (ou de changer) l'exécutable d'un programme.



            Lorsqu'on tape une commande en shell, un shell-fils est créé grâce à un fork (étape 1), puis le code de la commande est changé en mémoire par un exec() (étape 2). La commande s'exécute, et, à la fin appel de la fonction exit() (étape 3).

          7. La zone U et la table des processus


          8. Tous les processus ont une entrée dans la table des processus. Mais le noyau alloue pour chaque processus une structure appelée zone U, qui contient des données privées sur le processus, auxquelles le noyau seul a accès. La table des processus permet d'accéder à la table des régions par processus, qui elle accède à la table des régions (en mémoire).

          9. fork et exec d'un point de vue mémoire


          10. Lors d'un fork, le contenu de la table des régions est dupliqué, mais chaque régions est soit partagée ou copié. Lors d'un exec, libération des régions et réallocation de nouvelles régions.



            fork() : on rajoute aux processus existants.



            exec() : on supprime les processus existants.


          11. Le contexte d'un processus


          12. C'est l'ensemble des données qui permettent de reprendre l'exécution d'un processus interrompu.
            Il est composé de:
            1. l'état du processus
            2. son mot d'état:
              1. valeurs des registres actifs
              2. compteur ordinal
            3. les valeurs des variables globales statiques ou dynamiques
            4. l'entrée dans la table des processus
            5. la zone U
            6. les piles USER et SYSTEM
            7. les zones de code et de données
            Quand on change de processus courant, il y a changement du contexte et commutation du mot d'état.

          13. Commutation d'un mot d'état


          14. Pour être exécuté, un programme doit être chargé en mémoire centrale, et ses instructions une à une à l'unité centrale.
            L'unité centrale:
            1. UAL
            2. registres dont registres spécialisés:
              1. accumulateur : reçoit les résultats d'une instruction
              2. registre d'instruction : contient l'instruction en cours
              3. compteur ordinal : adresse de l'instruction en mémoire
              4. registres d'adresse
              5. registres de données
              6. registres d'état:
                1. du processeur
                2. du processus
            Tous ces registres forment le contexte d'unité centrale d'un processus, ou encore son mot d'état.
            Un processus est caractérisé par deux contextes:
            1. le contexte d'unité centrale qui est composé des mêmes données pour tous les processus
            2. le contexte qui dépend du code utilisé
            Pour exécuter un nouveau processus, il faut sauvegarder le mot d'état du processus courant, et charger celui du nouveau processus, c'est la commutation du mot d'état.
            Cette instruction utilise deux adresses:
            1. adresse de sauvegarde du premier mot d'état
            2. adresse de changement du nouveau
            Cette opération est effectuée de façon matérielle et n'est pas interruptible.

          15. Les interruptions


          16. Une interruption, c'est une commutation du mot d'état provoquée par le matériel.
            Ce signal est la conséquence d'un évènement extérieur ou intérieur, il modifie un indicateur régulièrement testé par l'UC.
            Une fois le signal détecté, il faut en déterminer la cause. On utilise pour cela unu indicateur : le vecteur d'interruption.
            Trois grands types d'interruption :
            1. externes (indépendantes du processus) intervention de l'utilisateur, pannes...
            2. déroutement : erreurs internes du processeur, débordement, divisio par zéro, erreur de mémoire...(sauvegarde sur le disque de l'image mémoire : core dumped).
            3. appels-système : demande d'entrée-sortie par exemple
            Selon les machines, un nombre de variables de niveaux d'interruption est utilisé.
            EX : sous UNIX, généralement:



            Si plusieurs niveaux d'interruption se présentent quand le système les consulte, c'est le niveau d'interruption qui va permettre au système de déterminer laquelle il doit traiter en priorité.





          17. Cascade d'interruption


          18. Si, pendant le traitement d'une interruption, un autre interruption se produit, et que ceci se répète, le système ne fait plus progresser les processus, ni les interruptions en cours de traitement.
            On peut retarder ou annuler la prise en charge d'un ou plusieurs niveaux d'interruption.
            C'est le rôle des mécanismes de masquage et de désarmement. Le masquage permet d'ignorer temporairement un niveau d'interruption. Le désarmement rend impossible le traitement d'un niveau d'interruption. Ce dernier ne s'applique pas aux interruptions de type déroutement.

          19. Etat et transitions d'un processus


          20. liste des états:
            1.le processus s'exécute en mode utilisateur
            2.le processus s'exécute en mode noyau
            3.le processus ne s'exécute pas mais il est éligible (= prêt)
            4.le processus est endormi en mémoire centrale
            5.un processus prêt mais en attente de transfert (swap) en mémoire centrale pour le rendre éligible
            6.processus endormi en zone de swap (généralement le disque)
            7.le processus passe du mode noyau au mode utilisateur mais il est préempté (il est prêt mais il est retiré de l'unité de traitement pour que les autres processus puissent s'exécuter)
            8.naissance du processus : ni prêt, ni endormi, c'est l'état initial de tous les processus.
            9.état zombie : juste après un exit, le processus est encore vivant juste le temps pour so père de récupérer les informations le concernant.

            le diagramme d'état:



            explication :
            soit le processus est préempté -> 7, quand le processus préempté est réélu, il repasse directement en mode utilisateur -> 1
            soit l'interruption est due à une E/S, endormissement du processus -> 4, à la fin de l'E/S, une autre interruption est générée, le processus est endormi en mode prêt -> 3
            soit une interruption due à une erreur, terminaison du processus -> 9
            Si un processus se trouve en -> 4, un autre processus a besoin de sa place mémoire, il passe en zone de swap -> 6
            Une fois reçu l'interruption de réveil, il passe en -> 5
            Quand suffisament de mémoire centrale sera libérée, il repassera alors en -> 3

            exemple





            l'ensemble de la mémoirecentrale est occupée par des processus mais le processus le plus prioritaire est en -> 5, il faut libérer donc de la place en -> 3;
            libérer de la mémoire = faire passer des processus de ->3 ou ->4 en ->5 ou ->6, c'est le rôle du swappeur :
            1. il sélectionne le ou les processus les plus appropriés pour un transfert hors mémoire centrale (swapout)
            2. il réalise ce transfert
            3. une fois la place suffisante libérée, le processus qui a provoqué le swapout passe en mémoire centrale (swapin)


          21. La table des processus


          22. Elle se trouve dans la mémoire du noyau et contient toutes les informations auxquelles le noyau doit avoir accès.
            elle contient :
            -état du processus
            -adresse de la zone U
            -adresses : taille et localisation en mémoire (centrale, secondaire)
            -UID : propriétaire du processus
            -PID, PPID : identification du processus et de son père
            -évènement : description de l'évènement qui réveillera le processus quand il est endormi
            -priorités : utilisées par l'ordonnanceur pour sélectionner l'élu parmi les lrocessus prêts
            -vecteur d'interruption : ensemble des signaux reçus mais pas encore traités
            -divers : différents compteurs : temps CPU utilisé...
          23. La zone U


          24. Une unique zone U est accessible à la fois, celle des processus en cours d'exécution:
            Elle contient:
            -pointeur sur la table des processus
            -UID de l'utilisateur, détermine les privilèges du processus, les droits d'accès aux fichiers...
            -compteur de temps utilisé par le processus (user et sstème)
            -erreur, stockage de la dernière erreur rencontrée lors d'un appel système
            -retour, valeur de retour du dernier appel système
            -E/S, contient les structures associées aux E/S
            -"." et "/" répertoire courant et racine
            -limite de la taille des fichiers de la mémoire utilisable
            -umask, masque de création des fichiers

          25. Accès à la table des processus et à la zone U


          26. Pour accéder aux donnée de la table des processus, on utilise la commande ps. Par contre, les informations de la zone U ne sont accessibles que par une réponse du processus lui-même.
            On y accède par différentes commandes :
            1. informations temporelles:
              times (struct tms *buffer)
              remplit la struct pointée par buffer:
              struct tms
              {
              tms_utime; // temps utilisateur tms_stime; //temps système tms_cutime; // temps utilisateur fils tms_cstime; // temps système fils
            2. changement de répertoire :
              chroot (const char *path)
              change le répertoire racine. (définit un nouveau point de départ pour les références absolues).

              chdir (const char *ref)
              change le répertoire courant de travail donc la référence relative.
            3. récupération du PID d'un processus
              getpid () : renvoie le pid du processus appelant
              getppid () : renvoie le pid du père du processus appelant
              getpgrp () : renvoie le pid du groupe du processus appelant
          27. Modification des données de la zone U


            1. tailles limites :
              ulimit (int cmd, ...)
              cmd peut prendre les valeurs suivantes :
              UL_GETFSIZE : retourne la taille maximum des fichiers en blocs
              UL_SETFSIZE : positionne cette valeur avec le deuxième argument
            2. priorité :
              nice (int valeur)
              permet de spécifier la priorité du programme d'exécution du processus, plus la valeur est petite, plus le processus est prioritaire. Seul le superuser peut spécifier une valeur négative.
        10. Ordonnancement des processus


        11. C'est la sélection dans le temps des processus pouvant accéder à une ressource
          Un algorithme d'ordonnancement réalise la sélection de celui qui va obtenir l'autorisation d'utiliser une ressource (UC ou E/S).
          Pour l'UC, notre but est de maximiser le débit et le taux utile de l'UC. Le débit est le nombre moyen de processus exécutés en un temps donné. Le taux utile, c'est la proportion de temps réellement utilisé pour exécuter les processus utilisateurs.
          1. Partage de l'U.C


          2. Il doit être fait entre les processus utilisateurs mais aussi entre les autres tâches du système :
            les E/S, les interruptions...
            De plus, notre algorithme d'ordonnancement devra nous assurer deux choses :
            exclusion mutuelle (une ressource est affectée à un processus à la fois)
            absence de famine (il y a famine si un processus attend pendant un temps indéterminé l'accès à une ressource)
            Pour trouver un algorithme d'ordonnancement, on se base sur deux remarques statistiques du comportement de processus :
            -les processus ont tendance à basculer constamment entre phase d'E/S et phase de calcul sur l'UC.
            -les processus consommant de longues périodes d'UC sont proportionnellement rares.




            Eviter la famine
            Un système qui ne crée pas de famine fournit toujours au processus la ressource demandée après un temps fini.
            Pour les périphériques (les disques), l'ordonnancement peut se faire par une file d'attente (FIFO).
            Pour l'unité centrale, on va utiliser des structures plus complètes de manière à gérer les priorités. On pourra par exemple, permettre à des processus d'éviter la file d'attente. On peut utiliser différentes structures : file, liste, arbre, en fonction de la clé de notre algorithme. (priorité simple...) Cette structure devra nous donner accès à tous les processus éligibles.
            Stratégie globale d'un algo d'ordonnancement :




            Les ordonnancements à court terme doivent être le plus court possible car le processus élu ne va utiliser l'UC que pendant un très court laps de temps.
            -Critère de performance :
            taux d'utilisation de l'UC
            débit
            temps réel d'exécution
            temps d'attente
            temps de réponse
            les critères sont plus ou moins exclusifs, il faudra donc faire une sélection.

          3. Ordonnancement sans préemption


          4. .FCFS : first come first served, peu efficace.
            .SJF : shortest job first, le plus petit en premier, optimal pour le temps d'attente moyen.
            à priorité : l'utilisateur donne à chaque processus une priorité et ils sont activés en fonction de cette priorit&eacue;. Il y a possibilité de famine par les processus les moins prioritaires. La solution, plus le temps passe, plus le processus devient prioritaire.

          5. Algorithmes préemptifs


          6. La préemption, c'est la possibilité qu'à le systè de reprendre une ressource à un processus avant que celui-ci ne l'ait libéé.
            FCFS ne peut être préemptif
            SJF peut l'être : si un processus plus court que celui qui est actif arrive, le processus actif est préempté, et le nouveau s'exécute.
            Le round-robin (tourniquet) , particulièrement adapté aux systèmes à temps partag&eacue;. On va définir un quantum de temps d'utilisation de l'UC. La file des processus éligibles sera une queue circulaire (fifo circulaire). Tout processus nouveau est placé à la fin de la queue.
            Soit le processus actif rend l'UC avant la fin de sa tranche de temps (E/S par exemple), soit il est préempté. Dans les deux cas, il est placé à la fin de la liste.
            Si on a n processus, et q le quantum de temps, chaque processus est assuré d'obtenir le processeur au bout de (n-1)*q secondes au plus -> famine évitée.
            le quantum de temps pose un prolème :
            -si q est trop grand, round-robin revient à FCFS
            -qi q est trop petit, beaucoup de préemption, le nombre de changements de contexte grandit d'où une diminution du taux utile donc processeur n fois moins rapide (pour n processus).
            Une règle empirique est d'utiliser un quantum de temps tel que 80% des processus libérant naturellement l'UC avant l'expiration du quantum.
            Les algorithmes à queues multiples
            On différencie les processus en plusieurs classes de priorité différentes. Pour s&eacuta;lectionner un processus, le scheduler parcourt succéssivement les queues dans l'ordre décroissant des prioritées.
            Un exemple de queues organisées en fonction du contenu des processus :
            -processus systèmes
            -processus interactifs
            -processus gros calcul
            -processus utilisateurs
            Pour qu'un processus utilisateur soit exécuté, il faut que les autres queues soient vides.
            il est possible de réaliser différents algorithmes d'ordonnancement sur les différentes queues :
            un round-robin sur les processus interactifs. un fcfs pour les gros calculs en tâche de fond par exemple.

          7. Multi-level-feedback round-robin Gueues


          8. C'est le système d'ordonnancement des processus sous UNIX : plusieurs files d'attente qui matérialisent différents niveaux de priorité, et à l'intérieur de ces niveaux, on utilise un tourniquet.




            Dans les listes internes au noyau, de simples files d'attente sont utilisées (avec possibilité de passer devant un processus endormi de la même liste).
            Dans les processus utilisateurs, on applique la règle du tourniquet.
            Il faut d'abord calculer une priorité de base qui permet de placer le processus dans la bone file d'attente.
            un processus qui utilise l'UC voit sa priorité augmenter.
            un processus qui libère l'UC pour une E/S ne voit pas sa priorité changer.
            Plus la valeur de la priorité est grande, moins le processus est prioritaire.
            Evolution de la priorité Sous BSD, le scheduler utilise l'équation suivante, tous les 4 clics d'horloge :
            Puserprio = PUSER + (Pcpu/4) + 2Pnice
            Pcpu : estimation du temps passé par le processus sur l'UC.
            Pnice : valeur spécifiée par l'appel à nice, varie entre -20 et +20 (valeur négative réservée au superuser).
            La valeur de Pusrprio augmente avec le temps d'exécution du processus donc plus le processus passe de temps sur l'UC, moins il devient prioritaire.
            Les processus non exécutés deviennent forcément les plus prioritaires au bout d'un temps fini.
            Pour que Pcpu ne soit pas trop pénalisante sur le long terme, Pcpu est attée par la formule suivante :
            Pcpu = ((2*load)/(2*load+n)) * Pcpu + Pnice
            load = nombre moyen de processus actifs pendant une minute.
            Les classes de priorités :
            PSWAR : 0 priorité en cours de swap

            PINOD : 10 priorité en attendant lecture d'information SGF

            PRIBIO : 20 priorité en attente d'E/S disque

            PZERO : 25 priorité limite

            PWAIT : 30 priorité d'attente de base

            PSLEP : 40 priorité d'attente d'un évènement

            PUSER : 50 priorité de base pour les processus utilisateurs.

            L'ordre des priorités est très important. Les processus en attente d'un disque doivent être prioritaires par rapport aux processus en attente d'un buffer, car ils peuvent libérer un buffer.
            Si la priorité était inversée, possibilité d'interblocage ou d'attente très longue.

        12. Aperçu de la programmation systè en C


          1. fork()


          2. wait


          3. exec


          4. exit


          5. les évènements