虚拟地址与物理地址的转换

article/2025/9/30 8:31:41

在虚拟地址空间那篇文章中我们简单地介绍了虚拟地址空间,知道了应用程序中使用的是虚拟地址,需要通过MMU转换成物理地址,本文将详细介绍虚拟地址如何转换成物理地址。

页、页框、页表

linux操作系统以页为单位管理虚拟内存,通常一页为4k,而物理内存是以块为单位管理的,物理内存被分成很多与页大小相同的块,被称为页框,每个页地址与页框对应,这种对应关系被记录在页表中,页表是MMU中的数据结构,下图是页表中较为常见的几个属性。
在这里插入图片描述
页框存在于物理内存上,而页可以放置在任意的页框中,这是能够进行地址转换的基础。

缺页异常

页表结构图中,p(存在位)表示虚拟地址对应的物理地址是否已经加载到内存中,如果虚拟地址没有被使用过,物理地址就不会加载到内存中,当需要使用虚拟地址时,操作系统先检查存在位,如果存在位为1则地址转换后可以直接访问,如果存在位为0,会引发缺页异常,操作系统将加载页框到内存中,然后继续访问。与普通中断不同的是,缺页异常返回后会再次执行陷入中断的那条指令,而普通中断会执行跳过该指令,执行下一条指令。

换页

操作系统通常使用页面缓存算法来管理已经加载的页,当操作系统通过缺页异常准备加载新页面时,如果缓存已满,就需要先删除一页,再加载新页,删除页时,需要检查D(脏位),如果D为1,说明该页被修改过,需要先写入磁盘,再删除。linux操作系统中,名为pdflush的守护进程会周期性地刷脏页。
换页时选择被删除的页通过页面缓存置换算法来实现,常见的算法包括先进先出算法(FIFO)、最佳置换算法(OPT)和最近最少使用算法(LRU)。linux使用LRU算法实现页面置换,这里提供一种LRU的简单实现。


//双向链表,也可以使用stl的list
struct linkedlist{linkedlist* prev;linkedlist* next;int value;int key;linkedlist():prev(nullptr),next(nullptr),key(0),value(0){};linkedlist(int p1,int p2):prev(nullptr),next(nullptr),key(p1),value(p2){};linkedlist(linkedlist* p1, linkedlist* p2, int q1,int q2):prev(p1), next(p2),key(q1),value(q2) {};
};class LRUCache {
public:LRUCache(int capacity) {_capacity = capacity;size = 0;head = new linkedlist(0, 0);tail = new linkedlist(head, nullptr, 0, 0);head->next = tail;}//获取页面时,更新该页面位置到最前int get(int key) {                       if(mp.find(key)==mp.end())return -1;moveToHead(mp[key]);return mp[key]->value;}//添加页面时,删除最后一个页面void put(int key, int value) {if(mp.find(key)==mp.end()){if(size==_capacity) {delTail();--size;}linkedlist* node = new linkedlist(key,value);mp[key] = node;addToHead(node);++size;}else{mp[key]->value = value;moveToHead(mp[key]);}return;}
private:linkedlist* head;linkedlist* tail;unordered_map<int,linkedlist*> mp;int size;int _capacity;void moveToHead(linkedlist* node){node = delNode(node);addToHead(node);}void addToHead(linkedlist* node){linkedlist* tmp = head->next;head->next = node;node->prev = head;node->next = tmp;tmp->prev = node;}linkedlist* delNode(linkedlist* node){linkedlist* p = node->prev;linkedlist* n = node->next;p->next = n;n->prev = p;node->next = nullptr;node->prev = nullptr;return node;}void delTail(){linkedlist* node = tail->prev;node = delNode(node);mp.erase(node->key);delete node;node = nullptr;}
};

OPT算法被称为完美但无法实现的页面置换算法,限于篇幅(困了)我们后续再介绍。

多级页表

使用段页式管理内存的操作系统将虚拟地址先通过段表转换为线性地址,再通过页表将线性地址转换为物理地址。Linux操作系统使用页式管理,虚拟地址就是线性地址,我们仅详细介绍线性地址到物理地址的转换。

在这里插入图片描述

如上图,在32位操作系统中,页目录表的基址被记录在CR3寄存器中,地址的高10位为页目录表的偏移,通过基址和偏移可以找到页表基址,地址中间10为页表的偏移,通过基址和偏移可以找到对应的页,地址低12位记录了页中的偏移,就能够查找到对应的物理地址了。

快表(TLB)

