faire de gros devoirs bonjour la vie

 

Système d'ordinateur

gros travail

Titre Programmation Life -Hello's P2P   

Faculté d' informatique professionnelle                

Numéro d'étudiant     120L021215          

Classe    2003010              

Étudiant Min Boyu                  

Instructeur Zheng Guibin                   

École d'informatique et de technologie

mai 2021

Résumé

Cet article présente brièvement le processus hello P2P et le processus O2O ainsi que divers mécanismes d'accompagnement, notamment la relocalisation, l'adresse virtuelle, le cache multi-niveaux, la table de pages multi-niveaux, etc. En écrivant ce devoir, j'ai acquis une compréhension plus approfondie des systèmes informatiques

Mots clés : assemblage ; lien ; gestion du stockage ;. . .                           

Table des matières

Chapitre 1 Présentation.................................................. .................................................. ............ ............ - 4 -

1.1 Introduction à Hello................................................ ........ .................................................................. ....... ........ - 4 -

1.2 Environnement et outils............................................................ ................................................... ................. ........ - 4 -

1.3 Résultats intermédiaires............................................................ .................................................. ................ ........... - 4 -

1.4 Résumé de ce chapitre............................................................ ..................................................... .................. ........... - 4 -

Chapitre 2 Prétraitement........................................................ ....... .................................................................. ...................... - 5 -

2.1 Le concept et la fonction du prétraitement.................................................. ... .................................................. - 5 -

2.2 Commandes de prétraitement sous Ubuntu.................................................. ..... ........................ - 5 -

2.3 Bonjour analyse des résultats du prétraitement........................................... ....... ........................................ - 5 -

2.4 Résumé de ce chapitre............................................................ ..................................................... .................. ........... - 5 -

Chapitre 3 Compilation............................................................ .................................................. ............ ............ - 6 -

3.1 Le concept et la fonction de la compilation.................................................. ... ................................................-6 -

3.2 Commandes pour compiler sous Ubuntu.................................................. .... .......................................-6-

3.3 Analyse des résultats de la compilation Hello.................................. ....... ........................ - 6 -

3.4 Résumé de ce chapitre............................................................ ..................................................... .................. ........... - 6 -

Chapitre 4 Compilation............................................................ .................................................. ............ ............ - 7 -

4.1 Le concept et la fonction de l'assemblage.................................................. ..... ............................................-7 -

4.2 Commandes à assembler sous Ubuntu.................................................. ...... ...........................................-7-

4.3 Format elfe cible déplaçable.................................................. ................................................... - 7 -

4.4 Analyse des résultats Hello.o.................................................. ...... ........................................... - 7 -

4.5 Résumé de ce chapitre............................................................ ..................................................... .................. ........... - 7 -

Chapitre 5 Liens........................................................ ....... .................................................................. ........ ................ - 8 -

5.1 Le concept et la fonction des liens.................................................. ... ............................................ - 8 -

5.2 Liaison des commandes sous Ubuntu.................................................. ..... ................................ - 8 -

5.3 Format du fichier objet exécutable bonjour............................................ .. ........................ - 8 -

5.4 L'espace d'adressage virtuel de Hello.................................................. ..... ...................................... - 8 -

5.5 Analyse du processus de relocalisation des liens.................................................. .... .................................... - 8 -

5.6 bonjour le processus d'exécution.................................................. ........ ........................................ - 8 -

5.7 Analyse de lien dynamique Hello.................................................. ................................................... - 8 -

5.8 Résumé de ce chapitre............................................................ ..................................................... .................. ........... - 9 -

Chapitre 6 bonjour la gestion des processus................................................ ..... ............................................ - dix -

6.1 Le concept et le rôle du processus.................................................. ... .............................................. - dix -

6.2 Décrire brièvement la fonction et le processus de traitement de Shell-bash............................................... .. - dix -

6.3 Processus de création du processus Hello's fork.................................................. .... ......................... - dix -

6.4 Processus exécutif de Hello.................................................. .................................................. - 10 -

6.5 Exécution du processus Bonjour.................................. ........ ......................................... - dix -

6.6 Exception de Hello et traitement du signal............................................... .... .............................. - dix -

6.7 Résumé de ce chapitre............................................................ ..................................................... .................. ......... - 10 -

Chapitre 7 bonjour la gestion du stockage.................................................. ....... ................................. - 11 -

7.1 Espace d'adressage mémoire de Hello.................................................. ..... ...................... - 11 -

7.2 Gestion des segments de conversion d'adresse logique Intel en adresse linéaire .......... .- 11 -

7.3 Conversion de l'adresse linéaire de Hello en adresse physique - gestion des pages........................................ ...... - 11 -

7.4 Conversion VA en PA prise en charge par TLB et table de pages à quatre niveaux.......................................... ....... ...... - 11 -

7.5 Accès à la mémoire physique pris en charge par le cache à trois niveaux.................................. ...................... - 11 -

7.6 Mappage de la mémoire lors du bonjour des forks de processus.................................. ... ...................... - 11 -

7.7 Mappage de la mémoire lors de l'exécution du processus hello............................................... ... ........................ - 11 -

