OVH Cloud OVH Cloud

Comme promis : traduc Virtuelle -> Physique

11 réponses
Avatar
AMcD®
Bon, allons-y ! Donc, quelques explications sur la traduction adresse
virtuelle -> adresse physique.



Petit rappel du mode protégé

============================



Nous partons d'une adresse dite logique, au format 16:32. Tous les octets de
l'espace d'adressage d'un processeur sont accessibles via une adresse
logique, au format segment:offset.



Le registre de segment contient le segment auquel appartient l'octet auquel
tu accèdes. Il s'agit en fait d'un sélecteur (de 16 bits donc), qui sert d'index
pour la table de descripteur (GDT ou LDT).



Bon, en réalité, un sélecteur n'est pas qu'un index, seuls 13 bits sont
utilisés comme index. 2^13 = 8192. Donc, la GDT ou la LDT peuvent contenir
8192 descripteurs...



Via ce sélecteur, tu accèdes donc à un descripteur de la GDT ou la LDT. Un
descripteur a une taille variable, jusqu'à 8 octets Ce qu'il faut en retenir
c'est qu'il contient (entre autres) la base et la limite d'un segment.
Autrement dit, son emplacement dans l'espace d'adressage du processeur et sa
taille.



À cette adresse de base, tu ajoutes l'offset (16 ou 32 bits) et tu obtiens
ce qu'on appelle l'adresse linéaire (sur 32 bits).



Donc : Adresse logique --[GDT/LDT+Offset]--> Adresse linéaire.



Cette adresse linéaire n'est pas encore l'adresse physique, il y a encore
l'étape du paging. Cela n'est pas obligatoire, mais les OS comme Windows l'utilisent.



Cette adresse linéaire est l'adresse physique si le paging n'est pas activé.



Si le paging est activé, l'adresse linéaire de 32 bits est composée comme
suit :



Bits 0 - 11 : Offset d'octet (BI, Byte Index) ;

Bits 12 - 21 : Index de la table de pages (PTI, Page Table Index);

Bits 22 - 31 : Index du répertoire de pages (PDI, Page Directory Index).



Le répertoire de page (PD, Page Directory) est une table de 1024 entrées de
4 octets chacune. Chacune de ces entrées, appelée PDE (Page Directory
Entry), pointe vers une table de pages.



Chacune de ces tables de pages contient jusqu'à 1024 entrées de 4 octets,
appelée, PTE (Page Table Entry), qui pointe enfin vers une page (enfin, pas
tout à fait, voir plus bas).



Une page occupe 4 Ko. Note que 1024 entrées de répertoire de pages x 1024
tables de pages x 4 Ko = 4 Go, les fameux 4 Go d'adressage des systèmes 32
bits.



Au passage le PDI+PTI forment ce qu'on appelle le Virtual Page Number.



Tu as donc :



- Un répertoire de page de 1024 entrées

- Chaque entrée pointe vers une Table de pages, qui peut contenir

- 1024 entrées pointant chacune vers une page de 4 Ko.



Il te faut encore savoir que le registre CR3 du processeur contient l'offset
du répertoire de pages du processus courant (adresse physique).



Au final, nous avons :



Adresse logique -> adresse linéaire -> PD -> PT -> Page + BI -> Adresse
physique !



Pas si complexe que ça finalement :-).



Petit exemple pratique de traduction

====================================



Quelques trucs à savoir :



- Windows mappe virtuellement la PT du processus courant à l'adresse
0xC0000000h de l'espace d'adressage, jusqu'en 0xC02FFFFFh, ce qui fait 3 Mo
de pointeurs vers des pages.



- À partir de 0xC0300000h et jusqu'en 0xC0300FFFh, c'est l'espace réservé à
la PD. Soit 0x00001000h = 4096 octets. Comme chaque PDE fait 4 octets, cela
fait 1024 entrées. La PDT peut donc gérer 1024 tables de pages, comme vu
plus haut.



Lançons maintenant un debugger, par exemple WinDBG. Lance une session de
kernel debugging en local. Prenons, au hasard, l'adresse virtuelle
0x00123454h (enfin, pas si au hasard que ça, mais bon, ce serait une autre
histoire).



Tape : dc 0x00123454



Tu obtiens le contenu de la mémoire à l'adresse virtuelle 0x00123454, soit :



00123454 00000000 00000000 0012347c 00000000 ........|4......

00123464 00000000 00000000 00000000 00000000 ................

00123474 00000000 00000000 00000000 00000000 ................

00123484 00000000 001234a8 00000000 00000000 .....4..........



Etc.



Ton adresse virtuelle de 32 bits, découpons-là en BI, PTI et PDI :



