首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在xv6中循环遍历进程的所有页表条目?

如何在xv6中循环遍历进程的所有页表条目?
EN

Stack Overflow用户
提问于 2022-02-05 03:53:51
回答 1查看 660关注 0票数 1

我试图循环遍历xv6中的进程的所有页面。我看过这个图表来了解它是如何工作的:

但我的密码是:

代码语言:javascript
复制
unexpected trap 14 from cpu 0 eip 801045ff (cr2=0xdfbb000)

代码:

代码语言:javascript
复制
  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
        }
      }
    }
}

这在proc.c中的某些自定义函数中是在其他地方调用的。P是进程指针。据我所知,cr3包含当前进程的物理地址。但是,在我的例子中,我需要获得给定进程指针的页表。xv6代码似乎在cr3中加载了V2P(p->pgdir)。这就是为什么我试图获得V2P(p->pgdir)。然而,陷阱发生在pde被取消引用之前。这意味着这里有个问题。我不应该用物理地址吗?

编辑:正如Brendan回答的,虚拟地址p->pgdir应该被取消引用。此外,还应该通过P2V将页面目录中的PPN转换为正确地取消对页面表的引用。如果将来有其他人对xv6的这一方面感到困惑,我希望这会有所帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-05 16:50:36

在处理分页时,金科玉律是“永远不要在任何类型的指针中存储物理地址”。原因是:

( a)它们不是虚拟地址,也不能取消引用,因此,如果尝试使用物理地址作为指针,最好通过确保获得编译时错误来使bug变得明显。

在某些情况下,物理地址与虚拟地址的大小不同(例如:在80x86中的"PAE分页“中,虚拟地址仍然是32位,但物理地址可能高达52位);而且它更好(为了便于移植--例如,可以在某个时候更容易地将PAE支持添加到XV6中)。

记住这一点,您的第一行代码就是一个明显的错误(它打破了“黄金法则”)。它应该是pde_t physPgDir = V2P(p->pgdir);pde_t * pgDir = p->pgdir;。我会让你找出哪一个(我怀疑这是家庭作业,我相信通过遵守“金科玉律”你就能解决你自己的问题)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70995156

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档