7.8 Traitement des défauts de page et des interruptions de défaut de page........................................... .... ................................ - 11 -

7.9 Gestion dynamique de l'allocation de stockage.................................................. ..................................................... .. - 11 -

7.10 Résumé de ce chapitre.................................................. ..................................................... .................. ....... - 12 -

Chapitre 8 bonjour la gestion des E/S.................................................. . .................................................. - 13 -

8.1 Méthode de gestion des périphériques Linux IO.................................................. ...... ........................ - 13 -

8.2 Brève description de l'interface IO Unix et de ses fonctions............................................ ................................. - 13 -

8.3 Analyse de l'implémentation de printf.................................................. ..................................................... .. - 13 -

8.4 Analyse de l'implémentation de getchar.................................................. ..................................................... .. - 13 -

8.5 Résumé de ce chapitre............................................................ ..................................................... .................. ......... - 13 -

en conclusion................................................ .................................................. ............ ........................ - 14 -

annexe................................................. .................................................................. ............... ........................ - 15 -

références................................................................ . .................................................................. .............. ................. - 16 -

Chapitre 1 Aperçu

1.1 Introduction à Bonjour

Sur la base des aveux de Hello, en utilisant la terminologie des systèmes informatiques, décrivez brièvement l'ensemble du processus du P2P de Hello, 020.

 Tout d'abord, écrivez hello.c en utilisant un langage de haut niveau (langage C) via un éditeur de documents, puis compilez-le avec gcc. Après les étapes de hello.i, hello.s et hello.o, il devient finalement le fichier déplaçable. programme exécutable de hello.o, puis les bibliothèques statiques ou dynamiques sont liées par ld, et enfin un programme complet est formé. Lorsque le programme est ouvert, le shell bash crée d'abord un processus enfant, puis utilise la fonction execve() pour permettre au processus enfant d'exécuter le programme, formant ainsi un processus. Ce qui précède est du P2P.

Pour devenir un processus, vous devez charger le programme dans l'espace d'adressage virtuel, puis commencer à exécuter le code du segment de code. À ce stade, la CPU alloue des tranches de temps au fichier d'exécution hello, exécute le flux de contrôle logique et exécute séquentiellement des opérations telles que la récupération d'instructions, le décodage, l'exécution, les opérations de mémoire et la réécriture. De plus, pendant le processus d'exécution, la gestion du stockage et la MMU récupèrent les données requises du disque ou de la mémoire via le cache à trois niveaux L1, L2, L3 et la table de pages à plusieurs niveaux, et les extraient conformément aux instructions de code via le Système d'E/S. Lorsque le programme se termine, bash appelle le gestionnaire sigchld pour recycler le processus enfant, libérer la mémoire et supprimer la structure de données liée au programme en cours d'exécution. De zéro, jusqu'à ce qu'il soit finalement recyclé, c'est l'O2O de bonjour.

Logiciels : virtualbox, éditeur de texte vim, bashshell, edb

1.3 Résultats intermédiaires

Hello.i : fichier prétraité

Hello.s : Après compilation, le fichier écrit en code assembleur

Hello.o : Après assemblage, un fichier écrit en code machine

Bonjour : le fichier exécutable lié

1.4 Résumé de ce chapitre

Au début de cet article, je présente brièvement la vie de hello.

Chapitre 2 Prétraitement

2.1 Concept et rôle du prétraitement

Le prétraitement fait généralement référence au processus précédant la génération du code binaire lorsque le code source du programme est traduit en code cible. En règle générale, le texte du code source du programme est traité par un préprocesseur et les résultats sont ensuite compilés par le cœur du compilateur. Ce processus n'analyse pas le code source du programme, mais il divise ou traite le code source en unités spécifiques - (dans la terminologie C/C++) jetons de prétraitement (jetons de prétraitement) utilisés pour prendre en charge les fonctionnalités du langage (telles que l'appel de macro C/C++). ).

2.2 Commandes de prétraitement sous Ubuntu

gcc -E bonjour.c -o bonjour.i

2.3 Bonjour analyse des résultats du prétraitement

Ajoutez la bibliothèque d'inclusion : stdio.h unistd.h stdlib.h

Commentaires omis

2.4 Résumé de ce chapitre

Ce chapitre présente le concept et le rôle du prétraitement et le redirige vers hello.i pour la navigation.

Chapitre 3 Compilation

3.1 Le concept et la fonction de la compilation

Hello.i est toujours écrit en langage C, qui ne peut pas être exécuté par l'ordinateur, il doit donc être converti en langage de niveau inférieur, il doit donc être compilé pour convertir .i en .s et devenir un langage assembleur de niveau inférieur .

3.2 Commandes pour compiler sous Ubuntu

gcc -S bonjour.i -o bonjour.s

3.3 Analyse des résultats de la compilation de Hello

3.3.1 : Opérations relationnelles

déplacement %edi, -20(%rbp)

cmpl $4, -20(%rbp)

Ces deux étapes correspondent à if(argc!=4), et la valeur de edi est exactement la valeur de argc.

3.3.2 : Fonction