0x00123454h = 100100011010001010100b soit :



BI = 010001010100b = 454h

PTI = 0100100011b = 123h

PDI = 0000000000b = 0000h



À partir de 0xc0000000, il y a 1024 (maxi) PT de 1024 entrées de 4 octets
chacune.



Puisque PDI = 0, nous sommes donc sur la première entrée de la PD. Pour
atteindre la PT :



0xC0000000 + PDI x 1024 x 4 octets = 0xC0000000 = zbib



Pour atteindre la page :



Zbib + PTI x 4 octets (chaque pointeur de page fait 4 octets)



= 0xC0000000 + 123h x 4 = 0xc000048C.



Nous voici donc à notre PTE. Mais ce n'est pas encore tout à fait notre
adresse physique finale. Qu'y a-t-il à cet endroit ?



Le debugger nous dit :



dd 0xc000048c L1

c000048c 00258067



Donc, si vous êtes toujours là, le contenu de notre PTE est 0x00258067h. Le
dernier truc à savoir est qu'en fait un PTE contient 12 bits d'état
(simplifions) et 20 bits de numéro de cadre de page, ou FPN (Frame Page
Number). Bref, l'offset du début de la page qu'on cherche).



0x00258067h = 1001011000000001100111b soit :



00000000001001011000.000001100111 si on découpe en 20+12bits. Nous intéresse
00000000001001011000b soit 0x00258h, le FPN.



Une page faisant 4 Ko, multiplions notre FPN par 4096 pour arriver au
premier octet de la page cherchée : 0x00258 x 0x1000h = 0x00258000h.



Il nous reste à rajouter notre BI (je suis sûr qu'e t'y pensais plus !) et
on obtient l'octet physique recherché (il était temps, je sais) :



0x00258000h + 454h = 0x00258454h.



Pour résumer, l'adresse virtuelle 0x00123454h correspond à l'adresse
physique 0x00258454h. Hmm, j'en vois qui ne me croient pas. Bon...



lkd> dc 0x00123454

00123454 00000000 00000000 0012347c 00000000 ........|4......

00123464 00000000 00000000 00000000 00000000 ................

00123474 00000000 00000000 00000000 00000000 ................

00123484 00000000 001234a8 00000000 00000000 .....4..........



lkd> !dc 0x00258454

# 258454 00000000 00000000 0012347c 00000000 ........|4......

# 258464 00000000 00000000 00000000 00000000 ................

# 258474 00000000 00000000 00000000 00000000 ................

# 258484 00000000 001234a8 00000000 00000000 .....4..........



Hihihi.



Comment ça c'est abominable ? Meuh non, il y a pire, j'aurai pu causer des
TLB, du PAE, mais j'ai pitié et vu l'heure matinale...



Encore 2-3 trucs !



Avec WinDBG, on peut visualiser des trucs sympas :



- !process : donne des infos utiles, notamment l'adresse physique de la PD
dans le paramètre DirBase.



- !pte adresse_virtuelle donne le contenu du PDE et du PTE de l'adresse
virtuelle. Par exemple :



lkd> !pte 0x00123454

VA 00123454

PDE at C0300000 PTE at C000048C

contains 033E9067 contains 00258067

pfn 33e9 ---DA--UWEV pfn 258 ---DA-UWEV



C000048C et 00258067 doivent vous dire quelque chose.



Exercice

========



Les courageux peuvent refaire l'exercice ci-dessus avec le debugger et en
partant de la valeur physique de la PD. Bon courage !



Ouf, c'est fini. Je me croirai revenu quelques années en arrière, ici, avec
mes post kilométriques :-)...


--
AMcD®

http://arnold.mcdonald.free.fr/

1 réponse

1 2
Avatar
Vincent Burel
"heinquoi" <nospam* wrote in message
news:41703386$0$29592$
dans son post, Vincent Burel nous à dit:

> les 4 octet suivant forme une adresse 32 bit, l'adresse de la première
> entrée de la GDT... auquel vous n'avez pas accès d'ailleurs sauf si
> vous êtes en IOPL 0 :-)
>
> Sinon , lisez la doc Intel, ( le volume 3 : système programmeur
> guide) vous ferez gagner du temps à tout le monde.

je le telecharge. Savoir ou trouver l'info c'est bcp. Si tu avais
commencé par la j'aurais ( et vous aussi ) gagner du temps ....



je croyais que vous le saviez, car intel a toujours fourni des docs PDF et
n'a jamais lésiné en matière de diffusion d'explication, de note technique
et autre pour expliquer sont processor et l'architecture qui va avec...
c'est dans leur intérêt aussi.

Tu peux télécharger toute la doc concertnat l'IA-32 par exemple.
1 2