0% ont trouvé ce document utile (0 vote)
22 vues42 pages

Chapitre 1

Le document traite des systèmes d'exploitation, en se concentrant sur les concepts de programmes, processus et threads. Il explique comment un programme est exécuté, les formats de fichiers exécutables, ainsi que la gestion des processus en mémoire, y compris le changement de contexte. Des exemples de code et des structures de données comme le Program Control Block (PCB) sont également présentés pour illustrer ces concepts.

Transféré par

Youcef Benyahia
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
22 vues42 pages

Chapitre 1

Le document traite des systèmes d'exploitation, en se concentrant sur les concepts de programmes, processus et threads. Il explique comment un programme est exécuté, les formats de fichiers exécutables, ainsi que la gestion des processus en mémoire, y compris le changement de contexte. Des exemples de code et des structures de données comme le Program Control Block (PCB) sont également présentés pour illustrer ces concepts.

Transféré par

Youcef Benyahia
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Cours systèmes

d’exploitation

Chapitre 1: Programmes, Processus,


et Threads
• Contenu
–Programmes
–Processus
–Changement de contexte
–Threads

2
Execution d’un code dynamique
• Une des fonctionnalités les plus basiques d’un
OS est l’exécution et la gestion d’un code
dynamiquement, ex:
– Une ligne de commande sur le terminal
– Une icone doublement cliques sur le bureau
– Des taches exécutées en arrière plan
• Un processus est l’unité de base d’un
programme en exécution

3
Programmes et Processus
Processus
Instance d’un
programme en cours
d’execution stockée
en RAM

Programme
Un fichier
executable sur
une mémoire Relation 1-n entre
secondaire programme et
processus

4
Comment s’execute un programme?
• Quand vous double cliquer sur un *.exe ,
qu’arrive-t-il?

• Quelles informations doit contenir un fichier


*.exe pour lancer un programme ?

5
Formats de programmes
• Les programmes obéissent à un format
spécifique :
– DOS: COM executables (*.com)
– DOS: MZ executables (*.exe)
• Mark Zbikowski exutables, developpeur DOS
– Windows Portable Executable (*.exe)
– Unix/Linux: Executable and Linkable Format (ELF)
– Mac OSX: Mach object file format (Mach-O)

6
test.c
#include <stdio.h>

int big_big_array[10 * 1024 * 1024];


char *a_string = "Hello, World!";
int a_var_with_value = 100;

int main(void) {
big_big_array[0] = 100;
printf("%s\n", a_string);
a_var_with_value += 20;

printf("main is : %p\n", &main);


return 0;
}
7
Format de fichier ELF
• ELF Header
– Contient des informations de
compatibilité
– Point d’entrée du code executable
• Program header table
– Liste tous les segments dans le fichier
– Utilisé pour charger et executer le
programme
• Section header table
– Utilisée par le linker
8
Format de fichier ELF
typedef struct {
1 unsigned char e_ident[EI_NIDENT];
Elf32_Half e_type; ISA ( instruction set
5 Elf32_Half e_machine; architecture)
Elf32_Word e_version;
Elf32_Addr e_entry; Offset du program headers
Elf32_Off e_phoff; • Point d’entrée d’un
Elf32_Off e_shoff; code executable
Offset du section headers
10 Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
De program headers
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
# de section headers
15 Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
} Elf32_Ehdr; 9
ELF Header
$ gcc –g –o test test.c
$ readelf --header test
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x400460
Start of program headers: 64 (bytes into file)
Start of section headers: 5216 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 9
Size of section headers: 64 (bytes)
Number of section headers: 36
Section header string table index: 33 10
Point d’entrée
int main(void) {

printf("main is : %p\n", &main);
return 0;
}
$ gcc -g -o test test.c
$ readelf --headers ./test | grep Entry point'
Entry point address: 0x400460
$ ./test
Hello World!
main is : 0x400544

