Comme promis : traduc Virtuelle -> Physique

Le
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/
Vos réponses Page 1 / 2
Trier par : date / pertinence
heinquoi
Le #9838641
dans son post, AMcD®
Bon, allons-y ! Donc, quelques explications sur la traduction adresse
...
...



Je suis bluffé !!! C'est exactement ce que je recherchais a savoir. Rien
d'autre a dire qu'un GRAND MERCI a AMcD®, qui une fois encore épate par
la précision de ses compétences et connaissances.
--
Cordialement,
Heinquoi
AMcD®
Le #9838631
Envoie ton adresse (pour le chèque) :-).

Remarque, je plaisante, mais je préfère ce genre de remarque laudative (tout
à fait justifiée par ailleurs, ouïlle les chevilles) au mails de Dark Poulpo
me traitant de gars qui n'y comprend rien, de produit du passé et que c'est
lui qui qu'est la prochaine génération de gars qui que déchire tout parce
qui l'est trop fort le gars...

--
AMcD®

http://arnold.mcdonald.free.fr/
Thierry
Le #9838601
Bonjour,

AMcD® a écrit :

Envoie ton adresse (pour le chèque) :-).



Tu devrais les mettre sur ton site tous tes longs messages comme celui-ci.

--
« Always look at the bright side of the life... »
AMcD®
Le #9838591
Thierry wrote:

Tu devrais les mettre sur ton site tous tes longs messages comme
celui-ci.



Faudrait surtout le reécrire pour en faire quelque chose de plus
présentable. Un de ces 4...

--
AMcD®

http://arnold.mcdonald.free.fr/
heinquoi
Le #9838581
dans son post, Thierry
Bonjour,

AMcD® a écrit :

Envoie ton adresse (pour le chèque) :-).



Tu devrais les mettre sur ton site tous tes longs messages comme
celui-ci.



ou bien les proposer a un site comme http://www.developpez.com , car
si, ce post a pu m'aider pour un probleme d'exception systeme en C / C++
, il poura tres certainement en aider d'autre en assembleur ou comme moi
en C/C++.
[reference a d'autre post que tu as fait AMcD® ] Peut etre que si les
developpeurs ( ou ceux qui se le pretendent) sont si "mauvais" , c'est
parce qu'ils n'ont pas les informations necessaires a leur progression
au moment ou ils en ont besoins. ( en tout cas c'est parfois mon cas )
--
Cordialement,
Heinquoi
Cyrille Szymanski
Le #9838571
Le 14-10-2004, AMcD®
Tu devrais les mettre sur ton site tous tes longs messages comme
celui-ci.



Faudrait surtout le reécrire pour en faire quelque chose de plus
présentable. Un de ces 4...



Meuh non, depuis le temps qu'on te le dit, tu devrais écrire un livre
:-)

--
cns
Thierry
Le #9838561
Bonjour,

AMcD® a écrit :

Tu devrais les mettre sur ton site tous tes longs messages comme
celui-ci.



Faudrait surtout le reécrire pour en faire quelque chose de plus
présentable.



Mets-les d'abord sur ton site. On, s'en branle de la forme.

--
« Always look at the bright side of the life... »
heinquoi
Le #9838551
dans son post, Thierry

Mets-les d'abord sur ton site. On, s'en branle de la forme.


Complètement d'accord.

Cela dit, pour me faire avancé pourrions nous prendre l'exemple
suivant:
nous avons le registre FS en mode protégé = 0x0038
et j'aimerais connaitre dans un premier temps l'adresse linéaire sur
32bit de FS:00
FS=0x00381000b
FS est notre segment sur 16 bits
le bit 0 et le bit 1 sont la Requested Privilège Level ( gere les
droits d'acces) peut donc prendre 4 valeur soit de 0 a 3.
le bit 2 est la TI Table indicator. si 0 c'est la GDT ( Global
Descriptor Table) si 1 c'est la LDT (Local Descriptor Table) dans notre
cas 0 soit la GDT.

ensuite les 13bits restant sont l'index soit ici = 111b = 0x7 = 7

mais la j'ai un problème, ou je trouve la GDT ?


--
Cordialement,
Heinquoi


--
Cordialement,
Heinquoi
Vincent Burel
Le #9838531
"heinquoi" news:416e8408$0$29496$
dans son post, Thierry >
> Mets-les d'abord sur ton site. On, s'en branle de la forme.
Complètement d'accord.

Cela dit, pour me faire avancé pourrions nous prendre l'exemple
suivant:
nous avons le registre FS en mode protégé = 0x0038
et j'aimerais connaitre dans un premier temps l'adresse linéaire sur
32bit de FS:00
FS=0x00381000b
FS est notre segment sur 16 bits
le bit 0 et le bit 1 sont la Requested Privilège Level ( gere les
droits d'acces) peut donc prendre 4 valeur soit de 0 a 3.
le bit 2 est la TI Table indicator. si 0 c'est la GDT ( Global
Descriptor Table) si 1 c'est la LDT (Local Descriptor Table) dans notre
cas 0 soit la GDT.

ensuite les 13bits restant sont l'index soit ici = 111b = 0x7 = 7

mais la j'ai un problème, ou je trouve la GDT ?



ha, l'ai déjà dis dans se thread :

faites un SGDT FWORD PTR gdt_head

où gdt_head est une structure de 6 octets. le premier WORD donne la taille
de la GDT -1
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.

VB
heinquoi
Le #9838491
dans son post, Vincent Burel
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 ....
--
Cordialement,
Heinquoi
Publicité
Poster une réponse
Anonyme