【VM】关于virtual memory地址翻译的一些问题(2)

上一篇文章讲了地址翻译 的一些基本概念,这一次记录些容易出现理解错误的地方。

1.  TLB 是硬件实现的

TLB(translation lookaside buffer)存在于MMU中,是由硬件实现的,通过一定的机制,讲TLBT于TLBI一个set中的所有tag同时进行比较。

2. PTE存储的值是物理地址

在很多时候,由于虚拟地址和物理地址都是同样的word size(比如32),我们常常忽略掉PTE中存储的地址究竟是虚拟地址还是物理地址。答案是物理地址。关于这一点,我们可以这样思考——如果存储的是虚拟地址,那么OS在翻译一个虚拟地址时,通过VPN1,CR3找到一个PTE,通过对PTE取值,得到下一节页表,如果是个虚拟地址,则又要对它进行翻译……于是进入了一个死循环(常见递归错误)。

3. Page的基地址、CR3(PTBR)都是物理地址

同2中所说,PTE中存放的是物理地址。通过第一级页表中的PTE找到的是下一级页表的基地址,那么页表的基地址(包括CR3)都是物理地址

4. PTE中的最后几位为权限位

在ICS这门课程中,我们经常会练习的题目是给出一定的VPN和value的对应值,以及一个特殊说明valid or invalid. 这个valid位就是存在于PTE值的最后一位。我们可以在JOS的lab中看到,当OS要翻译一个虚拟地址时,每当通过PTE得到其对应的值都要执行

if (!( value & PTE_P ))
      return ~0x0;

其中PTE_P的值位0x1,即检查其最后一位判断这个page及其子page是否有效。

5. VPN只是PTE个数的的offset

同在第4点中说的原因一样,在得到VPN后常常会出现直接将CR3的值(当作size_t)与VPN相加的错误。我们在JOS的lab中可以看到一个二级页表的地址翻译可以如下实现:

// This function returns the physical address of the page containing 'va',
// defined by the page directory 'pgdir'.  The hardware normally performs
// this functionality for us!  We define our own version to help check
// the check_kern_pgdir() function;

static physaddr_t
check_va2pa(pde_t *pgdir, uintptr_t va)
{
	pte_t *p;
	pgdir = &pgdir[PDX(va)];
	if (!(*pgdir & PTE_P))
		return ~0;
	p = (pte_t*) KADDR(PTE_ADDR(*pgdir));
	if (!(p[PTX(va)] & PTE_P))
		return ~0;
	return PTE_ADDR(p[PTX(va)]);
}

pgdir在这里指代的就是CR3,而&pgdir[PDX(va)]  == pgdir + PDX(va). 注意在这里pgdir是一个指针,也就是说,应该将VPN乘以4再加上CR3的值。比如CR3是0x40000,VPN是0x101,那么PTE应该是0x40404.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值