11
Point d’entrée!= &main
$ ./test • La plupart des compilateurs
Hello World!
main is : 0x400544 inserent des programmes
$ readelf --headers ./test | grep Entry point' avant et après le code
Entry point address: 0x400460 • Ce code s’executent avant et
$ objdump --disassemble –M intel ./test
… après le main()
0000000000400460 <_start>:
400460: 31 ed xor ebp,ebp
400462: 49 89 d1 mov r9,rdx
400465: 5e pop rsi
400466: 48 89 e2 mov rdx,rsp
400469: 48 83 e4 f0 and rsp,0xfffffffffffffff0
40046d: 50 push rax
40046e: 54 push rsp
40046f: 49 c7 c0 20 06 40 00 mov r8,0x400620
400476: 48 c7 c1 90 05 40 00 mov rcx,0x400590
40047d: 48 c7 c7 44 05 40 00 mov rdi,0x400544
400484: e8 c7 ff ff ff call 400450 <__libc_start_main@plt>

12
Sections & Segments
sections multiples
• Sections : sont des bouts de dans un segment
codes et de données Segments
regroupés et liés par le
compilateur
• chaque segment contient une
ou plusieurs sections liés ( ex
: section de code )

13
Sections
• Sections : différentes parties de code et de
données qui composent un programme
• Sections clé:
– .text – Code executable
– .bss – Les variables globales à initializer à 0
– .data, .rodata – données initialisées
– .strtab – Noms des variables et des fonctions

14
Section (Exemple)
Chaine de car → .data
Tableau vide →
.bss
int big_big_array[10*1024*1024];
char *a_string = "Hello, World!";
int a_var_with_value = 0x100;
Variable globale
int main(void) {
initialisée→ .data
big_big_array[0] = 100;
printf("%s\n", a_string);
a_var_with_value += 20;

constante → .rodata
}
Code → .text 15
$ readelf --headers ./test

Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .[Link]-tag .[Link]-id .[Link] .dynsym .dynstr .[Link] .gnu.version_r
.[Link] .[Link] .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame
03 .ctors .dtors .jcr .dynamic .got .[Link] .data .bss
04 .dynamic
05 .[Link]-tag .[Link]-id
06 .eh_frame_hdr
07
08 .ctors .dtors .jcr .dynamic .got

There are 36 section headers, starting at offset 0x1460:
Section Headers:
[Nr] Name Type Address Offset Size ES Flags Link Info Align
[ 0] NULL 00000000 00000000 00000000 00 0 0 0
[ 1] .interp PROGBITS 00400238 00000238 0000001c 00 A 0 0 1
[ 2] .[Link]-tag NOTE 00400254 00000254 00000020 00 A 0 0 4
[ 3] .[Link]-I NOTE 00400274 00000274 00000024 00 A 0 0 4
[ 4] .[Link] GNU_HASH 00400298 00000298 0000001c 00 A 5 0 8
[ 5] .dynsym DYNSYM 004002b8 000002b8 00000078 18 A 6 1 8
[ 6] .dynstr STRTAB 00400330 00000330 00000044 00 A 0 0 1
[ 7] .[Link] VERSYM 00400374 00000374 0000000a 02 A 5 0 2

Program Loader
• Une fonctionnalité système
qui charge un programme
dans la mémoire et crée des Mémoire
process : ESP
Stack
– Place les segments en mémoire
– Charge les librairies nécessaires
– Effectue la relocation en
mémoire Fichier ELF Heap
– Alloue de l’espace pour la pile ELF Header
de contexte .text .bss
.data
– Affecte à l’EIP(instruction .rodata
.rodata EIP
pointer register) le début du .data
.bss .text
programme
17
Program Loader
• La pile est utilisée pour les variables
Mémoire
locales et les appels de fonction
– Sa taille augmente de haut vers le bas Stack

• Le tas est alloué dynamiquement


(malloc/new)
– Sa taille augmente de bas en haut Heap

• Quand les deux structures se croisent, .bss


il n’y a plus de mémoire pour le .rodata
porcess .data
– Le Process va probablement crasher .text

18
• Programs
• Processus
• Changement de contexte
• Threads

