首页 > 编程知识 正文

物理地址和虚拟地址的关系,逻辑地址空间和物理地址空间

时间:2023-05-05 22:02:28 阅读:155704 作者:1693

文章目录物理地址(physical address )虚拟地址(virtual memory )逻辑地址(logical address )线性地址)或者虚拟地址(virtual address )地址转换

物理地址(physical address )

用于存储器芯片级单元寻址,对应处理器和CPU连接的地址总线。

可以将物理地址理解为直接连接到计算机的内存本身,将内存视为一个从0字节到最大可用空间按字节编号的大数组,也可以将其称为物理地址,但实际上这是硬件为软件提供的抽象。 所以,说“支持地址总线”更合适,但也可以理解无视物理存储器寻址方式的想法,直接将物理地址和物理存储器一一对应。 错误的理解可能有助于形而上的抽象。

“虚拟地址”(virtual memory )这是整个内存(请勿在计算机上插入该对)的抽象描述。 这对于物理存储器,可以直接理解为“不真实”、“虚假”的存储器。 例如,0x08000000存储器地址不是物理地址上的大的排列中的0x08000000 - 1的地址要素。

因为所有现代操作系统都提供了内存管理抽象,即虚拟内存(virtual memory )。 该进程使用虚拟内存中的地址来帮助操作系统执行相关的硬件,并将其“转换”为真正的物理地址。 这一“转变”是所有问题讨论的关键。

有了这样的抽象,程序可以使用比实际物理地址大得多的地址空间。 也可以在多个进程中使用相同的地址。 不足为奇。 因为转换后的物理地址不一样。

如果尝试反编译——连接后的程序,您会发现连接器为该程序分配了地址。 例如,要调用函数a,代码将是call0x0811111111,而不是call A。 也就是说,函数a的地址已经确定。 如果没有这样的“转换”,如果没有虚拟地址的概念,就不能这样做。

逻辑地址Intel为了兼容性,保留了太古时期的阶段性存储器管理方式。 逻辑地址是指在机器语言指令中用于指定操作数或指令的地址。 在上面的示例中,连接器分配给a的地址0x08111111是逻辑地址。

——,很抱歉。 这似乎违背了Intel中段管理中对逻辑地址的要求。 “逻辑地址是段标识符加上指定了段内相相对地址的偏移,表示为[段标识符:段内偏移]。 也就是说,以上示例中的0x08111111应该表示为[A的代码段标识符:x]

与逻辑地址(也称为线性地址(linear address )或虚拟地址)类似,但这也是不现实的地址。 如果逻辑地址是对应硬件平台的段管理预转换地址,则线性地址对应硬件页存储器的预转换地址。

地址转换第一步:CPU段式管理中——逻辑地址转线性地址

CPU利用段内存管理单元将逻辑地址转换为线程地址。

1个逻辑地址由【段识别符:段内偏移】2部分构成。

段标识符由称为段选择器的16位字段组成。 前13位是索引号。 接下来的三位包含如图所示的硬件详细信息。

段的段描述符是根据段标识符中的索引号从GDT或LDT中检索的。 段描述符中的base字段是段的开始地址

段描述符:用于描述段开始位置的线性地址的Base字段。

一些全局段描述符被放置在“全局段描述符表(GDT )”中,一些本地的(例如每个过程本身)被放置在所谓的“本地段描述符表(LDT )”中。

GDT内存中的地址和大小存储在CPU的gdtr控制寄存器中,LDT存储在ldtr寄存器中。

段开头地址段内偏移=线性地址

首先,给出完整的逻辑地址[段选择器:段内偏移地址],

1、查看段选择器的T1=0或1,知道当前要转换的是GDT段还是LDT段,并从相应的寄存器获得其地址和尺寸。 我们有一个数组。

2、取出段选择器的前13位,在该数组中可以找到对应的段描述符。 这样的话,就知道了Base,也就是基地址。

3、将Base offset转换为线性地址。

步骤1 :页面管理——从线性地址到物理地址

利用其页面内存管理单元,将其转换为最终的物理地址。

linux的虚假段管理

Intel要求进行两次转换。 虽说这样兼容,但也有冗余。 但是,这是Intel硬件的要求。

其他硬件平台没有二次变换的概念,Linux也需要高级抽象才能提供统一的接口。

所以,Linux的段管理实际上只是“欺骗”了硬件。

根据Intel的意图,全球使用GDT,每个进程都使用自己的LDT——,而Linux对所有进程使用同一段来寻址指令和数据。 也就是说,与用户段、用户代码段相对应,内核中的是内核段和内核代码段。

在Linux上,逻辑地址和线性地址始终匹配

的,即逻辑地址的偏移量字段的值与线性地址的值总是相同的。

linux页式管理

CPU的页式内存管理单元,负责把一个线性地址,最终翻译为一个物理地址。

线性地址被分为以固定长度为单位的组,称为页(page),例如一个32位的机器,线性地址最英勇的大雁为4G,可以用4KB为一个页来划分,这页,整个线性地址就被划分为一个tatol_page[2^20]的大数组,共有2的20个次方个页。

另一类“页”,我们称之为物理页,或者是页框、页桢的。是分页单元把所有的物理内存也划分为固定长度的管理单位,它的长度一般与内存页是一一对应的。

每个进程都有自己的页目录,当进程处于运行态的时候,其页目录地址存放在cr3寄存器中。

每一个32位的线性地址被划分为三部份,【页目录索引(10位):页表索引(10位):页内偏移(12位)】

依据以下步骤进行转换:

从cr3中取出进程的页目录地址(操作系统负责在调度进程的时候,把这个地址装入对应寄存器);

根据线性地址前十位,在数组中,找到对应的索引项,因为引入了二级管理模式,页目录中的项,不再是页的地址,而是一个页表的地址。(又引入了一个数组),页的地址被放到页表中去了。

根据线性地址的中间十位,在页表(也是数组)中找到页的起始地址;

将页的起始地址与线性地址中最后12位相加。

目的:

内存节约:如果一级页表中的一个页表条目为空,那么那所指的二级页表就根本不会存在。这表现出一种巨大的潜在节约,因为对于一个典型的程序,4GB虚拟地址空间的大部份都会是未分配的;

32位,PGD = 10bit,PUD = PMD = 0,table = 10bit,offset = 12bit

64位,PUD和PMD ≠ 0

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。