CPU通过地址来访问内存中的单元,地址有虚拟地址和物理地址之分。那么虚拟地址到物理地址,怎么转换?小编整理了修改硬盘物理地址的相关资料。供大家参考!
虚拟地址到物理地址参考如下虚拟地址和物理地址的概念CPU通过地址来访问内存中的单元,地址有虚拟地址和物理地址之分,如果CPU没有MMU(Memory Management Unit,内存管理单元),或者有MMU但没有启用,CPU核在取指令或访问内存时发出的地址将直接传到CPU芯片的外部地址引脚上,直接被内存芯片(以下称为物理内存,以便与虚拟内存区分)接收,这称为物理地址(Physical Address,以下简称PA),如下图所示。
物理地址示意图
如果CPU启用了MMU,CPU核发出的地址将被MMU截获,从CPU到MMU的地址称为虚拟地址(Virtual Address,以下简称VA),而MMU将这个地址翻译成另一个地址发到CPU芯片的外部地址引脚上,也就是将虚拟地址映射成物理地址,如下图所示[1]。
虚拟地址示意图
MMU将虚拟地址映射到物理地址是以页(Page)为单位的,对于32位CPU通常一页为4K。例如,虚拟地址0xb700 1000~0xb700 1fff是一个页,可能被MMU映射到物理地址0x2000~0x2fff,物理内存中的一个物理页面也称为一个页框(Page Frame)。
内核也不能直接访问物理地址.但因为内核的虚拟地址和物理地址之间只是一个差值0xc0000000的区别,所以从物理地址求虚拟地址或从虚拟地址求物理地址很容易,+-这个差就行了
物理地址(physical address)
用于内存芯片级的单元寻址,与处理器和CPU连接的地址总线相对应。
——这个概念应该是这几个概念中最好理解的一个,但是值得一提的是,虽然可以直接把物理地址理解成插在机器上那根内存本身,把内存看成一个从0字节一直到最大空量逐字节的编号的大数组,然后把这个数组叫做物理地址,但是事实上,这只是一个硬件提供给软件的抽像,内存的寻址方式并不是这样。所以,说它是“与地址总线相对应”,是更贴切一些,不过抛开对物理内存寻址方式的考虑,直接把物理地址与物理的内存一一对应,也是可以接受的。也许错误的理解更利于形而上的抽像。
虚拟地址到物理地址的转换步骤已知一个虚拟地址0x01AF5518, 则转换的过程如下:
注意: *这里讨论的以Windows下普通模式分页的情况, 也就是2级页表的情况*
1.首先把虚拟地址拆分成3个部分(低12位, 中10位, 高10位), 换成2进制如下:
-> 0000 0001 1010 1111 0101 0101 0001 1000
按照10, 10, 12的位数重新排列后
-> (页目录索引)00 000 00110, (页表项索引)10 1111 0101, (偏移)0101 0001 1000
换算成十六进制后可以得到如下结果
页目录索引 = 6, 页表项索引 = 0x2f5 , 偏移 = 0x518
2. 根据当前的CR3寄存器中的物理地址定位页目录表基址
Cr3中存放的是物理地址, 这个物理地址指向进程的页目录表基址, 由此可以得到
页目录表基址(PDE) = Cr3 = 0xAA0E5000
3. 计算页表项的地址
页表地址存放在页目录表(PDE)中的第6个项目中, 也就是
[0xAA0E5000 + 4 * 6] = [0xAA0E5018] = 0x3D955867, 其中0x00000867为该页表属性值, PTE = 0x3D955000
3. 计算页面物理地址
我们要找的页面在这个页表中的第0x2f5项, 所以虚拟地址所在的页的物理地址为
[0x3D955000 + 0x2f5 * 4] = [0x3D955BD4] =
假设[0x3D955BD4] = 0x7095e847, 页面的物理地址 x0x7095e000, 0x00000847表示的是页面属性
4. 计算最终的物理地址
由虚拟地址分离的偏移可以计算出最终的物理地址为
0x7095E000 + 0x00000518 = 0x7095E518.