18
LU3NI031 — 2021 — Présentation de l'UE OS : Présentations LU3IN031 Archi L3 S6 Franck Wajsburt & Pirouz Bazargan-Sabet pré[email protected] 1 LU3NI031 — 2021 — Présentation de l'UE SoC Un SoC (ordinateur) est composé au minimum d'un processeur pour exécuter le programme, d'une mémoire RAM contenant plusieurs segments d'adresses de l'espace d'adressage du processeur pour : le code du programme ; les données du programme ; et la pile d'exécution. d'une mémoire ROM contenant le code de démarrage du processeur. d'un contrôleur d'entrées-sorties configurable par des registres accessibles par lecture/écriture dans l'espace d'adressage (mais ce n'est pas de la mémoire). d'un bus système routant les requêtes de lecture/écriture du processeur vers les composants gérant les adresses concernées. de lignes d'interruption permettant aux contrôleurs d'entrées-sorties de prévenir de la terminaison d'une commande demandée. 2

OS : Présentations

  • Upload
    others

  • View
    7

  • Download
    0

Embed Size (px)

Citation preview

Page 1: OS : Présentations

LU3NI031 — 2021 — Présentation de l'UE

OS : PrésentationsLU3IN031 Archi L3 S6

Franck Wajsburt & Pirouz Bazargan-Sabet

pré[email protected]

1

LU3NI031 — 2021 — Présentation de l'UE

SoC

Un SoC (ordinateur) est composé au minimum • d'un processeur pour exécuter le programme,• d'une mémoire RAM contenant plusieurs segments d'adresses

de l'espace d'adressage du processeur pour : – le code du programme ;– les données du programme ;– et la pile d'exécution.

• d'une mémoire ROM contenant le code de démarrage du processeur.• d'un contrôleur d'entrées-sorties configurable par des registres accessibles par

