[SOS] Paging !!!

Thomas Petazzoni thomas.petazzoni at enix.org
Sam 8 Jan 19:55:54 CET 2005


Salut,

Je vais tenter une réponse. J'espère que je ne dirais pas de bétises. 
David me corrigera le cas échéant.

Toutes les références vers l'article seront numérotées selon ce qu'on 
peut trouver à l'adresse : 
http://sos.enix.org/wiki/upload/SOSDownload/sos-texte-art4.pdf

LfvrChris at aol.com wrote:

>     J'ai remarqué une chose bizarre dans les sources concernant la fonction 
> *paging_setup_map_helper()* ainsi que la fonction *sos_paging_map()*. Dans la 
> première on remarque bien que lorsque l'entrée dans la PDE n'existe pas, on 
> alloue une nouvelle PTE et on l'initialise en utilisant la fonction *memset()*. 
> Dans la seconde on remarque que lorsque l'entrée dans la PDE n'existe pas, on 
> alloue bien une nouvelle PTE mais on reset PT qui est un pointeur construit à 
> partir du mirroring.
>  
>     La nouvelle PTE est issue de la fonction *sos_physmem_ref_physpage_new()*
>  
>     Est-ce logique ?
>  
>     Ne vaudrait-il pas plutôt utiliser la fonction *memset()* sur la nouvelle 
> page que nous venons de créer, c'est à dire sur la nouvelle PTE, d'autant plus 
> que l'on réalise une initialisation sur toute une page soit 4096 octets ?
>  
>     Pouvez-vous m'expliquer le lien entre le pointeur PT construit à partir du 
> mirroring et la nouvelle PTE créée lorsque l'entrée n'est pas présente dans la PDE ?
>  
>     La difference est-elle due à l'identity mapping utilisée au départ, car à ce 
> moment là il y a correspondance entre les adresses virtuelles et les adresses 
> physiques ?

Dans la partie 3.2.1 de l'article 4, tu peux lire qu'un identity mapping 
est réalisé sur les trois parties indispensables et inamovibles du 
noyau, à savoir :
  - Le code et les données du noyau
  - La zone de mémoire vidéo
  - Le tableau des descripteurs de pages phsyiques

C'est la fonction sos_paging_setup() du fichier hwcore/paging.c qui met 
en place cet identity mapping :

================================================================
   /* Identity-map the identity_mapping_* area */
   for (paddr = identity_mapping_base ;
        paddr < identity_mapping_top ;
        paddr += SOS_PAGE_SIZE)
     {
       if (paging_setup_map_helper(pd, paddr, paddr))
         return -SOS_ENOMEM;
     }

   /* Identity-map the PC-specific BIOS/Video area */
   for (paddr = BIOS_N_VIDEO_START ;
        paddr < BIOS_N_VIDEO_END ;
        paddr += SOS_PAGE_SIZE)
     {
       if (paging_setup_map_helper(pd, paddr, paddr))
         return -SOS_ENOMEM;
     }
==================================================================

La première boucle for() met en place l'identity mapping pour le code et 
les données du noyau ainsi que le tableau des descripteurs de page 
physiques (ils sont cote à cote en mémoire, voir figure 10 dans 
l'article). La seconde boucle for() met en place l'identity mapping pour 
la mémoire vidéo.

Pour mettre en place cet identity mapping, la fonction 
paging_setup_map_helper() est appelée pour effectuer l'association 
virtuelle => physique de chaque page. Ce qui est *important*, c'est de 
noter qu'à ce stade de l'initialisation, la pagination n'est pas encore 
activée ! Comme la segmentation est configurée en mode flat, les 
adresses auxquelles on accède sont directement les adresses physiques. 
Vu qu'il n'y a pas de pagination, il n'y a pas non plus de mirroring.

La fonction paging_setup_map_helper() utilise donc directement les 
adresses physiques pour initialiser les PTs. C'est la raison pour 
laquelle on a le code suivant :

=====================================================================
       /* No : allocate a new one */
       pt = (struct x86_pte*) sos_physmem_ref_physpage_new(FALSE);
       if (! pt)
         return -SOS_ENOMEM;

       memset((void*)pt, 0x0, SOS_PAGE_SIZE);
=====================================================================

La nouvelle table de page (PT) est mise à zéro en utilisant directement 
l'adresse retournée par sos_physmem_ref_physpage_new(), qui est une 
adresse PHYSIQUE. Encore fois, cela est possible à ce stage car la 
pagination n'est PAS activée.

Le mirroring et la pagination seront mis en place et activés dans la 
suite de la fonction sos_paging_setup().

A contrario, la fonction sos_paging_map() est appelée pour mettre en 
place un mapping virtuel => physique lorsque la pagination (et donc le 
mirroring) sont activés. On ne peut donc plus mettre à zéro le PT en 
utilisant directement son adresse physique. Il faut utiliser l'adresse 
virtuelle de ce PT dans le mirroring, calculée selon la formule suivante :

======================================================================
   /* Address of the PT in the mirroring */
   struct x86_pte * pt = (struct x86_pte*) (SOS_PAGING_MIRROR_VADDR
                                            + SOS_PAGE_SIZE*index_in_pd);
=======================================================================

La mise en place d'un nouveau PT se déroule donc en 4 étapes (qu'on 
retrouve dans le if(! pd[index_in_pd].present)) :

  1) Allocation d'une page physique, dont l'adresse physique est stockée 
dans la variable pt_ppage.

  2) Enregistrement du nouveau PT dans le PD à l'index index_in_pd. Cet 
enregistrement aura pour effet de rendre le PT accessible dans l'espace 
du mirroring, à l'adresse "pt" calculée par la formule donnée précédemment.

  3) Invalidation d'une éventuelle entrée du TLB liée à ce PT par 
l'instruction invlpg.

  4) Mise à zéro du nouveau PT, en utilisant l'adresse "pt", c'est à 
dire l'adresse VIRTUELLE du nouveau PT dans le mirroring. On ne peut pas 
faire memset((void*) pt_ppage, 0, SOS_PAGE_SIZE);, puisque pt_ppage est 
une adresse PHYSIQUE, donc non accessible directement au travers de la 
pagination.

Tu retrouveras le détail des explications de sos_paging_map() dans la 
partie 3.3 de l'article 4.

Voilà, j'espère que ces explications répondent à ta question. Si ce 
n'est pas le cas, n'hésite pas à demander des précisions.

Bonne soirée,

Thomas
-- 
PETAZZONI Thomas - thomas.petazzoni at enix.org
http://thomas.enix.org - Jabber: thomas.petazzoni at jabber.dk
KOS: http://kos.enix.org/ - Lolut: http://lolut.utbm.info
Fingerprint : 0BE1 4CF3 CEA4 AC9D CC6E  1624 F653 CB30 98D3 F7A7
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 256 bytes
Desc: OpenPGP digital signature
Url : http://the-doors.enix.org/pipermail/sos/attachments/20050108/d31df632/signature.pgp


Plus d'informations sur la liste de diffusion Sos