6.s081 lab3 pagetable

        逻辑地址会被MMU(内存管理单元)转换为物理地址。因为MMU会读取内存中的page table,根据映射关系进行翻译。

虚拟地址:64个位,分为index和offse,index对应页,也就是4096个字节;offset对应具体字节。64位的前25位用不上,27位表示页号,12位表页内偏移地址(2^12=4096)。根据页表只要通过index找到对应的页就行了,offset不需要翻译。

多级结构:但27位表示页号说明这个进程拥有的page table会拥有2^27条映射关系。这过于消耗内存,实际上使用多级结构,将27分为9+9+9。3层page directory,他们的大小也是4096位,每个条目PTE(Page Table Entry)是8字节,所以一个page directory有4096/8=512项。就相当于3层512叉树。

        SATP寄存器会指向最高一级的page directory的物理内存地址。

        index前9位地址在最高层page directory找到通过索引获得一个PNN(44位),就是物理页号,再拼上12位的0形成物理地址找到一个页,这个页是第二层page directory

        以此类推,然后再第三层page directory获得一个PNN(44位),拼上12位offset,就变成了真实物理地址

        好处:这样如果地址空间只使用了1页,就只需要3个page directory,也就是3*512项,每一层的page directory只有一条PTE起作用。

        而原来不管怎么样都只有一页,即使你只需要1页,整个page table也要占据2^27

PTE:低10位是标志位,vaild表示是否合法,Readable和Writable可读和可写

Executable表明你可以从这个page执行指令

User表明这个page可以被运行在用户空间的进程访问。

1.vmprint

启动xv6时,刚执行完exec(),打印第一个进程的页表

首先在kernel/defs.h中增加vmprint()的声明  void vmprint(pagetable_t );

然后在exec()结束的时候调用写的函数vmprint()

最后,在kernel/vm.c实现函数vmprint()

void _vmprint(pagetable_t pagetable, int depth){
    if(depth == 1) //第一次调用的时候打印那个头部
        printf("page table %p\n", pagetable);
    if(depth == 4) //一共只有3层页表,第四次跳出循环递归
        return;
    for(int i = 0; i < 512; i++){ //一页最多512个条目,遍历他们并打印
        pte_t pte = pagetable[i];  //第i个条目
        if(pte && PTE_V){    //如果该条目合法
            printf("..");
            for(int j = 1; j < depth; j++)
                printf(" ..");
            printf("%d: pte %p pa %p\n", i, pte, PTE2PA(pte));
            _vmprint((pagetable_t) PTE2PA(pte), depth + 1); //递归调用,打印此条目对应页的所有条目
        }
    }
}

void vmprint(pagetable_t pagetable){
    _vmprint(pagetable, 1);
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值