You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

xv6(RISC-V/C)能否手动修改页表PTE?页表打印PTE值不一致求解

xv6三级页表PTE值疑问

我在给xv6实现三级页表时,遇到了PTE值的困惑:打印页表时,开头输出的page table address(比如...87f49000)和第二行的PTE值(比如...21fd1401)始终不一致。我原本以为这两个值应该相同,有人说这是操作系统调度随时间变化导致的正常情况。

我是不是漏了什么,才让页表输出不符合预期?我只想让前两个页表的PTE值看起来和预期一致!

预期输出(PTE地址部分与页表地址相同)

预期输出:页表地址与对应PTE的物理地址部分一致

实际输出

实际输出:完整PTE值与页表地址不一致

我的代码(无需关注)

static int level = 0;
static int print_end = 0;
static uint64 vadd_lv0 = 0;
static uint64 vadd_lv1 = 0;
static uint64 vadd_lv2 = 0;
static pte_t pte = 0;

void vmprint(pagetable_t pagetable) {
  if (level == 0){
    printf("page table %p\n", pagetable);
    print_end = 0;
    pte = pagetable;
  }
  // iterate 512 PTEs
  for (uint64 i = 0; i < 512; i++) {    
    uint64 va = 0;
    switch(level){
      case 0:
        vadd_lv0 = i<<30;
        va = vadd_lv0;
        break;
      case 1:
        vadd_lv1 = i<<21;
        va = vadd_lv0+vadd_lv1;
        break;
      case 2:
        vadd_lv2 = i<<12;
        va = vadd_lv0+vadd_lv1+vadd_lv2;
        break;
    }
    pte_t t = pagetable[i];
    if (t & PTE_V) {
      uint64 pa = PTE2PA(t);
      if (level==0 && i==255)
        print_end = 1;
      if (level != 0 && !print_end){     
        printf("|");
      }else if (level!=0){
        printf(" ");
      }
      for (int j = 0; j < (level-1)*4+3; j++) printf(" ");

      printf("+-- %d: pte=%p va=%p pa=%p",i, t, va, pa);
      printf((t&PTE_V)?" V":"");
      printf((t&PTE_R)?" R":"");
      printf((t&PTE_W)?" W":"");
      printf((t&PTE_X)?" X":"");
      printf((t&PTE_U)?" U":"");
      printf((t&PTE_D)?" D":"");

      printf("\n");

      // PTE without any WRX bit set points to low-level page table
      if ((t & (PTE_W|PTE_R|PTE_X)) == 0){

        level++;
        vmprint((pagetable_t)pa);
        level--;
      }
    }
  }
}

问题解析

  1. 核心差异:页表地址 vs PTE值
    开头打印的page table address是当前页表本身的纯物理地址;而第二行的PTE值是上级页表中指向当前页表的条目,它不仅包含目标页表的物理地址,还附加了PTE_V(有效位)、PTE_U(用户位)等权限标志位。你看到的PTE值末尾的01就是PTE_V位被置1的结果(xv6中PTE_V是最低位),所以二者必然不同。

  2. 预期输出的“相同”是视觉假象
    预期输出里只显示了PTE值的高地址部分,末尾的标志位被截断或未展示,才会看起来和页表地址一致。实际完整的PTE值一定包含标志位,和纯物理地址有差异。

  3. 调度变化的说法不成立
    同一个进程的页表结构不会随调度随意变化,你看到的不一致是页表结构的正常特性,和调度无关。

  4. 实现预期效果的方法
    如果你想让输出中PTE的地址部分和页表地址相同,打印时只提取PTE中的物理地址部分即可,修改打印行:

    // 替换原printf行,单独展示PTE的物理地址部分
    printf("+-- %d: pte=%p (pa=%p) va=%p pa=%p",i, t, PTE2PA(t), va, pa);
    

    或者直接把打印PTE的部分换成PTE2PA(t),就能看到和页表地址一致的数值。

内容的提问来源于stack exchange,提问作者Chunhao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 04:55:07