lecture/écriture dans l'espace d'adressage (mais ce n'est pas de la mémoire).

• d'un bus système routant les requêtes de lecture/écriture du processeur vers les composants gérant les adresses concernées.

• de lignes d'interruption permettant aux contrôleurs d'entrées-sorties de prévenir de la terminaison d'une commande demandée.

2

Page 2: OS : Présentations

LU3NI031 — 2021 — Présentation de l'UE

SoC minimal

Un cœur MIPSqui exécute le code des programmes sur des

données présentes en mémoire et qui accède aux autres composants par des load/store

Un composant de mémoire morte (ROM)contenant le code de démarrage

Un composant de mémoire vive (RAM)contenant le code du programme, ses données et sa (ou ses) pile(s) d'exécution de fonctions

Un contrôleur de TTY (terminal) qui contrôle le couple écran-clavier, qui peut

envoyer des requêtes d'interruption (IRQ) vers le MIPS (IRQ : Interrupt ReQuest) pour prévenir qu'un

caractère tapé au clavier est en attente d'être lu.

Un bus systèmequi transmet les requêtes de lecture et d'écriture

du MIPS vers les mémoires et vers le TTY

3

périphériqueterminal

MémoireROM MIPS

Bus système

mémoireRAM TTY

IRQ

Système sur Puce minimal

lw sw

Ce schéma est un exemple de SoC minimal mais réaliste, c'est celui qui sera utilisé en TP.SoC nommé almo (utilisé dans le module architecture logicielle et matérielle des ordinateurs)

LU3NI031 — 2021 — Présentation de l'UE

SoC étendu

4

périphériques

MémoireROM MIPS

Bus système

mémoireRAM TTY

IRQ

lw sw

Ce schéma est toujours un exemple de SoC minimal mais avec plus de composants

MIPS ICUTIMER

BDFB

Page 3: OS : Présentations

LU3NI031 — 2021 — Présentation de l'UE

Espace d'adressage du prototypeLes segments représentés ici sont ceux du prototype utilisé en TP.

• L'adresse de boot est 0xBFC00000.Cette adresse est imposée par le MIPS.Le segment fait 0x1000 octets (4 kio)

• L'adresse du TTY est 0xD0200000C'est un segment de 16 octets par TTY.

• ktext et kdata sont les segments utilisés par le noyau du système d'exploitation– ktext commence en 0x80000000

et sa taille est 0x20000 (132 kio)– kdata commence en 0x80020000

et sa taille est 0x3E0000 (~ 4 Mio)• text et data sont les segments de l'application

– text commence en 0x7F400000et sa taille est 0x100000 (1 Mio)

– data commence en 0x7F500000et sa taille est 0xB00000 (~ 11 Mio)ce segment contient les données globales du programme et la ou les piles d'exécutions des fonctions.

5

ROM MIPS

Bus

RAM TTY IRQ

Applications

réservé au noyau

0x00000000

0xFFFFFFFC

0x80000000

0x7FFFFFFF

0xD0200000

0xBFC00000

0x80020000

stack

data

text

boot

TTY

kdata

ktext

0x7F400000

0x7F50000

0x10 * nb TTY

0x1000

0x3E0000

0x200000

0xB00000

0x100000

LU3NI031 — 2021 — Présentation de l'UE

Chaque mémoire gère une ou plusieurs segments d'adresses dans des bancs de mémoire physique(un banc de mémoire est un composant matériel).

Les requêtes contiennent• une adresse sur 32 bits• une commande (read/write)• une donnée sur 32 bits si c'est une écriture • un masque désignant les octets concernés

pour les écritures (bit enable)

Le décodeur sélectionne le banc concerné qui réalise la requête et produit une réponse avec :

• une donnée sur 32 bits (la sélection du ou des octets concernés est faite par le MIPS lui-même).

• une acquittement si c'est une écriture.

Mémoires RAM et ROM

6

ROM MIPS

Bus

RAM TTY IRQ

Contrôleur de bus

banc du segment 2

banc du segment 1

banc du segment 0

Décodeur d'adresse

requête data/inst. du MIPS

réponse data/inst. vers le MIPS

Les mémoires RAM et ROM stockent les instructions et les data des programmes• Les mémoires sont des tableaux d'octets et chaque octet a sa propre adresse• Les mémoires reçoivent des requêtes de lecture (load) ou d'écriture (store) du MIPS .

RAM et ROM sont deux types de mémoire• Le contenu d'une ROM est persistant. ⇒ Elle ne peut pas être écrite par le MIPS• Une RAM peut être lue et écrite ⇒ Son contenu est non significatif au démarrage.

Page 4: OS : Présentations

LU3NI031 — 2021 — Présentation de l'UE

boot

Périphérique (Device)Un périphérique (device en anglais) est un composant matériel qui propose un service spécifique (entrée-sortie, timer, etc.)

• Le TTY est un périphérique d'entrées-sorties texte (écran-clavier)• Les périphériques contiennent des registres de contrôle qui sont placés dans

l'espace d'adressage du MIPS pour qu'il puisse les accéder par load/store• Le TTY contient 4 registres par TTY à partir de l'adresse 0xd0200000 (3 sont utilisés ici)

TTY_WRITE est le registre de sortie vers l'écran du terminal TTYC'est un registre en écriture seule. Pour écrire un caractère à l'écran, il faut écrire son code ASCII dans le registre TTY_WRITE. Le caractère s'affiche là où se trouve le curseur, lequel avance automatiquement.

TTY_STATUS est le registre d'état qui informe de la présence de caractères en attente d'être lu sur le clavier.

C'est un registre en lecture seule qui vaut 0 s'il n'y a pas de caractères en attente et 1 s'il y a au moins un caractère en attente d'être lu.

TTY_READ est le registre d'entrée du clavier C'est un registre en lecture seule.

Il contient le code ASCII du dernier caractère tapé au clavier.

• Il y a autant de jeu de 4 registres que de TTY, ils sont placés à des adresses consécutives : pour 2 TTYs de 0xd0200000 à 0xd020001C

• Notez la présence d'une ligne d'interruption (IRQ) que le TTY active lorsqu'il a un caractère en attente (nous détaillerons son usage au prochain cours)

Attention à ne pas confondre registres du MIPS et registres de périphérique !

7

ROM MIPS

Bus

RAM TTY IRQ

TTY

unused

TTY_READ

TTY_STATUS

TTY_WRITE 0

4

8

C

data

text

stack

devices

kdata

ktext

0xd0200000

adresse du TTY dans l'espaced'adressagedu MIPS pour le prototype utilisé en TP

0xd0200000

0xd0200004

0xd0200008

LU3NI031 — 2021 — Présentation de l'UE

kernel.x

OS

• Boot• Modes d'exécution du MIPS• Composants du noyau et de la libc• Communication entre kernel.x et user.x

8

mode kernel

mode user

User.x

kent

ry

memexceptsyscall

interrupt

threadsklibc

driv

ers

etc.

libc

Page 5: OS : Présentations

LU3NI031 — 2021 — Présentation de l'UE

Espace d'Adresses

Boot du prototype de TP

9

Le prototype que vous allez utiliser :• n'a pas de contrôleur de disque. • n'a pas la possibilité de « découvrir » le matériel

Le processus de boot doit donc être plus simple.• Le simulateur du prototype va prendre en

paramètre les fichiers binaires contenant le noyau et l'application et remplir directement les RAM avec les instructions et les données globales présentes dans ces fichiers.

• Le matériel (adresses et taille des segments de mémoire) et le nombre de périphériques sont mis dans le fichier ldscript et dans des #define du code kernel.

Cela simplifie beaucoup le démarrage et ce n'est toutefois pas irréaliste, c'est ce qui se passe dans les micro-contrôleurs qui sont des SoC intégrant des RAM en technologie flash dont le contenu est persistant comme pour les ROM et dont le matériel est connu au moment de la compilation du programme (p. ex Arduino).

syscallexception

kernel

lw swIRQ

kdataktext

regsdevice

ROM

system libraries (libc,...)

user

spa

ceke

rnel

spa

ce

syst

ème

d'ex

ploi

tatio

n

lw sw

API POSIX

Application utilisateur

stackdatatext

boot

LU3NI031 — 2021 — Présentation de l'UE

Questions

10

Une application s'exécute sur un système d'exploitation

• Quels sont les composants du noyau ?• Comment le noyau lance-t-il l'application ?• Comment l'application appelle-elle le noyau ?• L'application (user.x) et le noyau (kernel.x)

sont 2 exécutables qui communiquent, que doivent-ils avoir en commun ?

• Comment rendre le noyau indépendant des périphériques et du processeur ?Espace d'Adresses

syscallexception

kernel

lw swIRQ

kdataktext

regsdevice

ROM

system libraries (libc,...)

user

spa

ceke

rnel

spa

ce

syst

ème

d'ex

ploi

tatio

n

lw sw

API POSIX

user application

stackdatatext

user.x

kernel.x

Page 6: OS : Présentations

LU3NI031 — 2021 — Présentation de l'UE

Deux modes d'exécution pour le MIPSModes • kernel → tous les droits• Mode user → droits restreints

Pourquoi 2 modes ? on ne peut pas faire confiance à l'application ! • Elle peut casser le matériel en le contrôlant mal• Elle peut accéder à des données protégées en lecture ou en écriture• Elle peut modifier le noyau système d'exploitation

⇒ Le MIPS propose un mode user d'exécution bridé pour l'application et un mode kernel pour le code et les données sensibles.

Le mode user n'accède qu'à une partie de l'espace d'adressage et il ne peut pas exécuter les instructions permettant de changer de mode !

Notez que certains processeurs proposent plus de modes pour restreindre les droits, par exemple un mode pour le code des pilotes de périphériques.

11

LU3NI031 — 2021 — Présentation de l'UE

Partition du MIPS : kernel - user

Partie réservée au noyau• code du noyau • données du noyau• code de boot• registres des contrôleurs

de périphériques• pile(s) du noyau (pas ici)

12

ROM

Bus

URAMKRAM TTY IRQ

0x00000000

0xFFFFFFFC

0x80000000

0x7FFFFFFF

0xD0200000

0xBFC00000

0x80020000

stack

data

text

boot

TTY

kdata

ktext

0x7F400000

0x7F50000

0x10 * nb TTY

0x1000

0x3E0000

0x200000

0xB00000

0x100000

TTY

unused

TTY_READ

TTY_STATUS

TTY_WRITE 048C

Partie pour l'application• code• données globales• pile(s) des fils d'exécution

MIPS

User Kernel

MIPS

GPR$0-$31

C0$0-$31

mtc0

mfc0Registres système

Page 7: OS : Présentations

LU3NI031 — 2021 — Présentation de l'UE

Passage de mode

13

• Le MIPS démarre en mode kernel pour initialiser le matériel et les structures de données du noyau et pour charger une application utilisateur. Dans notre cas, l'application est déjà en mémoire.

• Puis, le MIPS passe en mode user en utilisant l'instruction eret pour exécuter l'application utilisateur.

• Ensuite, le MIPS retourne en mode kernel pour 3 raisons :[S] un appel système après l'exécution de l'instruction syscall[E] une exception après l'exécution d'une instruction erronée[I] une interruption après qu'un composant ait levé un signal IRQ

demandant au noyau de faire une opération.• Ensuite, le MIPS retourne à l'application ou pas…

kernel.x User.x S.E.I

eretPrincipaux registres système impliqués - EPC adresse de retour - CR registre de cause - SR registre status

LU3NI031 — 2021 — Présentation de l'UE

USER

● adresses de 0 à 0x7FFFFFFFuniquement les segment légaux

● instruction syscall pourune demande de service au noyau

● les accès mémoire hors segmentles accès mémoire non alignésla division par 0l'exécution de code erronéle dépassement de capacitéprovoque aussi l'entrée dans kernelce sont les exceptions, la plupartsont fatales (on en revient pas !)

● IRQ : interruptions matérielles

14

Modes du MIPSKERNEL

• Tout l'espace d'adressage

• instruction eret pour sortir du noyau

• Banc de registres protégés (système) $12 c0_sr registre d'état $13 c0_cause cause d'appel du noyau $14 c0_epc adresse de retour

ou de l'instruction fautive $8 c0_bar adresse malformée $15 c0_procid numéro de core $9 c0_count compteur de cycles

• instructions d'accès au registres protégés mtc0 $GPR, $C0 movetoc0 mfc0 $GPR, $C0 movefromc0

Attention il y a 2 bancs de registres distincts

Page 8: OS : Présentations

LU3NI031 — 2021 — Présentation de l'UE

U K

Contenu du Status Register c0_sr ($12)

c0_sr contient les masques des lignes d'interruption et le mode d'exécution.

HWI5 HWI4 HWI3 HWI2 HWI1 HWI0 SWI1 SWI0 0 0 0 UM 0 ERL EXL IE

6 IRQ HARD 2 IRQ SOFT

masques des interruptions (IRQ)

User Mode = 1 en mode USER Error Level = 1 au démarrage et

quand le MIPS est dans un état incohérent Exception Level = 1 à l'entrée dans le noyau

après un syscall, une exception et une IRQ global IRQ enable = 1 quand les interruptions

sont acceptées

ERL

EXL

IE

7 015 8

15

UM

GPR $12

mtc0

mfc0mtc0 $GPR, $12mfc0 $GPR, $12

LU3NI031 — 2021 — Présentation de l'UE

Comportement du registre c0_sr ($12)

Comportement du MIPS• Si UM est à 1: le MIPS est en mode USER• Si IE est à 1: le MIPS autorise les IRQ à interrompre le programme courant

SAUF si ERL ou EXL sont à 1, en effet • Si l'un des bits ERL ou EXL est à 1 alors

le MIPS est en mode KERNEL avec IRQ masquée ∀ l'état de UM et IEValeurs typiques de SR• Lors de l'exécution d'une application USER → 0xFF11• À l'entrée dans le noyau → 0xFF13• Pendant l'exécution d'un syscall → 0xFF01• Pendant l'exécution d'une section critique → 0xFF00

0 0 0 UM 0 ERL EXL IEHWI5 HWI4 HWI3 HWI2 HWI1 HWI0 SWI1 SWI0

7 015 8

16

U K

GPR $12

mtc0

mfc0

Page 9: OS : Présentations

LU3NI031 — 2021 — Présentation de l'UE

U K

GPR $13

mtc0

mfc0

Cause Register c0_cause ($13)

0 0 0 0

15 8

Etat des interruptions (IRQ)

HWI5 HWI4 HWI3 HWI2 HWI1

7 5 2 0

Valeurs de XCODE effectivement utilisés dans cette version du MIPS010 = 0000

2: INT Interruption

410 = 0100

2 : ADEL Adresse illégale en lecture

510 = 0101

2 : ADES Adresse illégale en écriture

610 = 0110

2 : IBE Bus erreur sur accès instruction

710 = 0111

2 : DBE Bus erreur sur accès donnée

810 = 1000

2 : SYS Appel système (SYSCALL)

910 = 1001

2 : BP Point d'arrêt (BREAK)

1010 = 1010

2 : RI Codop illégal

1110 = 1011

2 : CPU Coprocesseur inaccessible

1210 = 1100

2 : OVF Overflow arithmétique

HWI0 SWI1 SWI0 XCODE

17

Le registre CR contient la cause d'entrée dans le noyau (après syscall, except ou irq)

mtc0 $GPR, $13mfc0 $GPR, $13

LU3NI031 — 2021 — Présentation de l'UE

Entrée et sortie du noyau syscall, exception, interruption

c0_sr.EXL ← 1mise à 1 du bit EXL du registre Status Register donc passage en mode kernel sans interruption

c0_cause.xcode ← numéro de causepar exemple 8 si la cause est syscall

EPC ← PC ou PC+4PC adresse de l'instruction courante

pour syscall et exceptionPC+4 adresse suivante pour interruption

PC ← 0x80000180C'est là que se trouve l'entrée du noyau toute cause confondue

18

eret

c0_sr.EXL ← 0mise à 0 du bit EXL du registre Status Register donc passage en mode c0_sr.UM et avec interruption ou pas suivant c0_sr.IEc0_sr.UM = 1 ⇒ mode user

c0_sr.IE = 1 ⇒ int autorisées

PC ← EPCdésigne l'adresse de la prochaine instruction à exécuter

Page 10: OS : Présentations

LU3NI031 — 2021 — Présentation de l'UE

Ce qu'il faut retenir• Le MIPS propose 2 modes d'exécution :

○ un mode kernel avec tous les droits et ○ un mode user avec des droits restreints.

• Dans le mode kernel, le programme peut accéder○ aux registres système via les instructions mtc0 et mfc0 ○ à tout l'espace d'adressage de 0 à 0xFFFFFFFF

• Dans le mode user, le programme ne peut accéder ○ qu'à la moitié de l'espace d'adressage (adresses < 0x80000000)○ ne peut pas utiliser les instructions mtc0 et mfc0, une tentative produit une exception

• Le MIPS démarre en mode kernel et saute dans le mode user avec l'instruction eret• Le noyau est appelé pour 3 raisons :

○ exécution de l'instruction syscall○ une exception due à une erreur du programme (div par 0, violation, etc.)○ une interruption demandée par un contrôleur de périphérique

• Les registres système pour la gestion des appels du noyau sont :○ c0_cause ($12) cause d'appel du noyau défini dans le champ XCODE○ c0_sr ($13) mode d'exécution et les masques d'interruption○ c0_epc ($14) adresse de l'instruction retour ou de l'instruction fautive

19

LU3NI031 — 2021 — Présentation de l'UE

Composants du système d'exploitation● Le point d'entrée : kentry● Les gestionnaires d'évènements → syscall, except. et interrupt.● Abstraction du matériel → cpu (MIPS) et architecture (almo1)● Bibliothèque de fonctions standards noyau : klibc● Bibliothèque de fonctions standards utilisateur : libc

20

Page 11: OS : Présentations

LU3NI031 — 2021 — Présentation de l'UE

Composants du système d'exploitation

21

Espace d'Adresses

syscallexception

kernel

kdataktext

regsdevice

ROM

system libraries (libc,...)

user

spa

ceke

rnel

spa

ce

système d'exploitation

lw sw

user application

stackdatatext

IRQ

excep

harch

kentryklibc

API POSIX

lw swIRQ

kentryentrée du noyau

gestionnaire des appels système

gestionnaired'exception

gestionnaired'interruption

klibc : fonctions standards du noyau

API processeurassembleur

API architecturedrivers...

libc : fonctions standards user

syscall

hcpukinit

entrée du noyauaprès le boot

boot

LU3NI031 — 2021 — Présentation de l'UE 22

Kentry

Espace d'Adresses

syscallexception

kernel

kdataktext

regsdevice

ROM

system libraries (libc,...)

lw sw

user application

stackdatatext

IRQ

excep

harch

kentryklibc

boot

API POSIX

lw swIRQ

syscall

hcpukinit

• Le code de kentry est à l'adresse 0x80000180• Il est nécessairement en assembleur• Il ne modifie aucun registre de l'utilisateur • Il analyse le registre c0_cause

pour savoir quel gestionnaire appeler– gestionnaire de syscall– gestionnaire d'exception– gestionnaire d'interruption

• Le processeur est en mode kernel et les interruptions sont masquées (elles resteront masquées quel que soit la cause, c'est un choix d'implémentation simplificateur)

C'est l'unique porte d'entrée du noyau → Sauf au démarrage où l'on entre dans le noyau par kinit()

Page 12: OS : Présentations

LU3NI031 — 2021 — Présentation de l'UE

func 0

func 1

func 2

func 31

0

1

2

31

syscall_vector

Espace d'Adresses

syscallexception

kernel

kdataktext

regsdevice

ROM

system libraries (libc,...)

lw sw

user application

stackdatatext

IRQ

excep

harch

kentryklibc

boot

API POSIX

lw swIRQ

syscall

hcpukinit

23

gestionnaire de syscall

• C'est encore du code assembleur• On entre dans le gestionnaire avec

– $2 contenant le numéro du service– $4,$5,$6,$7 contenant les arguments

• Dans le noyau, Il existe un tableau de pointeurs de fonctions dont la case n°i contient le pointeur vers la fonctionréalisant le service n°i

– SYSCALL_NR : le nombre de services– syscall_vector[SYSCALL_NR]

• Le gestionnaire fait simplement un appel de fonction– syscall_vector[$2]($4, $5, $6, $7)

• Le noyau ne fait évidemment jamais de syscall, il fait des appels de fonctions directs

Gère les appels système de l'utilisateur après le passage par kentry

LU3NI031 — 2021 — Présentation de l'UE 24

gestionnaire d'exception

Espace d'Adresses

syscallexception

kernel

kdataktext

regsdevice

ROM

system libraries (libc,...)

lw sw

user application

stackdatatext

IRQ

excep

harch

kentryklibc

boot

API POSIX

lw swIRQ

syscall

hcpukinit

• C'est encore du code assembleur• Sauve l'état de tous les registres dans un tableau• Appelle une fonction du noyau (fonction en C)

qui demande l'affichage des valeurs du tableau• Puis le programme est normalement déchargé,

mais là, il se bloque simplement• Les exceptions ne sont jamais provoquées par

le noyau (sinon c'est un kernel panic)

Gère les exceptions provoquées par des erreurs dans l'application,Ici, elles sont toujours fatales. Il faut juste connaître la raison du problème.

Page 13: OS : Présentations

LU3NI031 — 2021 — Présentation de l'UE 25

API processeur : hcpu

Espace d'Adresses

syscallexception

kernel

kdataktext

regsdevice

ROM

system libraries (libc,...)

lw sw

user application

stackdatatext

IRQ

excep

harch

kentryklibc

boot

API POSIX

lw swIRQ

syscall

hcpukinit

• le numéro du core, dans le cas où il y en a plusieurs• la valeur du compteur de cycles• mais aussi, des services que nous verrons plus tard

– le masquage des interruptions– l'accès atomique à la mémoire (read-modif-write)

En cas de changement de processeurc'est la seule partie du noyau à réécrire

Contient kentry et les gestionnaires d'événements vus précédemment et des fonctions permettant d'accéder à des services spécifiques

LU3NI031 — 2021 — Présentation de l'UE 26

API architecture : harch

Espace d'Adresses

syscallexception

kernel

kdataktext

regsdevice

ROM

system libraries (libc,...)

lw sw

user application

stackdatatext

IRQ

excep

harch

kentryklibc

boot

API POSIX

lw swIRQ

syscall

hcpukinit

• ici, seulement le contrôleur de TTYs• mais aussi, des contrôleurs de disques, des timers,

des contrôleurs vidéo ou même des contrôleurs de la fréquence du SoC, il existe une multitude de périphériques !

Le noyau définit une API avec des services standards qui doivent être proposés par tous les périphériques• Ce sont les fonctions : open(), read(), write(), close(), etc.• Ces fonctions sont écrites différemment pour chaque

périphérique, il y a un read pour TTY, un pour le disque, etc. • L'ensemble de ces fonctions forment un pilote (driver)• L'ajout d'un périphérique dans le SoC entraîne l'ajout

d'un pilote dans le noyau.

Contient l'ensemble des fonctions permettant d'accéder aux contrôleurs de périphériques

Page 14: OS : Présentations

LU3NI031 — 2021 — Présentation de l'UE 27

Bibliothèque standard du noyau : klibc

Espace d'Adresses

syscallexception

kernel

kdataktext

regsdevice

ROM

system libraries (libc,...)

lw sw

user application

stackdatatext

IRQ

excep

harch

kentryklibc

boot

API POSIX

lw swIRQ

syscall

hcpukinit

Le noyau rassemble ici toutes les fonctions utiles qui ne sont pas en rapport direct avec la gestion d'une ressource matérielle ou logicielle.

• des fonctions print comme fprintf()• déplacement de mémoire comme memcpy()• de gestions de chaîne comme strlen()• et d'autres comme rand()

Ces fonctions peuvent utiliser les autres modules fprintf() utilise directement tty_write() de harch

LU3NI031 — 2021 — Présentation de l'UE 28

Bibliothèque standard de l'utilisateur : libc

Espace d'Adresses

syscallexception

kernel

kdataktext

regsdevice

ROM

system libraries (libc,...)

lw sw

user application

stackdatatext

IRQ

excep

harch

kentryklibc

boot

API POSIX

lw swIRQ

syscall

hcpukinit

• Les fonctions de la libc font appel au noyau pour accéder à ses ressources en utilisant une fonction d'appel du noyau.

• Cette fonction d'appel est propre au processeur, dans le cas du MIPS, la fonction d'appel utilise l'instruction syscall

• Si on change de processeur, il faut réécrire cette fonction.• Les fonctions de la libc sont liées avec l'application et

sont donc présentes dans le l'exécutable user.x• Ces fonctions sont exécutées en mode user sauf au

moment où elle exécute l'instruction syscall, à cet instant elles entrent dans le noyau, qui exécute le service demandé en mode kernel et qui ressort.

La libc est dans le système d'exploitation, mais elle n'est pas dans le noyau, elle implémente l'API POSIX (ici pseudo-POSIX).

Page 15: OS : Présentations

LU3NI031 — 2021 — Présentation de l'UE

Ce qu'il faut retenir

• Au boot, le MIPS est en mode kernel et saute la fonction kinit() du noyau par jr

• Depuis le mode user, l'entrée dans le noyau est kentry à l'adresse 0x80000180 quelque soit la cause (syscall, exception et interruption)

• kentry analyse la cause (avec c0_cause) puis aiguille vers le bon gestionnaire pour son traitement (syscall, exception ou interruption)

• Le noyau définit une API vers le processeur et une API vers les périphériques afin de permettre le portage vers d'autres processeurs et d'autres architectures

• Le noyau contient une klibc avec quelques fonctions utiles (printf, memcpy, etc.)

• L'application accède aux services du noyau via des bibliothèques système (libc) qui encapsule l'appel de syscall.

Dans le cas général, le noyau contient d'autres sous-systèmes : pour la gestion des fichiers ; de la mémoire ; des communications réseau ; des processus et des threads (fils d'exécution dans un processus), nous n'accordons pas ça ici.

29

LU3NI031 — 2021 — Présentation de l'UE

Communication entre kernel.x et user.x ● passage user → kernel ● passage kernel → user

30

Page 16: OS : Présentations

LU3NI031 — 2021 — Présentation de l'UE

passage user → kernelNous avons vu qu'il y a 3 causes : syscall, exception et interruption. Dans tous les cas, le MIPS saute implicitement à l'adresse 0x80000180(notez qu'un saut explicite à cette adresse provoque une exception)Convention d'appel pour syscall• $2 contient un numéro de service (commun kernel / user)• $4, $5, $6, $7 contiennent les arguments• $2 contient le code de retour (en général 0 si tout va bien)• seuls les registres GPR persistants ($16 à $23) sont garantis inchangés• se comporte presque comme un appel de fonction, la différence est que

l'appelant de syscall ne réserve pas de place dans la pile pour les arguments

Convention d'appel pour les exceptions et les interruptions• Dans notre cas, les exceptions sont fatales, mais parfois elles ne le sont pas et

on revient dans l'application, nous n'avons pas vu les interruptions, mais disons qu'elles s'insèrent entre deux instructions. Dans les deux cas, tous les registres sont conservés intacts, l'exception ou l'interruption a juste « voler » du temps.

31

LU3NI031 — 2021 — Présentation de l'UE

passage kernel → user

Il y a deux types de passage kernel → user● au retour d'un syscall (ou d'une exception ou d'une interruption)

○ Il n'y a pas de problème, l'adresse de saut est dans EPC

● au démarrage de l'application et là Il y a deux problèmes1. Quelle est l'adresse de la première instruction de l'application ?

→ par convention ce sera la première adresse de .text2. Est-ce qu'on peut appeler directement la fonction main() ?

→ non ! main() ne peut pas être la première fonction appelée parce qu'il y a des choses à faire avant

→ par convention la première fonction est _start() — elle initialise toutes les variables globales non initialisées (BSS) — elle appelle la fonction main() — elle appelle la fonction exit() si main() ne l'a pas fait_start() est placé dans une section nommée .crt0 (c runtine 0)que le ldscript placera en début de section .text

32

Page 17: OS : Présentations

LU3NI031 — 2021 — Présentation de l'UE

Démarrage de l'application

33

__text_origin = 0x7F400000 ; /* first byte address of user code region */

__text_length = 0x00100000 ;

__data_origin = 0x7F500000 ; /* first byte address of user data region */

__data_length = 0x00B00000 ;

__data_end = __data_origin + __data_length ; /* first addr after user data region */

__crt0 = __text_origin;

MEMORY {

text_region : ORIGIN = __text_origin,

LENGTH = __text_length

data_region : ORIGIN = __data_origin,

LENGTH = __data_length

}

SECTIONS {

.text : {

*(.crt0); /* c runtime at the beginning thow to launch main() */

*(.text) /* all others codes */

} > text_region

.data : {

*(.*data*) /* initialized global variables */

. = ALIGN(4); /* move the filling pointer to an word aligned address */

__bss_origin = .; /* first byte of uninitialized global variables */

*(.*bss*) /* uninitialized global variables */

. = ALIGN(4); /* move the filling pointer to an word aligned address */

__bss_end = .; /* first byte after the bss section */

} > data_region

}

__attribute__ ((section (".crt0")))

void _start (void)

{

int res;

for (int *a = &__bss_origin; a != &__bss_end; *a++ = 0);

res = main ();

exit (res);

}

mise à 0des variables globales non explicitement initialisées

user.ld

crt0.c

LU3NI031 — 2021 — Présentation de l'UE 34

Parcours de boot à exit

boot: j kinit

kinit() { EPC ← _start c0_sr ← 0xFF13 eret}

_start() { BSS ← 0 res = main(); exit(x);}

main() { fprintf() → syscall wr return x;}

kentry

syscall_handler stack ← EPC+4 syscall_vector[wr]() EPC ← stack eret

syscall_vector[write]() { TTY ← buffer}

syscall_vector[exit]() { while(1);}

1

2

3

4

56

7

8

9

10

user

kernel

Page 18: OS : Présentations

LU3NI031 — 2021 — Présentation de l'UE

Ce qu'il faut retenir

• un syscall se comporte presque comme un appel de fonction

• les interruptions et les exceptions (quand elles reviennent) sont juste des voleurs de temps du point de vue de l'application.

• Le noyau doit connaître l'adresse du début de l'application nommée _start() placée au début du segment de .text (code user)

• C'est en plaçant cette fonction dans une section spécifique .crt0 que le ldscript peut imposer le placement de _start()

• La fonction _start() initialise les variables globales non initialisées, lance main() et appelle exit().

• Les numéros de services syscall sont définis dans des fichiers communs au noyau et à l'application.

35

LU3NI031 — 2021 — Présentation de l'UE

Nous avons vu

• que le MIPS a deux mode d'exécution : kernel et user• que le mode user interdit les adresses supérieures à 0x80000000 • qu'il y a trois causes d'appel du noyau : syscall, exception et interruption• que le kernel n'a qu'un seul point d'entrée 0x80000180 quelque-soit la cause • qu'un appel système est semblable à un appel de fonction avec privilèges• que le noyau sait comment appeler l'application grâce à la convention crt0• que la première fonction de l'application est _start()• que _start() initialise les variables globales non initialisées avant d'appeler main()• que _start() appelle exit() si main() ne l'a pas déjà fait

36