Principes Fondamentaux des Systèmes d’Exploita8on
Romain Raveaux
Rôle de l'OS
• Gérer les ressources
– Processeur – Mémoire
– Périphériques
• Les uniformiser
• Les rendre accessible aux applica8ons
Différents types de noyau
• Monolithique : un seul bloc réalisant toutes les fonc8onnalités (ex: Linux)
• Micro-‐noyau : un pe8t noyau et de nombreux serveurs communiquants entre eux (ex: Hurd)
• Systèmes à composants
Le plan de ceNe par8e
• Mul8-‐tâches/processus
– Fork – Execve – Thread
• Communica8on entre tâches/processus
– pipe, signal, mémoire partagée, socket
• Synchronisa8on
– Mutex, sémaphore
Adresses physiques/effec8ves
• En mémoire :
• Instruc8ons (code)
• Données
• Pour faire du mul8tâche robuste, 2 types d'adresses :
• Adresses physiques
• Adresses « effec/ves », rela8ves à l'espace d'adressage courant
• Conversion physique => effec/ve : MMU.
Adresses effec8ves/physiques
• La traduc8on effec8ves => physiques
s'effectue à l'aide de tables de traduc/on, fournie par le système d'exploita8on.
• Sur x86, deux mécanismes se combinent :
– segmenta8on – pagina8on
Pe#t retour sur x86
• Deux modes de fonc8onnement du processeur :
• réel
– disponible depuis le 8086, 20 bits d'adresse, 1Mo RAM
– segmenta8on fixée (segments de 64 Ko)
• protégé
– disponible depuis le 386, 32 bits d'adresse, 4 Go RAM – segmenta8on “custom”
x86 : segmenta#on (1)
• Segments définis par des tables :
• GDT (Global Descriptor Table)
• LDT (Local Descriptor Table)
• Adresse définie par segment:offset, segment étant un sélecteur de segment dans une des tables.
• Les GDT et LDT con8ennent des descripteurs de segments.
Retour à la programma8on système
Les niveaux d’un SE
N1 : Appel système
N2 : bibliothèque standard du C et C++
N2 vers N1
N2 -‐> N1
Du point du vue Processeur et du
point de vue processus
Tables des descripteurs
Zones mémoires d’un processus
Zones mémoires d’un processus
Zones mémoires d’un processus
Thread
• Applica8on = un ou plusieurs flots d'instruc8on
• Processeur = exécute un flot d'instruc8on
• Mul8tâche = illusion d’exécu8on en parallèle
• Thread = un flot d'instruc8on
• Pour passer d'un flot à l'autre : changement de contexte
Thread
• Ges8on des threads : ordonnanceur ou scheduler
• État du thread : prêt, bloqué ou en éxécu8on, en fonc8on des ressources demandées et disponibles.
• Sources de blocage :
• matérielles
• logiques
• virtuelles
• Mécanisme de synchronisa8on logicielle pour protéger les ressources matérielles et logiques.
Thread : Synchronisa#on
• Solu/on : synchroniser
• Protec8on de ressources partagées
• Points de rendez-‐vous temporels
Thread
• Deux types de threads :
– Threads noyau : mode privilégié, dans n'importe quel espace d'adressage. Ex: keventd, kswap,
ksopirqd_CPU0
– Threads u/lisateur : mode u8lisateur, dans un espace d'adressage donné.
Synchronisa#on pour l'u#lisateur
• Sémaphores
– Même principe que les sémaphores noyau – semget(), semctl(), semop() (ipc/sem.c)
• Files de messages
– Mécanisme de synchro et de communica8on – msgget(), msgctl(), msgsnd() (ipc/msg.c)
• Fichiers
– Moyen de communica8on (pipe et fifo) – Moyen de synchro (fcntl)
• Signaux
– Communica8on basique : déclenchement d'une rou8ne dans d'autres processus.
• Mémoire partagée
– Région virtuelle iden8que dans plusieurs espaces d'adressage.
Processus Lourd
Processus Lourd
Processus Lourd
Zombie or not
WAIT
Processus
EXEC : Recouvrement
Processus léger : Thread
Thread Basics
• sta8c void *task_a (void *p_data)
• {
• while(1){
• puts ("Hello world A\n");
• puts ("Hello world A\n");
• sleep(1);
• }
• (void) p_data;
• return NULL;
• }
• int main (void)
• {
• pthread_t ta;
• puts ("main init");
• pthread_create (&ta, NULL, task_a, NULL);
– sleep(10);
• puts ("main end");
• return 0;
• }
Thread Pas de synchronisa8on
• sta8c void *task_b (void *p_data)
• {
• while(1){
• puts ("Hello world B\n");
• puts ("Hello world B\n");
• sleep(1);
• }
• (void) p_data;
• return NULL;
• }
• int main (void)
• {
• pthread_t ta;
• pthread_t tb;
• puts ("main init");
• pthread_create (&ta, NULL, task_a, NULL);
• pthread_create (&tb, NULL, task_b, NULL);
• sleep(10);
• puts ("main end");
• return 0;
• }
Thread Pas de synchronisa8on
• Hello world A
• Hello world A
• Hello world B
• Hello world B
• Hello world A
• Hello world B
• Hello world A
• Hello world B
• ….
Communica8on inter-‐processus
• Pipe()
int filedes[2];
pipe(filedes);
• …
• read(filedes[0],&car,1)
• write(filedes[1],monmsg,strlen(monsg));
Communica8on inter-‐processus
• Mémoire partagée
– Créa8on de la zone mémoire – Récupéra8on de l’iden8fiant
– ANachement à la zone mémoire
• Récupéra8on d’un pointeur sur la zone mémoire
– Détachement de la zone mémoire
• if ((mem_ID = shmget(CLEF, sizeof(Data), 0666
| IPC_CREAT)) < 0)
• {
• perror("shmget");
• exit(1);
• }
• if ((ptr_mem_partagee = shmat(mem_ID, NULL, 0)) == (void*) -‐1)
• {
• perror("shmat");
• exit(1);
• }
• shmdt(ptr_mem_partagee);
Mémoire Partagée
% ipcs –m
−−− Segments de mémoire partagée −−−
clé shmid propriétaire perms octets naNch état
• 0x00000000 1627649 user 640 25600 0
% ipcrm shm 1627649
Synchronisa8on
• Mutex
Les mutex
• Protéger une ressource partagée:
• pthread_mutex_t mutex1 =
PTHREAD_MUTEX_INITIALIZER;
• pthread_mutex_lock( &mutex1 );
• …. Accès à la ressource partagée …
• pthread_mutex_unlock( &mutex1 );
Synchronisa8on
• Sémaphore
Les sémaphores
• sem_t *monsem;
• monsem= sem_open(SEMNAME, O_CREAT|
O_EXCL, 0777, NBTOKEN);
• /* Close the semaphore */
• sem_close(monsem);
• /* Remove the semaphore */
• sem_unlink(SEMNAME);
Les sémaphores
• sem_wait(monsem);
• sem_post(monsem);
Informa8on supplémentaire
Droit
• Rwx = trois bits : 000, 100, 110, 001, ….
• R=lire
• W = écrire
• X = exécuter
• Rwx = moi
• Rwx = le groupe
• Rwx = les restes du monde
• Un fichier = 3 x 3 bits
• chmod 744 toto.txt
Le langage C
• int i =10;
• int *j = NULL;
• j = &i;
• *j : la valeur pointée par j
• &i : adresse de i.
• j : adresse de j.
Les includes u8les
• #include <stdio.h>
• #include <stdlib.h>
• #include <sys/types.h>
• #include <unistd.h>
Nombre aléatoire
• int printalea(){
• int nombre_aleatoire = 0;
• nombre_aleatoire = rand();
• prin‡("%d \n",nombre_aleatoire);
•
• return nombre_aleatoire ;
• }
Dormir
• Sleep(nombre_alea);
• Suspend l’execu8on du programme.
DUP2 et sauvegarde des flux
• #include<stdio.h>
• int main(void)
• {
• int a;
• int pfd[2];
• // backup stdin
• int stdin_bak = dup(0);
• // create pipe and redirect stdin to the pipe end
• pipe(pfd);
• dup2(pfd[0],0);
• // say we're finished with it, clean up and restore stdin
• close(0);
• close(pfd[0]);
• dup2(stdin_bak,0);
• close(stdin_bak);
• // to test it s8ll works, do a getchar
• a = getchar();
• prin‡("%c\n", a);
• return 0;
• }
Références
• Programma8on Système -‐ Maîtrisez les interfaces système avec le langage C sous Linux de Jean-‐Paul GOURRET
• Editeur : Edi8ons ENI; Édi8on :2012
• Simple OS :
– Thomas Petazzoni – Lolut -‐ hNp://lolut.utbm.info
Simple OS
Série complète sur la
construc8on d'un OS simple : SOS. A par8r de ce mois-‐ci
(numéro 62) et pendant 10 ou 11 numéros.