19
Les processus en mémoire
• Une fois le programme chargé , le noyeau dois
gérer le nouveau process créé
• Program Control Block (PCB): structure de
données representant un process
– Contient au moins un thread (peut être plus…)
– Garde trace de la mémoire utiliée par le process
• Segments de code
• Segments de données (stack & heap)
– Garde trace de l’éxecution du process
• Valeurs de registre
• EIP ( Instruction Pointer Register )
20
Program Control Block (PCB)
• Structure qui représente un processus en mémoire
• Crée pour chaque proceussus par le loader
• Géréé par le SE

struct task_struct { // Typical Unix PCB


pid t_pid; // process identifier
long state; // state of the process
unsigned int time_slice; //scheduling information
struct task_struct *parent; // this process’s parent
struct list_head children; // this process’s children
struct files_struct *files; // list of open files
struct mm_struct *mm; // address space of this process
};
21
Etats d’un processus
• Le processus passe par plusieurs états
– new: Le processus est créé
– running: Les Instructions sont en cours d’exécution
– waiting: Le processus est en attente d’un événement
– ready: Le processus attend d’être relancé
– terminated: le porcessus a termién son exécution

22
Arboresence de processus
• Tous les processus ont des parents
– i.e. quel processus a lance un autre?
• Si un processus déclenche de nouveaux
processus , ce sont ses enfants
– On créer alors un arbre de processus
• Si un parent termine son execution avant son
enfant , l’enfant devient orphan ( orphelin)
• Si un fils sors avant que le parent execute
wait(), le fils est appelé zombie
23
Arboresence de processus
• init un processus special déclenché par le
noyeau : racine de tous les processus
i ni t
pi d = 1

l ogi n kt hr e add s s hd
pi d = 8415 pi d = 2 pi d = 3028

bas h khe l pe r pdf l us h s s hd


pi d = 8416 pi d = 6 pi d = 200 pi d = 3610

e mac s t cs ch
ps
pi d = 9204 pi d = 4005
pi d = 9298
24
Gestion des processus
• fork() – Crée une copie du processus courant
avec un nouvel espace mémoire
– Sans arguments!
• exec() – Appel système pour changer le
programme cournant
• wait() – appel système pour attendre la fin
d’execution d’un autre processus
• signal() –notification à envoyer vers un autre
processus
25
Gestion des processus
Child Process

pid = fork();
if (pid == 0) main() {
exec(…); …
else }
wait(pid);
pid = 0

pid = fork(); pid = fork();


if (pid == 0) if (pid == 0)
exec(…); exec(…);
else pid = 9418 else
wait(pid); wait(pid);

Original Process 26
Question: que fait ce code?
int child_pid = fork();
if (child_pid == 0) { // I'm the child process
printf("I am process #%d\n", getpid());
return 0;
} else { // I'm the parent process
printf("I am parent of process #%d\n", child_pid);
return 0;
}
27
• Programmes
• Processus
• Changement de contexte
• Threads

28
Changement de contexte
• Changement de context
– Sauvegarde l’état d’un prcocessus avant de passer
vers un autre
– Restore l’état du processus une fois qu’il y
retourne
• Questions :
– Comment enregistrer l’état d’un processus?
– Comment récupérer l’état d’un processus?

29
La pile de processus
• Chaque processus est défini par une pile en
mémoire qui enregistre:
– Ses variables locales
– Les arguments des fonctions
– Les addresses des fonctions
• Sur les processeurs x86:
– ESP (Stack Pointer register) pointe vers la fin de la
pile (la donnée la plus récente)

30
int bar(int a, int b) {
int r = rand();
return a + b - r;
}
stack_exam.c
int foo(int a) {
int x, y;
x = a * 2;
y = a - 7;
return bar(x, y);
}

int main(void) {

foo(12);

}
31
$ gcc -g -fno-stack-protector -m32 -o stack_exam
stack_exam.c
Memory
EBP
$ objdump --disassemble –M intel ./stack_exam
… main()’s main()’s local variables
EIP 804842a: e8 c0 ff ff ff call 80483ef <foo> Frame
804842f: b8 00 00 00 00 mov eax,0x0 ESP 12 Argument to foo()

0x804842f Return addr to main()
080483ef <foo>:
80483ef: 55 push ebp Saved EBP
80483f0: 89 e5 mov ebp, esp
80483f2: 83 ec 28 sub esp, 0x28
80483f5: 8b 45 08 mov eax, [ebp+0x8]
80483f8: 01 c0 add eax, eax 24 x=a*2
80483fa: 89 45 f4 mov [ebp-0xc], eax
80483fd: 8b 45 08 mov eax, [ebp+0x8] 5 y=a-7
8048400: 83 e8 07 sub eax, 0x7
foo()’s
8048403: 89 45 f0 mov [ebp-0x10],eax
Frame
8048406: 8b 45 f0 mov eax, [ebp-0x10]
8048409: 89 44 24 04 mov [esp+0x4],eax
804840d: 8b 45 f4 mov eax, [ebp-0xc]
8048410: 89 04 24 mov [esp], eax
8048413: e8 bc ff ff ff call 80483d4 <bar> 5 2nd arg for bar()
8048418: c9 leave
24 1st arg for bar()
8048419: c3 ret
… 0x8048418 Return addr to foo()
Memory
EBP
… foo()’s local variables
080483d4 <bar>:
foo()’s
EIP 80483d4: 55 push ebp Frame 5 2nd arg for bar()
80483d5: 89 e5 mov ebp, esp
24 1st arg for bar()
80483d7: 83 ec 18 sub esp, 0x18
80483da: e8 31 ff ff ff call 8048310 <rand@plt> ESP 0x8048418 Return addr to foo()
80483df: 89 45 f4 mov [ebp-0xc], eax
Saved EBP
80483e2: 8b 45 0c mov eax, [ebp+0xc]
80483e5: 8b 55 08 mov edx, [ebp+0x8]
80483e8: 01 d0 add eax,edx
bar()’s
80483ea: 2b 45 f4 sub eax, [ebp-0xc]
Frame Some # Result of rand()
80483ed: c9 leave
80483ee: c3 ret

• leave → mov esp, ebp; pop ebp;


• La Valeur retournée est placée dans EAX
33
Changement de contexte
• On a vu que la pile sauvegarde
– Les variables locales
– Les arguments des fonctions
– Les valeurs retournée par els fonctions
– … grosso modo : l’état du processus
• Si on change de pile , on change alors de
processus
– Changement de context : passer d’un ESP à un
autre

34
• Programmes
• Processus
• Changement de contexte
• Threads

35
Problèmes avec les processus
• La creation de nouveau processus est lourde
(i.e. lente)
– Espace mémoire dédié pour chaque nouveau
proceussus
– fork() copie les états d’un parent vers un fils :
Beaucoup d’espace mémoire consommé

36
Threads
• processus légértqui partage le même espace
mémoire que le parent
• Chaque processus dispose d’au moins un thread
• Avantages:
– Espace mémoire partagé
– Economie: se crée plus rapidemnt et le changement
de context est tout aussi rapide
– Mise à l’échelle: Idéal pour des processeurs multi-
cores

37
Processus simple Process avec plusieurs
threads
Process-Level Shared Data Process-Level Shared Data
Global File Global File
Code Code
Data Descriptors Data Descriptors

Registers Stack Registers Registers Registers

Stack Stack Stack

Thread 1
Thread 1 Thread 2 Thread 3
38
Les Threads POIX
• POSIX standard API pour la creation de thread
– IEEE 1003.1c
• L’Implementation est indépendante du
système

39
Pthread API

• pthread_create() – crée un nouveau


thread
• pthread_exit() – termine le thread
courant
• pthread_join() – attend que le thread
passé en parametre se termine
• Pthreads : dispose d’un certain nombre de
mécanismes de synchronisation

40
Pthread : Exemple

41
Processus vs. Threads
• Threads son meilleurs si:
– Besoin de rapidité
– Calcul intensif

• Processus sont Meilleur si :


– Besoin de protection
• Un processus qui plante n’affecte pas les autres
– Besoin de sécurité
• Chaque processus dispose de son propore espace
mémoire sans toucher aux autres
42

Vous aimerez peut-être aussi