上面介绍的多级页表中包括一张页目录表和一张页表,需要多次跳转才能访问到物理地址,并且Linux的实际实现中,页目录表的数量还要更多。为了减少跳转带来的消耗,MMU引入了快表(TLB),快表个人理解就是一种缓存,将经常使用的页面及其页框直接记录在快表中,当需要访问物理地址时,先从TLB中寻找,如果命中TLB,则直接取出页框地址访问。
快表实际上是一个单独的高速缓存寄存器,其大小通常受到限制,因此快表只能访问有限个表项。当虚拟地址空间切换时,快表也会切换,此时页面转换的消耗将大大增加。

总结

本文较为深入地讨论了虚拟地址和物理地址的转换,相信大家都这个过程已经比较清楚,后续将对异常和中断进行介绍,帮助大家理解缺页异常的实际工作过程。


http://chatgpt.dhexx.cn/article/wN5fULRT.shtml

相关文章

Linux操作系统 虚拟地址空间

目录 1、一段代码引出一个问题 运行结果&#xff1a; 讨论&#xff1a; 2、Linux下进程虚拟地址空间分布 3、什么是虚拟地址空间&#xff1f; 4、虚拟地址出现之前&#xff1a;进程直接访问物理内存 5、再述虚拟地址空间 虚拟地址空间结构体是如何进行区域划分的呢&…

虚拟地址、虚拟内存、物理地址、物理内存

虚拟地址、虚拟内存、物理地址、物理内存 物理内存和虚拟内存虚拟地址、物理地址 物理内存和虚拟内存 物理内存 物理内存时有限的&#xff0c;当有多个进程要执行的时候&#xff0c;假设都要给4G内存&#xff0c;很显然你内存小一点&#xff0c;这很快就分配完了&#xff0c;…

虚拟地址空间【详解】 虚拟地址空间是什么 | 为什么要有虚拟地址空间

目录 一、什么是虚拟地址空间 / 虚拟地址空间是如何被设计的 1.先看一下linux空间分布 I.示意图: II.验证: 2. 在已知Linux内存分布之后&#xff0c;我们来看一个奇怪的现象 I.代码 : II. 输出: III.思考&#xff0c;引出--虚拟内存&#xff08;虚拟地址空间&#xff0…

虚拟地址转物理地址

概述 CPU是如何利用页目录和页表 等数据结构将一个32位的虚拟地址翻译为32位的物理地址的。其过程可以概括为如下步骤。 ① 通过CR3寄存器定位到页目录的起始地址&#xff0c;正因如此&#xff0c;CR3寄存器又称为页目录基地址寄存器&#xff08;PDBR&#xff09;。取线性地址…

虚拟地址与物理地址

虚拟地址 恰如其名&#xff0c;这个地址是虚拟的&#xff0c;与具体环境是解耦的&#xff0c;这样可以是程序员在编写程序时只需要关注代码逻辑本身&#xff0c;而不需要考虑地址分配。这些虚拟地址并不是真正运行在机器上的内存地址&#xff0c;每个程序的虚拟地址都是独立存在…

虚拟机ip地址

文章仅为自己在建立虚拟机过程中遇到的问题进行记录。 虚拟机查看IP地址输入 ip address 即可查看&#xff1b; 新建虚拟机的时候会遇到输入ip addr出现没有看到ip地址&#xff0c;例如如下情况时&#xff1a; 每个人上图可能会有不同显示&#xff0c;例如我的就是以eno16777…

浅谈虚拟地址转换成物理地址(值得收藏)

这里&#xff0c;我们讲解一下Linux是如何将虚拟地址转换成物理地址的 一、地址转换 在进程中&#xff0c;我们不直接对物理地址进行操作&#xff0c;CPU在运行时&#xff0c;指定的地址要经过MMU转换后才能访问到真正的物理内存。 地址转换的过程分为两部分&#xff0c;分段…

虚拟地址

虚拟地址 虚拟地址是程序运行在保护模式下&#xff0c;这样程序访问存储器所使用的逻辑地址称为虚拟地址。 那为什么需要虚拟地址呢 我们要说到寻址方式 寻址&#xff1a;根据指令内容确定操作数地址的过程&#xff0c;称为寻址 在16位的cup或者8086cpu的时候&#xff0c;他…

虚拟地址如何访问到物理地址

环境&#xff1a;32bit CPU 一、通过二级页表映射的方式访问物理地址 1、取一级页表的基地址Abase1 2、取虚拟地址的前12bit[31:20]地址O1 3、计算得到新地址Apgd(Abase1&0xFFFFF000)O1&#xff0c;此地址是PGD页表上的地址&#xff0c;取此地址中的数据Abase2 4、取虚拟地…

