一步步编写操作系统 39 二级页表1

前面讲述了页表的原理,并以一级页表做为原型讲述了地址转换过程。既然有了一级页表,为什么还要搞个二级页表呢?理由如下:

  1. 一级页表中最多可容纳1M(1048576)个页表项,每个页表项是4字节,如果页表项全满的话,便是4MB大小。
  2. 一级页表中所有页表项必须要提前建好,原因是操作系统要占用4GB虚拟地址空间的高1GB,用户进程要占用低3GB。
  3. 每个进程都有自己的页表,进程一多,光是页表占用的空间就很可观了。

归根结底,我们要解决的是:不要一次性地将全部页表项建好,需要时动态创建页表项。如何解决呢?

二级页表很好的解决了该问题。我们来说下,什么是二级页表。

无论是几级页表,标准页的尺寸都是4KB,这一点是不变的。所以4GB线性地址空间最多有1M个标准页。一级页表是将这1M个标准页放置到一张页表中,二级页表是将这1M个标准页平均放置1K个页表中。每个页表中包含有1K个页表项。页表项是4字节大小,页表包含1K个页表项,故页表大小为4KB,这恰恰是一个标准页的大小。

拆分出了这么多个页表,如何使用它们呢?为此,专门有个页目录表来存储这些页表。每个页表的物理地址在页目录表中都以页目录项PDE(Page Directory Entry)的形式存储,页目录项大小同页表项一样,都是用来描述一个物理页的物理地址,其大小都是4字节,而且最多有1024个页表,所以页目录表也是4KB大小,同样也是标准页的大小。

页表是用于管理内存的数据结构,其也要占用内存,所以页目录表和页表所占用的物理页,同样是混迹于物理内存之中,如图

页目录表中共1024个页表,也就是有1024个页目录项。一个页目录项中记录一个页表物理页地址,物理页地址是指页的物理地址,在页目录项及页表项中记录的都是页的物理地址,由于页大小都是0x1000,即4096,因此页地址是以000为结尾的16进制数字。每个页表中有1024个页表项,每个页表项中是一个物理页地址,最终数据是写在这页表项中指定的物理页中。页表项中分配的物理页地址在真正物理内存中离散颁布,毫无规律可言,操作系统负责这些物理页的分配与释放。由于页目录表和页表本身都要占用内存,且为4KB大小,故它们也会由操作系统在物理内存中分配一物理页存放。图中最粗的线是存放页目录表物理页,稍细一点的线指向的是用来存放页表的物理页,其它最细的线是页表项中分配的物理页,页表结构本身与其它数据混布渗透在物理内存中,页表所占用的物理页在外在形式上与其它数据占用的物理页没有什么不同,只有cpu知道它们的作用不同。页表在建立之初,物理内存各部分的布局还是相对较整洁的,随着操作系统分配或释放内存的动作越来越频繁,物理内存的布局将更加零散。

二级页表与一级页表在原理上相同,但结构上已经有了很大不同,它们在虚拟地址到物理地址转换方法上也很大不同。

我们已经知道,前面所说的一级页表转换方法,是将32位虚拟地址拆分成两部分,高20位用于定位一个物理页,低12位用于物理页内的偏移量。在二级页表转换中,依然是用32位虚拟地址的不同部分来定位物理页。

在二级页表是这样的:每个页表中可容纳1024个物理页,故每个页表可表示的内存容量是1024*4KB=4MB。页目录中共有1024个页表,故所有页表可表示的内存容量是1024*4MB=4GB,这已经达到了32位地址空间的最大容量。所以说,任意一个32位物理地址,它必然在某个页表之内的某个物理页中。我们定位某一个物理页,必然要先找到其所属的页表。页目录中1024个页表,只需要10位二进制就能够表示了,所以,虚拟地址的高10位(第31~22位)用来在页目录中定位一个页表,也就是这高10位用于定位页目录中的页目录项PDE,PDE中有页表物理页地址。找到页表后,到底是页表中哪一个物理页呢?由于页表中可容纳1024个物理页,故只需要10位二进制就能够表示了。所以虚拟地址的中间10位(第21~12位)用来在页表中定位具体的物理页,也就是在页表中定位一个页表项PTE,PTE中有分配的物理页地址。由于标准页都是4KB,12位二进制便可以表达4KB之内的任意地址,故线性地址中余下的12位(第11~0位)用于页内偏移量。

