在虚拟地址空间那篇文章中我们简单地介绍了虚拟地址空间,知道了应用程序中使用的是虚拟地址,需要通过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,则直接取出页框地址访问。
快表实际上是一个单独的高速缓存寄存器,其大小通常受到限制,因此快表只能访问有限个表项。当虚拟地址空间切换时,快表也会切换,此时页面转换的消耗将大大增加。

总结

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

虚拟地址与物理地址的转换相关推荐

  1. ARM32页表-虚拟地址到物理地址的转换

    ARM32的页表 页表就是用于将虚拟地址转换为物理地址的转换关系表.访问虚拟地址时,计算机通过页表找到对应的实际物理地址访问. 我们在上一节介绍了内存管理模块概图, 怎么完成从pgd 到 page的转 ...

  2. OS实战笔记(4)-- 虚拟地址和物理地址的转换

    在大学的时候,<操作系统原理>这门课我没有好好听,里面讲到过虚拟地址的相关知识.虽然在大学的时候,接过一两个项目(代码写的很烂,哈哈),偶尔也会自己练习几个编程题.但对虚拟地址.物理地址的 ...

  3. 虚拟地址到物理地址的转换步骤【转】

    转自:http://www.cnblogs.com/RyanHuang/archive/2012/05/30/2525006.html 已知一个虚拟地址0x01AF5518, 则转换的过程如下: 注意 ...

  4. 虚拟地址到物理地址的转换步骤

    已知一个虚拟地址0x01AF5518, 则转换的过程如下: 注意: 这里讨论的以Windows下普通模式分页的情况, 也就是2级页表的情况 1.首先把虚拟地址拆分成3个部分(低12位, 中10位, 高 ...

  5. linux内核线性地址等于物理地址,Linux 从虚拟地址到物理地址

    我们都知道,动态共享库里面的函数的共享的,这也是动态库的优势所在,就是节省内存.C 编译出来的可执行文件几乎都会用到libc的库,假如没有这个共享的技术,每个可执行文件都要占一份libc库的内存,这将 ...

  6. Windows虚拟地址转物理地址(原理+源码实现,附简单小工具)

                                                                                                        ...

  7. 用户的虚拟地址 linux 0 4gb,Linux驱动虚拟地址和物理地址的映射

    一般情况下,Linux系统中,进程的4GB内存空间被划分成为两个部分------用户空间和内核空间,大小分别为0~3G,3~4G. 用户进程通常情况下,只能访问用户空间的虚拟地址,不能访问到内核空间. ...

  8. Linux虚拟地址和物理地址的映射

    ➤背景 一般情况下,Linux系统中,进程的4GB内存空间被划分成为两个部分------用户空间和内核空间,大小分别为0~3G,3~4G.用户进程通常情况下,只能访问用户空间的虚拟地址,不能访问到内核 ...

  9. 简单的键盘按键记录(无码)/虚拟地址转物理地址/生成随机字符串/计算字符串哈希

    最近看到 一个 样本 ,里面有键盘 按键记录的功能 ,而且 实现也比较 简单,运行 记录 的效果还 不错 .主要思路如下 : //假代码 int i=0;for(i=0;i<0x100;i++) ...

  10. 虚拟地址 虚拟内存 物理地址

    物理内存和虚拟内存 我们先来了解一下,什么是物理内存,什么又是虚拟内存? 1.物理内存:指通过物理内存条而获得的内存空间,主要作用是在计算机运行时为操作系统和各种程序提供临时储存. 2.虚拟内存:对内 ...

最新文章

  1. Vue2 利用 v-model 实现组件props双向绑定的优美解决方案
  2. java退出循环吗,在Java中退出循环
  3. 设计模式-装饰模式(Decorator Pattern)
  4. arthas class/classloader相关命令之一:sc、sm
  5. K8S集群的搭建:环境准备及相关命令
  6. 数学建模国赛 常考赛题类型(模拟退火算法、粒子群算法、遗传算法)
  7. frp 后台地址_Frp后台自动启动的几个方法
  8. Python个人项目--豆瓣图书个性化推荐
  9. linux c统计进程网络读写,linux网络分析、性能分析、文本格式化、文件读写操作之利器(mtr、top、jq、sponge)...
  10. linux改文件后run,linux下.run文件如何安装与卸载
  11. ThinkPHP3.2 下载、导入、导出功能的设计与实现
  12. unittest学习记录
  13. HDU 3001 三进制状压DP
  14. springboot集成与使用Sentinel
  15. 【回顾】推荐系统的十二大评价指标总结
  16. Jenkins+maven+SVN构建java项目中遇到的问题及解决
  17. 第二人生的源码分析(9)登录界面显示
  18. PostgreSQL 生成随机数字、字符串、日期、验证码以及 UUID
  19. Professor Forcing: A New Algorithm for Training Recurrent Networks翻译
  20. 列中的空值违反了非空约束_管理社区中违反准则的情况

热门文章

  1. 怎么在计算机里隐藏文件,怎么显示电脑隐藏文件?
  2. 长尾效应--Long Tail Effect
  3. 麻省理工学院计算机科学与工程博士,2020年麻省理工学院博士读几年
  4. git启动linux系统,gitlab 开机自动启动配置
  5. python中ix用法_Python:Pandas中的ix用法详细解释
  6. 基于torch学汪峰写歌词、聊天机器人、图像着色/生成、看图说话、字幕生成
  7. 语言的流变_拔剑-浆糊的传说_新浪博客
  8. 浅论三维标注技术的重要性
  9. SDN,虚拟化,TSN,协议概述。
  10. 软工学子带你一起学习工程经济学!献上与工作相关的实用公式(值得一进)