简体   繁体   中英

How to loop through all page table entries of a process in xv6?

I'm trying to loop through all pages for a process in xv6. I've looked at this diagram to understand how it works: 在此处输入图像描述

but my code is getting:

unexpected trap 14 from cpu 0 eip 801045ff (cr2=0xdfbb000)

Code:

  pde_t *  physPgDir = (void *)V2P(p->pgdir);
  int c = 0;
  for(unsigned int  i =0; i<NPDENTRIES;i++){
    pde_t * pde = &physPgDir[i];
    
    if(*pde & PTE_P){//page directory valid entry
      int pde_ppn = (int)((PTE_ADDR(*pde)) >> PTXSHIFT);

      pte_t * physPgtab = (void *)(PTE_ADDR(*pde));//grab 20 MSB for inner page table phys pointer;
      // go through inner page table
      for(unsigned int j =0;j<NPDENTRIES;j++){
        pte_t * pte = &physPgtab[j];
        if(*pte & PTE_P){//valid entry
          c++;
          unsigned int pte_ppn = (PTE_ADDR(*pte)) >> PTXSHIFT;//grab 20 MSB for inner page table phys pointer;
          //do thing
        }
      }
    }
}

This is in some custom function in proc.c that gets called elsewhere. p is a process pointer. As far as I understand, cr3 contains the physical address of the current process. However in my case I need to get the page table for a given process pointer. The xv6 code seems to load V2P(p->pgdir) in cr3. That is why I tried to get V2P(p->pgdir). However,the trap happens before pde is dereferenced. Which means there is a problem there. Am I not supposed to use the physical address?

When dealing with paging the golden rule is "never store physical addresses in any kind of pointer". The reasons are:

a) They aren't virtual addresses and can't be dereferenced, so it's better to make bugs obvious by ensuring you get compile time errors if you try to use a physical address as a pointer.

b) In some cases physical addresses are a different size to virtual addresses (eg "PAE paging" in 80x86 where virtual addresses are still 32-bit but physical addresses are potentially up to 52 bits); and it's better (for portability - eg so that PAE support can be added to XV6 easier at some point).

With this in mind your first line of code is an obvious bug (it breaks the "golden rule"). It should either be pde_t physPgDir = V2P(p->pgdir); or pde_t * pgDir = p->pgdir; . I'll let you figure out which (as I suspect it's homework, and I'm confident that by adhering to the "golden rule" you'll solve your own problem).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM