Tuesday, September 29, 2009

虚拟地址到物理地址的转换过程

今天在QEMU上做了下实验。手工跟踪了下虚拟地址到物理地址的转换,又弄清楚了一些。下面记录下实验过程。

目的:给出虚拟地址0XC100,0000. 找出它的物理地址(我们已经知道答案是0X0100,0000. 但是要看一下是怎么得出这个结论的)。

环境:QEMU 0.9.2. 虚拟机是LINUX 2.6.18

方法及步骤:
1)在QEMU里按ALT+CTRL+2。切换到MONITOR模式。输入:info registers得到CR3内容:0x1132b000. 这个地址就是PAGE DIR TABLE的起始地址。
2) 虚拟地址的 C1加上后面2个0 决定了它在PAGE DIR TABLE里的位置。C1后面加2个0(总共10BIT) 翻译成2进制就是 1100,0001,00. 也就是十进制的772,16进制的304.
3)PAGE DIR TABLE里的0X304项的地址应该是 0X304*4=0XC10. 因为每个PAGE DIR ENTRY占4个字节。并且X86 CPU是按照字节寻址的。
4)查看 PAGE DIR TABLE里0X304的内容。在QEMU里输入xp /10hx 0x1132bc10 ( 0x1132bc10 =cr3+0xc10). 发现这个地址的内容是0X0130,F163. 注意X86是LITTLE ENDIAN的。
5)0X0130F (PAGE DIR ENTRY 的前20 位)是PAGE TABLE 的基地址。后面的是一些FLAG. PAGE TABLE的真正地址要再乘以0X1000. 所以PAGE TABLE的物理地址是 0X0130, F000.
6) 这时在看虚拟地址的中间10位。在本例中都是0。所以只要看PAGE TABLE的第一个ENTRY就可以了。用 xp /10hx 0x130f000. 发现内容是 0X0100,0163.
7)在 0X0100,0163 中,前20位是PAGE FRAME NUMBER. (后面的163是FLAG)其真正的地址应该再乘以0X1000。所以对应的地址就是0X0100,0000。由于虚拟地址的后面12位都是0,所以最后的真正物理地址就是0X0100,0000。也就是正确答案。

最后,几个想法:
1)在PAGE DIR, PAGE TABLE里放的是物理地址相关的或者物理的PAGE FRAME NUMBER. 这个是很容易理解的。如果放的是虚拟地址,那么又要用到另外一个PAGE DIR, PAGE TABLE来解释。结果就变成死循环了。
2)由于0XC100,0000在本例中是内核的起始地址,所以什么时候切换到QEMUMONITOR都没有关系。所有的进程这部分都一样的。我后来又转换过一次。第二次的CR3地址不同,也就是说此时运行的是另外一个进程。但是它的PAGE DIR ENTRY的内容和第一个是一样的。
3)如果是看虚拟地址0XC000,0000的话,结果有点奇怪。我猜是由于最开始的物理地址和BIOS啥等有关。目前还没完全搞清楚。

No comments: