当前位置: 首页 > 面试题库 >

请问虚拟内存和物理内存怎么对应

井兴怀
2023-03-14
本文向大家介绍请问虚拟内存和物理内存怎么对应相关面试题,主要包含被问及请问虚拟内存和物理内存怎么对应时的应答技巧和注意事项,需要的朋友参考一下

参考回答:

1、概念:

物理地址(physical address)

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

 

虽然可以直接把物理地址理解成插在机器上那根内存本身,把内存看成一个从0字节一直到最大空量逐字节的编号的大数组,然后把这个数组叫做物理地址,但是事实上,这只是一个硬件提供给软件的抽像,内存的寻址方式并不是这样。所以,说它是“与地址总线相对应”,是更贴切一些,不过抛开对物理内存寻址方式的考虑,直接把物理地址与物理的内存一一对应,也是可以接受的。也许错误的理解更利于形而上的抽像。

 

虚拟地址(virtual memory)

这是对整个内存(不要与机器上插那条对上号)的抽像描述。它是相对于物理内存来讲的,可以直接理解成“不直实的”,“假的”内存,例如,一个0x08000000内存地址,它并不对就物理地址上那个大数组中0x08000000 - 1那个地址元素;

 

之所以是这样,是因为现代操作系统都提供了一种内存管理的抽像,即虚拟内存(virtual memory)。进程使用虚拟内存中的地址,由操作系统协助相关硬件,把它“转换”成真正的物理地址。这个“转换”,是所有问题讨论的关键。

 

有了这样的抽像,一个程序,就可以使用比真实物理地址大得多的地址空间。甚至多个进程可以使用相同的地址。不奇怪,因为转换后的物理地址并非相同的。

 

——可以把连接后的程序反编译看一下,发现连接器已经为程序分配了一个地址,例如,要调用某个函数A,代码不是call A,而是call 0x0811111111 ,也就是说,函数A的地址已经被定下来了。没有这样的“转换”,没有虚拟地址的概念,这样做是根本行不通的。

 

2、地址转换

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

CPU要利用其段式内存管理单元,先将为个逻辑地址转换成一个线程地址。

一个逻辑地址由两部份组成,【段标识符:段内偏移量】。

段标识符是由一个16位长的字段组成,称为段选择符。其中前13位是一个索引号。后面3位包含一些硬件细节,如图:

img

通过段标识符中的索引号从GDT或者LDT找到该段的段描述符,段描述符中的base字段是段的起始地址

 

段描述符:Base字段,它描述了一个段的开始位置的线性地址。

 

一些全局的段描述符,就放在“全局段描述符表(GDT)”中,一些局部的,例如每个进程自己的,就放在所谓的“局部段描述符表(LDT)”中。

 

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

段起始地址+ 段内偏移量 = 线性地址

img

首先,给定一个完整的逻辑地址[段选择符:段内偏移地址],

1、看段选择符的T1=0还是1,知道当前要转换是GDT中的段,还是LDT中的段,再根据相应寄存器,得到其地址和大小。我们就有了一个数组了。

2、拿出段选择符中前13位,可以在这个数组中,查找到对应的段描述符,这样,它了Base,即基地址就知道了。

3、把Base + offset,就是要转换的线性地址了。

img

第一步:页式管理——线性地址转物理地址

 

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

 

linux假的段式管理

 

Intel要求两次转换,这样虽说是兼容了,但是却是很冗余,但是这是intel硬件的要求。

 

其它某些硬件平台,没有二次转换的概念,Linux也需要提供一个高层抽像,来提供一个统一的界面。

 

所以,Linux的段式管理,事实上只是“哄骗”了一下硬件而已。

 

按照Intel的本意,全局的用GDT,每个进程自己的用LDT——不过Linux则对所有的进程都使用了相同的段来对指令和数据寻址。即用户数据段,用户代码段,对应的,内核中的是内核数据段和内核代码段。

 

在Linux下,html" target="_blank">逻辑地址与线性地址总是一致的,即逻辑地址的偏移量字段的值与线性地址的值总是相同的。

 

linux页式管理

 

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

 

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

 

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

img

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

 

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

 

依据以下步骤进行转换:

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

 

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

 

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

 

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

 

目的:

 

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

img

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

64位,PUD和PMD ≠ 0

 类似资料:
  • 我们都知道,直接从内存读写数据要比从硬盘读写数据快得多,因此更希望所有数据的读取和写入都在内存中完成,然而内存是有限的,这样就引出了物理内存与虚拟内存的概念。 物理内存就是系统硬件提供的内存大小,是真正的内存。相对于物理内存,在 Linux 下还有一个虚拟内存的概念,虚拟内存是为了满足物理内存的不足而提出的策略,它是利用磁盘空间虚拟出的一块逻辑内存。用作虚拟内存的磁盘空间被称为 交换空间(又称  

  • 在与 GDT 相关的章节中,我们知道分段物理内存地址使用的是段选择和计算偏移(Linux在X86上的虚拟内存管理) 在本章中,我们将实现内存的分页功能,其原理是将分段的线性地址转换成物理地址(分页表存储了虚拟(线性)地址到物理地址间的映射)。 为什么我们需要分页管理内存? 内存分页将允许我们的内核: 为避免歧义,保留部分原文 use the hard-drive as a memory and n

  • 归功于 GRUB ,在启动后,内核可以知道可用物理内存的大小。 在实现操作系统时,前 8Mb 字节的物理内存将被内核保留使用,这些内存被用来存放: The kernel 内核 GDT, IDT et TSS Kernel Stack 内核栈 Some space reserved to hardware (video memory, ...) 保留硬件所需空间 Page directory and

  • 主要内容:虚拟内存如何工作?,按需分页,虚拟内存管理系统的快照虚拟内存是一种存储方案,为用户提供了一个拥有非常大的主内存的幻觉。 这是通过将辅助存储器的一部分作为主存储器来完成的。 在这种方案中,用户可以加载比可用主存更大的进程,因为存在内存可用于加载进程的错觉。 操作系统不是在主内存中加载一个大进程,而是在主内存中加载多个进程的不同部分。 通过这样做,多程序的程度将会增加,因此CPU利用率也会增加。 虚拟内存如何工作? 在现代语言中,虚拟内存近来变得非常普

  • 1、虚拟内存的基本概念 上一节所讨论的各种内存管理策略都是为了同时将多个进程保存在内存中以便允许多道程序设计。他们都具有以下两个共同特征: 1)一次性:作业必须一次性全部装入内存后,方可运行。这会导致两种情况发生:1当作业很大,不能全部被装入内存时,将使该作业无法运行;2当大量作业要求运行时,由于内存不足以容纳所有作业,只能使少数作业先运行,导致系统难以运行多道程序。 2)驻留性:作业被装入内存后

  • 5. 虚拟内存管理 我们知道操作系统利用体系结构提供的VA到PA的转换机制实现虚拟内存管理。有了共享库的基础知识之后,现在我们可以进一步理解虚拟内存管理了。首先分析一个例子: $ ps PID TTY TIME CMD 29977 pts/0 00:00:00 bash 30032 pts/0 00:00:00 ps $ cat /proc/29977/maps