经以上分析,二级页表地址转换原理是,将32位虚拟地址拆分成高10位、中间10位、低12位三部分,它们的作用是:高10位做为页表的索引,用于在页目录表中定位一个页目录项PDE,页目录项中有页表物理地址,也就是定位到了某个页表。中间10位做为物理页的索引,用于在页表内定位到某个页表项PTE,页表项中有分配的物理页地址,也就是定位到了某个物理页。低12位做为页内偏移量用于在已经定位到的物理页内寻址。

同一级页表一样,访问任何页表内的数据都要通过物理地址。由于页目录项PDE和页表项PTE都是4字节大小,给出了PDE和PTE索引后,还需要在背后悄悄乘以4,再加上页表物理地址,这才是最终要访问的绝对物理地址。转换过程背后的具体步骤是:

  1. 用虚拟地址的高10位乘以4,做为页目录表内的偏移地址,加上页目录表的物理地址,所得的和,便是页目录项的物理地址。读取该页目录项,从中获取到页表的物理地址。
  2. 用虚拟地址的中间10位乘以4,做为页表内的偏移地址,加上在第1步中得到的页表物理地址,所得的和,便是页表项的物理地址。读取该页表项,从中获取到分配的物理页地址。
  3. 虚拟地址的高10位和中间10位分别是PDE和PTE的索引值,所以它们需要乘以4。但低12位就不是索引值啦,其表示的范围是0~0xfff,做为页内偏移最合适,所以虚拟地址的低12位加上第2步中得到的物理页地址,所得的和便是最终转换的物理地址。

这种自动化较强的工作,还是由页部件自动完成的,

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/439720.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PointNet++详解与代码

在之前的一篇文章《PointNet:3D点集分类与分割深度学习模型》中分析了PointNet网络是如何进行3D点云数据分类与分割的。但是PointNet存在的一个缺点是无法获得局部特征,这使得它很难对复杂场景进行分析。在PointNet中,作者通过两个主要的方法…

一步步编写操作系统 40 内存分页下用户程序与操作系统的关系

分页的第一步要准备好一个页表,我们的页表是什么样子呢?现在我们要设计一个页表啦。 设计页表其实就是设计内存布局,不过在规划内存布局之前,我们需要了解用户进程与操作系统之间的关系。 前面讲保护模式时,我们知道…

一步步编写操作系统 41 快表tlb 简介

分页机制虽然很灵活,但您也看到了,为了实现虚拟地址到物理地址的映射,过程还是有些麻烦的。先要从CR3寄存器中获取页目录表物理地址,然后用虚拟地址的高10位乘以4的积做为在页目录表中的偏移量去寻址目录项pde,从pde中…

50个最有用的Matplotlib数据分析与可视化图

本文介绍了数据分析与可视化中最有用的50个数据分析图,共分为7大类:Correlation、Deviation、RankIng、Distribution、Composition、Change、Groups 原文链接:https://www.machinelearningplus.com/plots/top-50-matplotlib-visualizations-t…

视觉SLAM十四讲(1):预备知识

最近在学习高翔博士的《视觉SLAM十四讲》(第二版),算是初学本书,配套资源还算蛮丰富的,有代码(第一版和第二版都有),B站上也有高翔博士对第一版录制的讲解视频,真的是很贴…

一步步编写操作系统 43 汇编语言和c语言的理解

也许有的同学喜欢用汇编语言来实现操作系统,觉得用汇编来写程序似乎更简单直接,可控性比较强,有种“一切尽在掌握”的赶脚。而用c语言实现操作系统这件事,虽然轻松很多,但似乎隐约感觉到有些慌张。因为虽然c语言相对来…

视觉SLAM十四讲(2):初识SLAM

这一讲主要介绍视觉SLAM的结构,并完成第一个SLAM程序:HelloSLAM。 目录 2.1 小萝卜的例子 单目相机 双目相机 深度相机 2.2 经典视觉SLAM框架 2.3 SLAM问题的数学表述 2.4 编程实践 Hello SLAM 使用cmake 使用库 【高翔】视觉SLAM十四讲2.1 小…

一步步编写操作系统 44 用c语言编写内核1

