Ⅰ 虚拟地址到物理地址(内存虚拟化)
假设一个堆的基地址为34KB,虚拟地址为4KB,其大小为2KB
当 程序不分段时 ,找到堆中虚拟地值的物理地址很简单,物理地址 = 基地址 + 虚拟地址
当 程序分段时 ,找到堆中物理地址会复杂一些,物理地址 = 基地址 + (虚拟地址 - 该段的开头的虚拟地址)
举个例子,堆中有一个虚拟地址为4200,那么如果想得到其物理地址,需 34KB + 4200 - 4 KB = 34920
你可能好奇为什么要这么做,我们来简单解释一下:
首先我们先明确,之所以使用虚拟地址是想让程序以为自己独占内存,也就是说程序所占内存是从0 - xxx。虚拟地址是多少,就表示其在第多少个内存空间
当不分段时:整个程序的内存空间连续(无论是程序以为的内存空间还是物理内存都是连续的),所以虚拟地址即表明了其是第几个内存空间。显然 物理地址 = 基地址 + 虚拟地址
当分短时:整个程序的内存空间不再连续,每一段都有自己独特的基地址,但是虚拟地址还是相对于之前只有一个基地址时的值,那么此时虚拟地址就无法直接表示其在第几个内存空间了(因为程序以为的连续内存空间映射成的物理内存并不连续)。所以,我们需要虚拟地址相对于每个段自己的基地址的值,要完成这个操作只需要将虚拟地址 - 段开头的虚拟地址。因此 物理地址 = 基地址 + 虚拟地址 - 段开头的虚拟地址
Ⅱ 现代CPU如何自动把虚拟地址转换成物理地址的硬件电路
虚拟内存是一个由存放在磁盘上的N个连续的字节大小的单元组成的数组。
每个字节都有一个唯一的地址,就是虚拟地址。通常,虚拟地址由页号和偏移量组成,页号就是抽象的虚拟页的编号,偏移量用于计算实际的物理地址。
虚拟地址和物理地址的关系。进程虽然使用虚拟地址,但是用数据时还是要到实际的物理地址去取数据。这就存在一个虚拟地址到物理地址的转化运算,这是由CPU芯片上一个叫做内存管理单元(MMU)的专用硬件来实现的。
通常,物理地址=页号*页大小+页内偏移量。虚拟寻址CPU通过虚拟地址来访问主存,访问内存使用的物理地址,MMU通过将虚拟地址进行翻译,转化为物理地址,然后再用这个物理地址去访问内存数据。
Ⅲ Linux下怎样在进程中获取虚拟地址对应的物理地址
Linux文件目录中的/proc记录着当前进程的信息,称其为虚拟文件系统。在/proc下有一个链接目录名为self,这意味着哪一个进程打开了它,self中存储的信息就是所链接进程的。self中有一个名为page_map的文件,专门用来记录所链接进程的物理页号信息。这样通过/proc/pid/page_map文件,允许一个用户态的进程查看到每个虚拟页映射到的物理页
/proc/pid/page_map中的每一项都包含了一个64位的值,这个值内容如下所示。每一项的映射方式不同于真正的虚拟地址映射,其文件中遵循独立的对应关系,即虚拟地址相对于0x0经过的页面数是对应项在文件中的偏移量
* /proc/pid/pagemap. This file lets a userspace process find out which
physical frame each virtual page is mapped to. It contains one 64-bit
value for each virtual page, containing the following data (from
fs/proc/task_mmu.c, above pagemap_read):
* Bits 0-54 page frame number (PFN) if present//present为1时,bit0-54表示物理页号
* Bits 0-4 swap type if swapped
* Bits 5-54 swap offset if swapped
* Bit 55 pte is soft-dirty (see Documentation/vm/soft-dirty.txt)
* Bit 56 page exclusively mapped (since 4.2)
* Bits 57-60 zero
* Bit 61 page is file-page or shared-anon (since 3.5)
* Bit 62 page swapped
* Bit 63 page present//如果为1,表示当前物理页在内存中;为0,表示当前物理页不在内存中
在计算物理地址时,只需要找到虚拟地址的对应项,再通过对应项中的bit63判断此物理页是否在内存中,若在内存中则对应项中的物理页号加上偏移地址,就能得到物理地址
通过程序获取物理地址并验证写时拷贝技术
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>
//计算虚拟地址对应的地址,传入虚拟地址vaddr,通过paddr传出物理地址
void mem_addr(unsigned long vaddr, unsigned long *paddr)
{
int pageSize = getpagesize();//调用此函数获取系统设定的页面大小
unsigned long v_pageIndex = vaddr / pageSize;//计算此虚拟地址相对于0x0的经过的页面数
unsigned long v_offset = v_pageIndex * sizeof(uint64_t);//计算在/proc/pid/page_map文件中的偏移量
unsigned long page_offset = vaddr % pageSize;//计算虚拟地址在页面中的偏移量
uint64_t item = 0;//存储对应项的值
int fd = open("/proc/self/pagemap", O_RDONLY);。。以只读方式打开/proc/pid/page_map
if(fd == -1)//判断是否打开失败
{
printf("open /proc/self/pagemap error
");
return;
}
if(lseek(fd, v_offset, SEEK_SET) == -1)//将游标移动到相应位置,即对应项的起始地址且判断是否移动失败
{
printf("sleek error
");
return;
}
if(read(fd, &item, sizeof(uint64_t)) != sizeof(uint64_t))//读取对应项的值,并存入item中,且判断读取数据位数是否正确
{
printf("read item error
");
return;
}
if((((uint64_t)1 << 63) & item) == 0)//判断present是否为0
{
printf("page present is 0
");
return ;
}
uint64_t phy_pageIndex = (((uint64_t)1 << 55) - 1) & item;//计算物理页号,即取item的bit0-54
*paddr = (phy_pageIndex * pageSize) + page_offset;//再加上页内偏移量就得到了物理地址
}
const int a = 100;//全局常量
int main()
{
int b = 100;//局部变量
static c = 100;//局部静态变量
const int d = 100;//局部常量
char *str = "Hello World!";
unsigned long phy = 0;//物理地址
char *p = (char*)malloc(100);//动态内存
int pid = fork();//创建子进程
if(pid == 0)
{
//p[0] = '1';//子进程中修改动态内存
mem_addr((unsigned long)&a, &phy);
printf("pid = %d, virtual addr = %x , physical addr = %x
", getpid(), &a, phy);
}
else
{
mem_addr((unsigned long)&a, &phy);
printf("pid = %d, virtual addr = %x , physical addr = %x
", getpid(), &a, phy);
}
sleep(100);
free(p);
waitpid();
return 0;
}
测试结果如下:
全局常量:符合写时拷贝技术
子进程修改动态内存
*其实想要知道虚拟地址对应的物理地址,通过这样的方式也可以得到物理地址而不用操作MMU。。。*
以上就是Linux下怎样在进程中获取虚拟地址对应的物理地址的全文介绍,希望对您学习和使用linux系统开发有所帮助.
Ⅳ 分页,虚拟地址是怎么转换成物理地址的
虚拟地址(即图中的逻辑地址)的高位表示页号,由计算机硬件将页号取出,且和页表寄存器中的页表始址一起送加法器,就可以得到该页对应的页表项的地址,根据此地址到内存读出对应的块号,最后将块号和页内地址拼接得到对应的物理地址。
Ⅳ 操作系统中逻辑地址转物理地址是什么
1、确定虚拟地址(物理地址)的有效位。
2、再次确定逻辑地址页面位数你应该知道:逻辑地址=页号+页面。
3、由物理地址=页框号×页块大小(页块大小是等于页面大小的)+页内位移(即页面逻辑地址)
4、根据上面物理地址=页框号×1024B+1110000000。
5、若在一分页存储管理系统中,某作业的页表如下所示。已知页面大小为1024字节,试将逻辑地址1011,2148,4000,5012转化为相应的物理地址。
分析页式存储管理的地址结构是一维的,即逻辑地址(或物理地址)只用一个数值即可表示。若给定逻辑地址A,页面的大小为L,则页号p和页内地址d可按照下式求得:
p=int[A/L]d=AmodL
其中,int是取整函数(取数值的整数部分),mod是取余函数(取数值的余数部分)。
Ⅵ 试将十六进制的虚拟地址0A5CH、103CH、1A5CH转换成物理地址。
某虚存拟存储器的用户编程空间共32个页面,每页为1KB,内存为16KB。假定某时刻一用户页表中已调入内存的页面的页号和物理哪雹块号的对照表如下表:
页 号 物理块号
0 5
1 10
2 4
3 7
4 2
5 3
6 8
则逻辑地址0A5CH对应的物理地址李笑帆为 ?
答:按分页存储管理的思想,逻辑空间分页,内存空间分块,块的大小与页面的大小相同,为1KB(400H)。由于0A5CH=400H*2+25CH,所以逻辑地址0A5CH对应的页号为2,页内位移为25CH。
根据页表可知页号2对应的物理块号为4,物理块号为4的块首地址为400*4=1000(H),因此块首地址+块内位升销移=1000H+25CH=125CH,为逻辑地址0A5CH所对应的物理地址。
同理可得:逻辑地址103CH所对应的物理地址为:83CH。
逻辑地址1A5CH所对应的物理地址为:345CH。
Ⅶ 关于内存管理和地址转换的小小小小小总结
因为在ipad上画图比较好操作,这篇笔记就直接上传手写版了。把线性地址到物理地址部分的转换理了一下,以后有补充会做更新。
四级页表的作用主要就是地址映射,将逻辑地址映射到物理地址。
ARM MMU的地址转换过程实际上更加复杂,通过两级页表实现,转换方式有两大类共四种情况,具体的可以看这篇博客 https://blog.csdn.net/sinat_41104353/article/details/82778822
已知系统使用IA-32分页,现知道一个虚拟地址0x10036270,需要将该虚拟地址转换为物理地址。若已知CR3寄存器中的值为0x7401000,转化的过程如下:
1. 虚拟地址为0x10036270(00010000 00000011 01100010 01110000)
22-31bit为PDI值(00 0100 0000),12-21bit为PTI值(00 0011 0110 ),0-11bit为地址偏移(010 0111 0000)
2.页目录项PDE的地址=PDI×4+PDB(CR3)=0x40×4+0x740100=0x7401100
3.知道PDE物理地址后即可知道该物理地址中存储的值,比如假设该物理地址存储的值为0x28cf9067。PTE的值由PDE值的12-31bit及虚拟地址的12-21bit构成(0-11bit根据12bit填充为0),可得到PTE的物理地址=0x28cf9058
4.假设该物理地址中的值为0x182a7071,物理地址的值由PTE值的12-31bit及偏移地址构成。
最终得到物理地址=0x28cf9000+0x270=0x28cf9270。
以上为IA-32分页虚拟地址转物理地址的过程。
关于虚拟地址到物理地址的转换
由于在内存中存储的一般是虚拟地址,而在物理内存中地址定位的一定是物理地址,因此计算虚拟地址(线性地址)到物理地址的映射关系是内存分析的关键。
虚拟地址到物理地址的映射计算需要使用到一个基本规则: 在同一个虚拟地址页面上的内容,也在同一个物理页面。
比如,在物理内存管理中,页的大小一般为4KB、2MB、4MB,都大于或等于0x1000(4KB)。根据上述的规则,虚拟地址0xffdff000-0xffdfffff就应该映射到同一个物理页面上。而计算系统的页目录基地址是计算内存映射的关键,如果在0xffdff000-0xffdfffff中找到指向系统页目录基地址的指针就会解决地址映射的问题。
在上部分的笔记中能看到,CR3寄存器是非常重要的一个寄存器,它记录的是页目录基地址(或页目录指针基地址、或PLM4基地址),如果能得到CR3寄存器的内容,那么就有可能得到现成的页目录基地址。
这里以《内存取证原理与实践》的例子,先大概描述一下 利用CR3的虚拟地址找到其物理地址的方法 。
以64位win7操作系统为例,_KPRCB 的结构成员ProcessorState是一个_KPRROCESSOR_STATE结构,起始地址为0xfffff80045eff80+0x40,在0x0处是SpecialRegister成员,偏移0x010处就是CR3寄存器,它的虚拟地址为0xfffff80045eff80+0x40+0x10。
而根据上述提到的基本规则我们可以知道,它和0xfffff800045efe00在同一个页面中,那么所以它的物理地址= 0xFFFFF800045EFE00的物理地址+0x180(这两个地址的差值)+0x40+0x10。
关于页的分页方式和页的大小则由以下过程确定:
1. 根据CR3寄存器的内容找到它指向的物理地址。
2. 判断该地址处的第一个字节,如果不是0x01则跳转至第三步,否则表明其使用了PAE模式,从这个地址开始的8byte是页目录指针。根据待转换的虚拟地址的第31~30 bit选择页目录指针。例如,如果待转换的地址是0x8054c2b8(10000000 01010100 11000010 10111000),则页目录指针表的第三项(二进制10)为指向页目录的指针,根据这个指针可找到页目录基地址。
根据页目录基地址和虚拟地址的第21~20bit确定待转换虚拟地址对应的页目录项。例如,如果待转换的地址是ox8054c2b8,则第21~29bit是000000010(0x02),则从页目录基地址加上8×2开始的8个字节就是所找的页目录项。
3. 判断该地址处的第一个字节最高位,如果是“1”,则表明使用的大页模式;如果是“0”,则表明它指向页表。
Ⅷ 如何查电脑的物理地址
按步骤操作即可查询电脑的物理地址。
1、按住键盘上的Windows键,再按R键,调出“运行”窗口
(8)知道虚拟地址怎么求物理地址扩展阅读:
在存储器里以字节为单位存储信息,为正确地存放或取得信息,每一个字节单元给以一个唯一的存储器地址,称为物理地址(Physical Address),又叫实际地址或绝对地址。
地址从0开始编号,顺序地每次加1,因此存储器的物理地址空间是呈线性增长的。它是用二进喊段制数来表示的,是无符号整数,书写格式为十六进制数。它是指渗磨出现在CPU外部地址总线上的寻址物理内存的地址信号,是地址变换的最终结果。用于内存芯片级的单元寻址,与处理器和CPU连接的地址总线相对应。
在计算机科学唯斗中,物理地址(英语:physical address),也叫实地址(real address)、二进制地址(binary address),它是在地址总线上,以电子形式存在的,使得数据总线可以访问主存的某个特定存储单元的内存地址。在和虚拟内存的计算机中,物理地址这个术语多用于区分虚拟地址。尤其是在使用内存管理单元(MMU)转换内存地址的计算机中,虚拟和物理地址分别指在经MMU转换之前和之后的地址。在计算机网络中,物理地址有时又是MAC地址的同义词。这个地址实际上是用于数据链路层,而不是如它名字所指的物理层上的。
参考资料:物理地址 网络
Ⅸ 已知逻辑地址求物理地址
Ⅹ 通过虚拟地址计算物理地址 求过程
你打的太多了,有点乱,只说下地址转换问题:
1.虚拟地址:虚拟地址是以"段寄存器:偏移地址"形式存在的,例如--0542:24521360
2.线性地址:它是由分段部件把虚拟地址转化而来的.
3.物理地址:即真实存在的地址,由处理器的地址引脚寻找到的地址.
虚拟地址---->线性地址:
段寄存器是一个16位的寄存器,其中第0和1位控制着将要访问段的特权级,第2位说明是在gdt还是ldt寻找地址.高13位作为一个索引值,总共8192个索引.假设段寄存器-0000
0000
0000
1011(000b),那么我们可以知道rpl=3(特权级为3);ti=0,从gdt中选择段描述符;index=1,即将要索引的段描述符在gdt中的顺序号为1,由于一个段描述符占8个字节,所以其索引到的地址为"gdt的高32位+1*8".这也就是为什么gdt48位,留最低的16位作为限长的原因(8192*8=64k).
找到了段描述符,然后就是从段描述符中找出该段的位置了.段描述符是个8字节的内存空间,由于结构复杂,无法构图,省略段描述符的结构.我们只要知道在里面规定了该段的基址,限长,还有属性等等.找出基址后,再加上虚拟地址的偏址,就形成了32位的线性地址.由于偏址是32位的,所以该段独享4g的虚拟地址空间.
线性地址----->物理地址
该部分是由分页部件通过3级查找完成的.此时,我们把线性地址分为3段:0-11位(c)字节索引,12-21位(b)页表索引,22-31位(a)页目录索引.我们把页表描述符和页描述符通称为页表项,页表项占4个字节,总共占4kb大小.先以cr3为基址,以(a*4)为索引值,寻址页目录描述符.然后再以页目录地址的高20位地址为基址,以(b*4)为索引值,寻址页描述符.再以页描述符的高20位地址为基址,以c为偏移地址,相加得到物理地址.
从上可以看到页的大小是4kb,即一项任务cpu只调用该任务所占内存空间的4kb大小.有利于减少内存占用.
以上大体就是这样的,其中分页部件的转换相当复杂,不是三言两语就能说明白的.还有pentium之后,分页部件又采用了4mb的页面,线性地址采用2级寻址.才开启pae功能后,又形成了4级寻址.然后再结合后面的内存保护,i/o保护,任务保护及特权级的变换,形成了保护模式的大部分内容.
太复杂了,我也不是十分会.写的有些乱,但愿你能明白些.