fuite .LC0(%rip), %rdi

      appeler puts@PLT

      mouvement $1, %edi

      appeler exit@PLT

      rdi est utilisé comme paramètre de puts(), correspondant à printf("Usage: Hello student number, name, seconds!\n");

      edi est utilisé comme paramètre de sortie, correspondant à exit(1)

3.3.3 : Affectation

.L2 :

      mouvement $0, -4(%rbp)

      Correspond à l'opération d'affectation de i à 0 dans for(i=0;i<8;i++)

3.3.4 : Opération relationnelle, saut

      .L3 :

      cmpl $7, -4(%rbp)

             Correspond à l'opération de comparaison de i et 8 dans for(i=0;i<8;i++)

3.3.5 : Fonction

      movq -32(%rbp), %rax

      ajouter 16 $, %rax

      movq (%rax), %rdx

      movq -32(%rbp), %rax

      ajouter 8 $, %rax

      movq (%rax), %rax

      movq %rax, %rsi

              fuite .LC1(%rip), %rdi

              Le code ci-dessus correspond à

      printf("Bonjour %s %s\n",argv[1],argv[2]);argv est un tableau de pointeurs de caractères, chaque bit occupe 8 octets, le premier movq -32(%rbp), %rax; addq 16 $, %rax fait du contenu de rax l'adresse de argv[2], donc movq (%rax), %rdx signifie retirer le contenu de rax et l'envoyer à rdx. À ce stade, le contenu de rdx est argv[ 2], de même, le contenu de rsi est argv[1] et le contenu de rdi est "Bonjour %s %s\n", les trois sont exécutés en tant que paramètres de l'appel suivant printf@PLT

3.3.6 : Fonctionnement des fonctions

      movq -32(%rbp), %rax

      ajouter 24 $, %rax

      movq (%rax), %rax

      movq %rax, %rdi

      call  atoi@PLT

      rdi est argv[3], qui est passé dans atio() en tant que paramètre, converti en entier et stocké dans eax pour la transmission.

3.3.7 : Fonction

      déplacement %eax, %edi

      appeler sleep@PLT

      rdi en entrée, exécutez sleep();

3.3.8 : Opérations arithmétiques

      ajouter $1, -4(%rbp)

      Correspond à i++ ;

3.3.9 : Fonction

      appelez getchar@PLT

      Exécutez getchar();

3.3.10

      mouvement $0, %eax

      C'est le retour 0 ;

3.4 Résumé de ce chapitre

Afin de permettre à l'ordinateur de s'exécuter, hello.i est ensuite transformé en hello.s , qui est transformé en un langage assembleur de niveau inférieur.

Chapitre 4 Compilation

4.1 Concept et fonction de l'assemblage

Concept : Assembler des fichiers en langage assembleur pour générer des fichiers cibles.o. Chaque fichier source correspond à un fichier cible. Autrement dit, convertir le code du langage assembleur en code machine, c'est le travail effectué par l'assembleur.

Fonction : Générer du code machine qu'un ordinateur peut lire

4.2 Commandes à assembler sous Ubuntu

gcc -c bonjour.s -o bonjour.o

4.3 Format elfe cible relocalisable

La section .rela.text dans la figure ci-dessus stocke exactement les informations de relocalisation. offset représente le décalage depuis le début du segment de code qui doit être déplacé. Les 4 octets d'informations supérieurs représentent l'index du symbole dans .symtab. Les 4 octets d'informations les plus élevés représentent l'index du symbole dans .symtab. 4 octets indiquent le type de relocalisation et type indique le type de relocalisation. Par exemple, R-X86_64_PC32 ci-dessus est un adressage relatif et addend est l'addend.

4.4 Analyse des résultats de Hello.o

Le langage machine et le langage assembleur ont pour la plupart une correspondance biunivoque. Seules la position relative des variables de rbp et la méthode de référence des fonctions sont différentes.

Transfert de branche : en langage machine, il passe directement à une certaine adresse, tandis qu'en langage assembleur, il passe, par exemple, à .L1.

mnémonique.

Appel de fonction : le langage machine passe à l'instruction d'appel suivante (car il n'est pas lié, l'adresse relative est définie sur 0 par défaut, c'est donc le RIP logique), tandis que le langage assembleur suit directement le nom de la fonction.

Utilisation de variables globales : comme les appels de fonction, le langage machine utilise toujours rip+adresse de décalage relative, tandis que le langage assembleur utilise rip+nom de segment.

4.5 Résumé de ce chapitre

Ce chapitre analyse brièvement la relation et la différence entre le langage machine non lié et le code assembleur.

Lien du chapitre 5

5.1 Le concept et la fonction des liens

Concept : L'éditeur de liens associe chaque référence de symbole à une définition de symbole définie, puis fusionne plusieurs sections de code et sections de données distinctes en une seule section. Déplace les symboles de leurs positions relatives dans le fichier .o vers leurs emplacements de mémoire absolus finaux dans l'exécutable. Mettez à jour toutes les références à ces symboles avec leurs nouvelles positions.

Fonction : L'éditeur de liens (ld) fusionne le fichier relocalisable de hello et le fichier séparé précompilé printf.o utilisé dans la bibliothèque standard C tel que la fonction printf en un seul fichier. Le fichier fusionné est destiné au fichier exécutable hello

5.2 Commandes liées sous Ubuntu

Ld -o bonjour -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o bonjour.o /usr/lib/x86_64-linux-gnu/libc.so /usr/lib/x86_64-linux-gnu/crtn.o

5.3 Format du fichier cible exécutable bonjour

Sous la colonne Nom se trouve la taille du segment et la colonne Adresse est l'adresse de départ.

L'image ci-dessous montre les en-têtes du programme

5.4 L'espace d'adressage virtuel de Hello

Dans le Datadump, vous pouvez voir l'adresse 0x400000, qui correspond au caractère .ELF. Elle correspond à l'adresse de début du premier segment LOAD dans les en-têtes du programme, indiquant où le programme commence son exécution.

PHDR : table d'entête du programme

INTERP : L'interpréteur qui doit être appelé avant l'exécution du programme

LOAD : code objet du programme et informations constantes

DYNAMIC : Informations utilisées par l'éditeur de liens dynamique

REMARQUE : : Informations auxiliaires

GNU_EH_FRAME : Enregistrer les informations sur les exceptions

GNU_STACK : informations d'autorisation requises pour utiliser la pile système

GNU_RELRO : emplacement où les informations en lecture seule sont enregistrées après la relocalisation

5.5 Analyse du processus de relocalisation des liens

objdump -d -r hello analyse la différence entre hello et hello.o et explique le processus de liaison.

En combinaison avec le projet de relocalisation de hello.o, analysez comment il est relocalisé dans hello.

Par rapport à hello.o, l'emplacement d'origine qui doit être déplacé devient directement une adresse virtuelle. Le code hello.o suivant est obtenu par objdump -d -r hello.o.

Bonjour:

Bonjour.o

Évidemment, 1c dans hello.o est marqué comme nécessitant une relocalisation, et les adresses qui n'ont pas été déplacées sont toutes par défaut à 0. Dans Hello, puisqu'elle a été liée, l'adresse virtuelle est écrite directement. Il en va de même pour l’appel de fonction puts() ci-dessous.

Processus de relocalisation : 1c est un adressage absolu, directement

Bonjour

Bonjour.o

Le type est la relocalisation de la table PLT. Après plusieurs mappages, PLT[0] est l'adresse exit(). Les adresses de hello.o qui n'ont pas été déplacées sont toutes à 0 par défaut.

Idem ci-dessus pour les futurs déménagements

5.6 bonjour le processus d'exécution

( Le format suivant est organisé par vous-même et supprimé lors de l'édition )

  1. Jmpq *%r12 (c'est-à-dire l'adresse de départ de _start)
  2. Appelq *0x2ed2(%rip)
  3. Appelle bonjour !.plt+0x70

Remarque : 3 est un appel qui se produit lorsque le nombre de paramètres n'est pas 4 et que l'utilisation est directement imprimée et quittée.

4.callq 0x4010a0 L'instruction hello est imprimée à ce moment

5.appelq 0x4010c0

6.appelq 0x4010e0

7.callq 0x4010b0 exécute getchar()

8.callq libc-2.31.so!exit exécute la sortie (0)

Utilisez edb pour exécuter hello, décrivant tous les processus depuis le chargement de hello vers _start, jusqu'à l'appel de main et la fin du programme. Veuillez lister les noms ou adresses de programme de chaque sous-programme appelé et sauté.

5.7 Bonjour analyse de lien dynamique

Lorsqu'un programme appelle une fonction définie par une bibliothèque partagée, comme le compilateur ne peut pas prédire quelle sera l'adresse de la fonction à ce moment-là, le système de compilation fournit une méthode de liaison retardée pour reporter la liaison de l'adresse du processus jusqu'à la première fois. lorsque la procédure est appelée. L'adresse de la fonction est résolue grâce à la coopération du GOT et de la table de liaison des procédures PLT. Au moment du chargement, l'éditeur de liens dynamique déplace chaque entrée du GOT afin qu'elle contienne l'adresse absolue correcte, et chaque fonction du PLT est chargée d'appeler une fonction différente. Ensuite, en observant edb, vous pouvez trouver les modifications dans la section .got.plt après dl_init.
Tout d'abord, vous pouvez observer le contenu de la section .got.plt dans elf (la marque blanche sur l'image est la première adresse de la table plt)

Avant d'exécuter .dl_init :

Après avoir exécuté dl_init;

On voit qu'après initialisation, il était initialement 00. . L'emplacement est déplacé vers l'adresse de la fonction dans la bibliothèque de liens dynamiques

5.8 Résumé de ce chapitre

Liez le programme hello, complétez la résolution et la relocalisation des symboles, et faites-en un programme exécutable.

Chapitre 6 bonjour la gestion des processus

6.1 Concept et rôle du processus

Concept : Le processus est une activité en cours d'exécution d'un programme dans un ordinateur sur un certain ensemble de données. Il s'agit de l'unité de base de l'allocation et de la planification des ressources dans le système et de la base de la structure du système d'exploitation.

Fonction : dans les premières architectures informatiques orientées processus, le processus était l'entité d'exécution de base du programme ; dans l'architecture informatique contemporaine orientée thread, le processus était le conteneur du thread. Un programme est une description d'instructions, de données et de leur organisation, et un processus est l'entité du programme.

6.2 Décrire brièvement le fonctionnement et le processus de traitement de Shell-bash

Fonction : Shell-bash est un interpréteur de langage de commandes et un programme d'interface entre l'utilisateur et le noyau Linux. Nous pouvons saisir des commandes dans le shell puis les transmettre au noyau Linux.

Flux de traitement : Tout d'abord, bash déterminera si la commande que nous entrons est une commande interne. Si tel est le cas, exécutez-la immédiatement. Sinon, commencez par créer un processus enfant, laissez le processus enfant ouvrir le fichier programme dans le répertoire spécifié et exécutez le programme. .

6.3 Processus de création du processus Hello's fork

Le shell crée des processus enfants à l'aide de la fonction fork. Le processus enfant nouvellement créé est presque, mais pas entièrement, identique au processus parent. Le processus enfant obtient la même copie de l'espace d'adressage virtuel au niveau utilisateur du processus parent, y compris les segments de code et de données, le tas, la pile partagée et la pile utilisateur. Le processus enfant obtient également une copie identique de tous les descripteurs de fichiers ouverts que le processus parent, mais leurs PID sont différents. Après avoir entré la commande pour exécuter le programme hello, le shell commence à analyser la ligne de commande. Après avoir déterminé que hello n'est pas une commande intégrée, le shell appelle la fonction fork pour créer un processus enfant pour exécuter le programme hello.

6.4 Processus exécutif de Hello

Une fois que le shell a utilisé fork pour créer le processus enfant (utilisez setpgid(0,0) pour le placer dans un groupe de processus différent du processus parent), utilisez ensuite la fonction execve dans le processus enfant. La fonction execve charge et exécute le programme contenu dans le fichier exécutable hello dans le processus en cours, en remplaçant le programme actuel par le programme hello. Le chargement et l'exécution de hello nécessitent les étapes suivantes :

1. Supprimez la zone utilisateur existante. Supprime la structure de zone qui existe déjà dans la partie utilisateur de l'adresse virtuelle du processus actuel.

2. Cartographiez les zones privées. Créez de nouvelles structures de zones pour les zones de code, de données, de bss et de pile du nouveau programme. Toutes ces nouvelles zones sont privées et copient sur écriture (c'est le contenu du chapitre 9 Mémoire virtuelle). Les zones de code et de données sont mappées aux zones .text et .data dans le fichier hello. La zone bss est demandée avec des zéros binaires et est mappée sur un fichier anonyme dont la taille est incluse dans hello. Les zones de pile et de tas nécessitent également des zéros binaires et ont une longueur initiale de zéro.

3. Cartographiez la zone partagée. Si le programme hello est lié à des objets partagés, alors ces objets sont liés dynamiquement à ce programme puis mappés à la zone partagée dans l'espace d'adressage virtuel de l'utilisateur.

4. Réglez le compteur de programme. Définit le compteur de programme dans le contexte de processus actuel pour qu'il pointe vers le point d'entrée de la région de code. La prochaine fois que ce processus sera planifié, il démarrera son exécution à partir de ce point d’entrée.

execve ne renvoie -1 que lorsque le chargement échoue, sinon il ne renvoie pas.

6.5 Bonjour exécution du processus

En combinaison avec des informations de contexte de processus et des tranches de temps de processus, le processus de planification de processus, la conversion du mode utilisateur et du mode principal, etc. sont expliqués.

Le contrôle passe d’un processus à un autre via un changement de contexte. Chaque période de temps pendant laquelle un processus exécute une partie de son flux de contrôle est appelée tranche de temps de processus. Lorsque la tranche de temps hello est saisie, le code dans hello commence à être exécuté. Une fois le temps de cette période écoulé, le processus hello n'occupe plus de ressources telles que le CPU, mais stocke les informations du processus à ce moment (telles que la valeur du registre à ce moment) dans la mémoire principale. , le contrôle est renvoyé au noyau et le noyau exécute d'autres processus. Lorsque la tranche de temps bonjour revient, il retire la valeur du registre de la mémoire, la restaure dans le état après la dernière exécution, et continue l'exécution. Il s'agit d'un changement de contexte.

Dans le même temps, compte tenu de l'existence d'exceptions, si l'utilisateur entre manuellement ctrl-z, le processus hello recevra le signal sigtstp et le contrôle sera renvoyé au noyau pour exécuter la fonction de gestion des exceptions.

6.6 Bonjour exception et traitement du signal

Lorsque ctrl-z est enfoncé, le processus reçoit le signal sigtstp, rend le contrôle au noyau et appelle le gestionnaire d'exceptions. Par défaut, le processus hello sera suspendu. À ce moment, le processus bashshell waitfg() s'arrête, donc vous peut continuer à saisir d'autres commandes.Lors de la saisie Lors de l'exécution de la commande fg, bash envoie le signal sigcont au processus enfant, et le processus bash exécute waitfg(), donc le processus hello est exécuté au premier plan.

6.7 Résumé de ce chapitre

Bonjour, dans ce chapitre, j'ai réalisé un saut qualitatif du programme au processus et analysé ce processus et les opérations de gestion des exceptions qui l'accompagnent.

Chapitre 7 Bonjour Gestion du stockage

7.1 Bonjour espace d'adressage mémoire

L'adresse logique fait référence à l'adresse de décalage liée au segment générée par le programme, également appelée adresse absolue. En bonjour, il s'agit de l'adresse de décalage de chaque partie du segment.

Adresse linéaire : couche intermédiaire entre la traduction de l'adresse logique et de l'adresse physique. En mode protégé de la CPU, l'adresse logique dans le composant segmenté est l'adresse de décalage dans le segment, puis l'ajout de l'adresse de base du segment est appelée adresse linéaire. C'est-à-dire l'adresse de la mémoire virtuelle dans hello.

Adresse virtuelle : lorsque le processeur ne dispose pas d'un mécanisme de pagination, l'adresse linéaire est utilisée comme adresse physique finale ; si elle dispose d'un mécanisme de pagination, l'adresse linéaire est appelée adresse virtuelle. Le hello de ce gros travail s'exécute dans l'environnement matériel d'un ordinateur portable personnel, et il dispose évidemment d'un mécanisme de pagination, donc l'adresse virtuelle du programme hello est équivalente à l'adresse linéaire.

L'adresse physique est l'adresse absolue de l'unité mémoire. Dans le programme hello, c'est l'adresse obtenue après traduction de l'adresse de la mémoire virtuelle.

7.2 Gestion des segments de conversion d'adresse logique Intel en adresse linéaire

L'adresse logique se compose d'un sélecteur de segment et d'un décalage, et l'adresse linéaire se compose de la première adresse du segment et du décalage dans l'adresse logique. Parmi eux, l'adresse de tête de segment est stockée dans le descripteur de segment. Le descripteur de segment est stocké dans la table des descripteurs, qui est la GDT (table de descripteurs globale) ou LDT (table de descripteurs locaux). Lors de la conversion, recherchez d'abord l'adresse de base du LDT de hello dans GDT. L'adresse de base plus le décalage est l'adresse linéaire.

7.3 Conversion d'adresse linéaire en adresse physique de Hello - gestion des pages

       Une adresse linéaire, généralement une adresse virtuelle, peut être divisée en deux parties : VPN et VPO. Le VPN comprend deux parties : PTEI et PTET. PTEI peut indexer le groupe d'entrées correspondant dans PTE, puis utiliser PTET pour comparer et trouver l'entrée correspondante. . L'entrée contient les informations de restriction de référence de mémoire et le numéro de page physique. Le numéro de page physique et le VPO peuvent être combinés pour former une adresse physique et terminer la transformation.

Conversion 7,4 VA en PA prise en charge par TLB et table de pages à quatre niveaux

       La MMU (Storage Management Unit) recherche d'abord le PTE correspondant au VPN dans le TLB. S'il le trouve, elle peut directement obtenir le PPN et le combiner avec le VPO pour former une adresse physique. S'il n'est pas trouvé, le PTEA est obtenu via PTBR (registre d'adresses de base de table de pages), et le PTE correspondant est trouvé dans la mémoire et renvoyé. D'une part, il est combiné avec VPO pour obtenir l'adresse physique, et d'autre part , la table TLB est mise à jour.

      

La figure ci-dessus est un exemple de table de pages de deuxième niveau. Il en va de même pour une table de pages de quatrième niveau.

La partie VPN de l'adresse virtuelle contient l'adresse de décalage dans la table de pages à chaque niveau, adressage niveau par niveau, jusqu'à ce que le PPN soit obtenu dans la table de pages de quatrième niveau, et enfin que le PA soit obtenu.

7.5 Accès à la mémoire physique pris en charge par un cache à trois niveaux

Après avoir obtenu l'adresse physique de la MMU, recherchez-la d'abord dans le cache L1. Divisez l'adresse physique en index de groupe, balise et décalage pour la rechercher dans le cache. Si elle est trouvée, transmettez la valeur directement au processeur, sinon continuez à partir de l'étape suivante. Recherchez dans le cache de premier niveau jusqu'à ce que la mémoire principale soit atteinte.

7.6 Mappage de la mémoire lors des forks du processus Hello

Créez d’abord une copie intacte des tables mm_struct, vm_area_struct et page du processus actuel. Chaque page des deux processus est marquée comme en lecture seule. Chaque structure de zone (vm_area_struct) dans les deux processus est marquée comme copie privée sur écriture (COW). Lors du retour dans un nouveau processus,le nouveau processus a la même mémoire virtuelle que le processus appelant.Les opérations d'écriture ultérieures créent de nouvelles pages via le mécanisme de copie sur écriture.

7.7 Mappage de la mémoire lors de l'exécution du processus Hello

Supprimer la zone utilisateur existante

Créer une nouvelle structure de zones

Les données de code et d'initialisation sont mappées sur les zones .text et .data (fournies par le fichier cible)

.bss et pile mappés sur des fichiers anonymes

Réglez le PC pour qu'il pointe vers le point d'entrée de la zone de code

Linux échange les pages de code et de données selon les besoins

7.8 Traitement des défauts de page et des interruptions de défaut de page

       Défaut : Si le bit valide de l'entrée dans la table des pages du processus hello est 0, un défaut de page se produit, c'est-à-dire que les données correspondant à l'adresse virtuelle ne sont pas chargées dans la mémoire.

       Traitement : le processus génère une erreur de page et le contrôle est renvoyé au noyau. Le noyau utilise une certaine page de la mémoire comme page de sacrifice, la remplace par les données à lire, laisse un certain PTE pointer vers l'emplacement mémoire remplacé. , puis continue d'exécuter le processus hello.

7.9 Gestion dynamique de l'allocation de stockage

Printf appellera malloc . Veuillez décrire brièvement les méthodes et stratégies de base de la gestion dynamique de la mémoire.

L'allocateur gère le tas sous la forme d'un ensemble de blocs de différentes tailles, chacun étant soit alloué, soit libre. Les allocateurs sont principalement divisés en allocateurs explicites et allocateurs implicites.

Stratégie : liste libre explicite et liste libre implicite.

Liste libre implicite : connexion implicite via le champ size de l'en-tête. L'allocateur peut indirectement parcourir l'ensemble des blocs libres en parcourant tous les blocs du tas. Une liste implicite doublement chaînée peut être implémentée en ajoutant un pied. Lors de la recherche de blocs libres, vous pouvez utiliser des stratégies d'allocation telles que la première adaptation, l'adaptation suivante, la meilleure adaptation et l'adaptation de séparation ; lors de l'allocation de blocs libres, si le bloc est grand et qu'il n'est pas possible d'en trouver un plus approprié, vous pouvez le diviser ; Les blocs de libération doivent être fusionnés avec des blocs libres adjacents selon quatre situations.

Liste chaînée gratuite explicite : gère et alloue les blocs libres via une certaine structure de données au lieu de gérer les blocs alloués.

7.10 Résumé de ce chapitre

       Ce chapitre se concentre sur l'analyse du processus de gestion du stockage du processus hello.

Chapitre 8 Bonjour la gestion des E/S

8.1 Méthode de gestion des périphériques Linux IO

Modélisation des équipements : documentation

1. Fichiers ordinaires : fichiers contenant des données arbitraires.

2. Répertoire : un fichier contenant un ensemble de liens, chaque lien mappant un nom de fichier à un fichier

3. Socket : un fichier utilisé pour communiquer avec un autre processus sur un réseau

4. Canal nommé

5. Liens symboliques

6. Dispositifs de caractères et de blocage

Gestion des appareils : interface unix io

1. Ouvrir et fermer des fichiers

2. Lire et écrire des fichiers

3. Changer l'emplacement du fichier actuel

8.2 Décrire brièvement l'interface Unix IO et ses fonctions

La façon dont Linux mappe les périphériques aux fichiers permet au noyau Unix d'introduire une interface d'application simple de bas niveau.

Comme les fonctions suivantes, ce sont des appels système.

1. Ouvrez le fichier int open(char *filename, int flags, mode_t mode);

Renvoie un petit entier non négatif, le descripteur. Utilisez des descripteurs pour identifier les fichiers. Chaque processus dispose de trois fichiers ouverts : entrée standard ( 0 ), sortie standard ( 1 ) et erreur standard ( 2 ). Retour : nouveau descripteur de fichier en cas de succès, -1 si une erreur se produit

flags : Comment le processus a l'intention d'accéder au fichier

Contient les options suivantes

O_RDONLY : lecture seule     O_WRONLY : écriture uniquement     O_RDWR : lecture et écriture

O_CREAT : Si le fichier n'existe pas, créez-le

O_TRUNC : Tronquer si le fichier existe déjà

O_APPEND : pour chaque opération d'écriture, définissez k à la fin du fichier

Remarque : Il peut également s'agir d'un ou plusieurs masques de bits ou

mode : Spécifie les bits d'autorisation d'accès du nouveau fichier

2. Modifiez l'emplacement actuel du fichier. Décalage d'octets depuis le début du fichier. Le noyau du système maintient une position de fichier k, commençant à 0 pour chaque fichier ouvert. L'application exécute la recherche, définit la position actuelle k et modifie explicitement la position actuelle du fichier en appelant la fonction lseek.

3. Lisez et écrivez des fichiers.

Opération de lecture : copie n octets du fichier vers la mémoire, en commençant par la position actuelle du fichier k et en augmentant k jusqu'à k+n. Pour un fichier d'une taille de m octets, lorsque k>=m, l'opération de lecture déclenche une Conditions EOF de.

Opération d'écriture : copiez n octets de la mémoire vers le fichier, k est mis à jour en k+n

ssize_t read(int fd, void *buf, size_t n);

Retour : Le nombre d'octets lus en cas de succès, 0 si EOF, -1 si une erreur se produit.

ssize_t write(int fd, const void *buf, size_t n);

Retour : nombre d'octets écrits en cas de succès, -1 si une erreur se produit

4. Fermez le fichier : Le noyau libère la structure de données créée lors de l'ouverture du fichier et restaure le descripteur dans le pool de descripteurs. Le processus ferme un fichier ouvert en appelant la fonction close. C'est une erreur de fermer un descripteur déjà fermé.

int close(int fd); Retour : 0 en cas de succès, -1 si une erreur se produit.

8.3 Analyse de l'implémentation de printf

int printf(const char *fmt, ...)

{

int je;

char buf[256];

    va_list arg = (va_list)((char*)(&fmt) + 4);

    je = vsprintf(buf, fmt, arg);

    écrire(buf, je);

    je reviens;

}

Par exemple, prenons printf ( "hello %c",a )

Buf stocke la chaîne à imprimer. fmt est la première adresse de la chaîne "hello %c" . Dans ce cas, arg est le pointeur de a.

int vsprintf(char *buf, const char *fmt, va_list args)

   {

    char* p;

    char tmp[256];

    va_list p_next_arg = args;

  

    pour (p=buf;*fmt;fmt++) {

    si (*fmt != '%') {

    *p++ = *fmt;

    continuer;

    }

  

    fmt++;

  

    commutateur (*fmt) {

    cas 'x' :

    itoa(tmp, *((int*)p_next_arg));

    strcpy(p,tmp);

    p_next_arg += 4 ;

    p += strlen(tmp);

    casser;

    cas 's' :

    casser;

    défaut:

    casser;

    }

    }

  

    retour (p - buf);

   }

Lisez le contenu de fmt caractère par caractère . Si % n'est pas rencontré , copiez les caractères de fmt dans le segment de données avec buf comme première adresse (en utilisant p comme pointeur pour suivre la progression), et le pointeur fmt avance ; si % est rencontré , cela signifie que pour afficher une variable dans un format spécifique, copiez le contenu de arg où pointe le pointeur p actuel, et fmt continue le mouvement précédent. Bouclez l'opération ci-dessus jusqu'à ce que \0 soit rencontré, indiquant que la chaîne a été lue. À ce moment, p pointe vers la fin de la chaîne à afficher, et buf est au début, donc le i renvoyé par soustraction est la longueur de la chaîne. Enfin, écrivez la chaîne avec l'adresse dirigée par buf avec i caractères dans la zone de sortie standard. Dans la fonction d'écriture, définissez le trap: syscall et donnez le contrôle au système. Sous-programme du pilote d'affichage des caractères : de l'ASCII à la bibliothèque de polices pour afficher le vram (en stockant le RVB de chaque pointinformations sur la couleur).

La puce d'affichage lit le vram ligne par ligne en fonction de la fréquence de rafraîchissement et transmet chaque point ( composant RVB ) à l'écran LCD via la ligne de signal .

8.4 Analyse de l'implémentation de getchar

Exception asynchrone - traitement des interruptions clavier : sous-programme de traitement des interruptions clavier. Acceptez le code de numérisation de la clé, convertissez-le en code ascii et enregistrez-le dans le tampon du clavier du système. Utilisez le pointeur bb pour prendre des données de type char, laissez le pointeur bb pointer directement vers la première adresse de buf, et enfin vérifiez la valeur de retour de read. Si une erreur de lecture se produit, n = -1 est renvoyé, et enfin EOF est renvoyé ; sinon, cela signifie succès, et bb est renvoyé. le caractère pointé

8.5 Résumé de ce chapitre

       Une exploration plus approfondie des opérations io dans hello, impliquant initialement des appels système

en conclusion

Dans le langage des systèmes informatiques, résumez le processus que bonjour a suivi étape par étape.

Votre compréhension approfondie de la conception et de la mise en œuvre de systèmes informatiques, vos idées innovantes, telles que de nouvelles méthodes de conception et de mise en œuvre.

Hello a été écrit pour la première fois en langage C. Après prétraitement, compilation et assemblage, il est transformé en code machine sous la forme d'une chaîne de 01. L'appel de fonctions dans d'autres bibliothèques (telles que printf) ne peut pas être exécuté sans connaître l'adresse virtuelle exacte . Par conséquent, si vous le liez à nouveau, il devient un programme exécutable.

Lorsque vous ouvrez le fichier hello dans le shell bash, bash lance d'abord un processus enfant, puis exécute le fichier, donc hello devient un processus.

Le code et les données requis pour exécuter le programme hello doivent passer par l'unité de gestion de stockage. Le cache multi-niveaux exquis, la table de pages multi-niveaux, le mécanisme d'adresse virtuelle et le TLB se coordonnent pour rendre la lecture des données rapide et précise, et enregistrer espace!

annexe

Hello.i : fichier prétraité

Hello.s : Après compilation, le fichier écrit en code assembleur

Hello.o : Après assemblage, un fichier écrit en code machine

Bonjour : le fichier exécutable lié

les références

[1] Randal E. Bryant, David R. O'Hallaron. Compréhension approfondie des systèmes informatiques. Machinery Industry Press

[2] ch06-02 Système de hiérarchie de mémoire, Harbin, Institut de technologie de Harbin

[3] ch09-1 Mémoire virtuelle, Harbin, Institut de technologie de Harbin

[4] Luo Ya Jing Feng. Lien dynamique Linux GOT et PLT https://www.cnblogs.com/xingyun/archive/2011/12/10/2283149.html

Je suppose que tu aimes

Origine blog.csdn.net/qq_16198739/article/details/124830131
conseillé
Classement