总线地址、物理地址、虚拟地址

1、总线地址 地址总线&#xff08;Address Bus&#xff09;是一种计算机总线&#xff0c;是CPU或有DMA能力的单元&#xff0c;用来沟通这些单元想要访问&#xff08;读取/写入&#xff09;计算机内存组件/地方的物理地址。 其实就是CPU能够访问内存的范围。 CPU寻找外部的内…

虚拟地址空间和物理地址空间

1.概念 物理地址&#xff1a;物理地址空间是实在的存在于计算机中的一个实体&#xff0c;在每一台计算机中保持唯一独立性。我们可以称它为物理内存&#xff1b;如在32位的机器上&#xff0c;物理空间的大小理论上可以达到2^32字节(4GB)&#xff0c;但如果实际装了512的内存&a…

Linux虚拟地址空间

目录 父子进程地址相同的变量值不同问题运行结果 Linux下进程虚拟地址空间分布什么是虚拟地址空间&#xff1f;进程直接访问物理内存&#xff08;无虚拟空间&#xff09;再述虚拟地址空间&#xff01;虚拟地址空间结构体是如何区域划分?解答最初的问题延伸问题: 一个pid变量怎…

虚拟地址空间

对于每一个进程都会对应一个虚拟地址空间&#xff0c;对于32位的操作系统&#xff08;其指令的位数最大为32位&#xff0c;因此地址码最多32位&#xff09;&#xff0c;虚拟地址空间的大小为B即0~4GB的虚拟地址空间&#xff0c;其中内核空间为1GB&#xff0c;如下所示&#xff…

逻辑地址、物理地址、虚拟地址

文章目录 物理地址(physical address)虚拟地址(virtual memory)逻辑地址(logical address)线性地址(linear address)或也叫虚拟地址(virtual address)地址转换 物理地址(physical address) 用于内存芯片级的单元寻址&#xff0c;与处理器和CPU连接的地址总线相对应。 虽然可以…

CPU中虚拟地址、逻辑地址(有效地址)、线性地址、物理地址

虚拟地址、逻辑地址&#xff08;有效地址&#xff09;、线性地址、物理地址 1、虚拟地址2、逻辑地址&#xff08;有效地址&#xff09;3、线性地址4、物理地址5、总结 1、虚拟地址 在实模式下&#xff0c;虚拟地址是指由程序产生的由段选择符和段内偏移地址组成的地址。经过CPU…

虚拟地址和物理地址

1、地址概念 物理地址&#xff1a;物理内存就是真实的内存&#xff0c;CPU的地址线可以直接进行寻址的内存空间大小。比如在32位平台下&#xff0c;寻址的范围是2^32也就是4G&#xff0c;并且这是固定的。在实际的应用中&#xff0c;很多的应用程序都比较大&#xff0c;计算机…

Linux操作系统~什么是虚拟地址?深度剖析进程地址空间

目录 1.所以进程的地址空间是什么呢&#xff1f; 2.mm_struct内部有什么&#xff1f; 3.虚拟地址空间与物理内存如何关联 页表 4.为什么设计这样一个进程地址空间&#xff0c;不让程序直接访问内存 Q&#xff1a;为什么子进程修改值以后&#xff0c;地址还是相同&#xf…

初识虚拟地址空间

物理地址和虚拟地址 物理寻址&#xff1a;CPU访问存储器的最原始方法就是直接用物理地址&#xff08;Physical Address, 可简称PA&#xff09;。物理地址是唯一的。 虚拟寻址&#xff1a;CPU通过生成一个虚拟的地址来访问内存&#xff0c;在访问前会把虚拟地址转化为物理地址…

虚拟地址空间,虚拟文件系统

1、虚拟地址空间 1、概念与原因 虚拟地址空间是一个抽象的概念&#xff0c;在IBM中&#xff0c;这样说道&#xff1a;它存在&#xff0c;但你看不见&#xff0c;就是虚拟的。虚拟地址空间就是这样一个东西。&#xff08;注意区分虚拟内存与虚拟地址空间&#xff09; 虚拟地址空…

彻底搞懂虚拟内存,虚拟地址,虚拟地址空间

程序经过编译后&#xff0c;变成了可执行的文件&#xff0c;可执行文件主要包括代码和数据两部分&#xff0c;代码是只读的&#xff0c;数据则是可读可写的。 可执行文件由操作系统加载到内存中&#xff0c;交由CPU去执行&#xff0c;现在问题来了&#xff0c;CPU怎么去访问代…