先来个简单的,欢迎我们神秘嘉宾——main.c。这是我们第一个c语言代码。 1 int main(void) { 2 while(1); 3 return 0; 4 }它没法再简单啦,简单的程序似乎能帮助咱们更容易的理解所学的知识,哈哈,我说的是似乎,其实&…

从零实现一个3D目标检测算法(1):3D目标检测概述

本文是根据github上的开源项目:https://github.com/open-mmlab/OpenPCDet整理而来,在此表示感谢,强烈推荐大家去关注。使用的预训练模型也为此项目中提供的模型,不过此项目已更新为v0.2版,与本文中代码略有不同。 本文…

一步步编写操作系统 45 用c语言编写内核2

在linux下用于链接的程序是ld,链接有一个好处,可以指定最终生成的可执行文件的起始虚拟地址。它是用-Ttext参数来指定的,所以咱们可以执行以下命令完成链接: ld kernel/main.o -Ttext 0xc0001500 -e main -o kernel/kernel.bin …

使用OpenCV库快速求解相机内参

本文主要介绍如何使用OpenCV库函数求解相机内参。具体可查阅官网:https://docs.opencv.org/master/dc/dbb/tutorial_py_calibration.html。 关于相机内参的求解还有很多其它的工具,如使用MATLAB求解会更方便,直接调用MATLAB中的APP即可。 1.背…

一步步编写操作系统 46 用c语言编写内核3

再把上节代码贴出来, 1 //int main(void) { 2 int _start(void) { 3 while(1); 4 return 0; 5 }有没有同学想过,这里写一个_start函数,让其调用main函数如何?其实这是可以的,main函数并不是第一个函数,它实…

一步步编写操作系统 47 48 二进制程序运行方式

操作系统并不是在功能上给予用户的支持,这种支持是体现在机制上。也就是说,单纯的操作系统,用户拿它什么都做不了,用户需要的是某种功能。而操作系统仅仅是个提供支持的平台。 虽然我们是模仿linux来写一个黑屏白字的系统&#x…

百度顶会论文复现(1):课程概述

最近百度推出了一款重磅课程《全球顶会论文作者,28天免费手把手带你复现顶会论文》。这个课程真的是很硬核的课程,这里简单记录下自己的学习过程。 文章目录1. 课程设计思路和安排2. 课程大纲1. 课程设计思路和安排 课程设计思路如下,共分为…

百度顶会论文复现(2):GAN综述

本节课主要是对GAN的发展进行了介绍,包括基本原理,训练方法,存在问题,改进以及应用场景等。实践作业则为手写数字生成。课程地址为:https://aistudio.baidu.com/aistudio/education/preview/493290。 文章目录1.什么是…

一步步编写操作系统 48 二进制程序的加载方式

接上节,程序头可以自定义,只要我们按照自己定义的格式去解析就行。也许我光这么一说,很多同学还是不能彻底明白如何自定义文件头,因为大多数同学都是用高级语言来写程序,即使用了偏底层的c语言,不同平台的c…

百度顶会论文复现(3):视频分类综述

本节课主要是对视频分类的发展进行了介绍,包括任务与背景,分类方法,前沿进展等。课程地址为:https://aistudio.baidu.com/aistudio/course/introduce/1340?directly1&shared1。 文章目录1. 任务与背景2. 视频分类方法2.1 双流…

一步步编写操作系统 46 linux的elf可执行文件格式1

ELF文件格式依然是分为文件头和文件体两部分,只是该文件头相对稍显复杂,类似层次化结构,先用个ELF header从“全局上”给出程序文件的组织结构,概要出程序中其它头表的位置大小等信息,如程序头表的大小及位置、节头表的…

百度顶会论文复现(4):飞桨API详解

本节课主要是对飞桨常用API进行了介绍,课程地址为:https://aistudio.baidu.com/aistudio/education/group/info/1340。 文章目录1.飞桨API官网2. API使用介绍3. 飞桨模型操作1.飞桨API官网 官网地址为:https://www.paddlepaddle.org.cn/docu…

一步步编写操作系统 47 elf格式文件分析实验

在上一节中,我们讲述了elf格式的部分理论知识,为什么是部分呢?因为我们本着“够用”的原则,只把我们需要了解的部分说完啦。不过,我相信大部分同学仅仅凭上一节中的理论知识还是领悟不到elf本质,咱们在本节…