这个分页,主要是在mit6.828的lab2的背景下来说的。

Mit6.828 Lab2:http://pdos.csail.mit.edu/6.828/2014/labs/lab2/

lab2主要讲虚拟内存->物理内存的变换,通过一定的函数来实现软件MMU的部分。

整个地址转化的过程如下图所示:

首先,明确一点,在程序里面的所有地址,都是虚拟地址,程序里面是不会出现物理地址的,就算是物理地址,CPU也会把它当做虚拟地址,通过MMU转化为物理地址。

通过上面的图,可以知道,在系统中,CPU得到一个虚拟地址,这个虚拟地址是logical address,通过分段翻译后,会得到一个线性地址(linear address),线性地址通过分页翻译后,就可以得到物理地址了。

在lab2里,分段机制基本就没有,所以可以直接认为cpu得到的虚拟地址就是线性地址,只需要经过page translation 就可以得到物理地址了。下面,就来讲一下系统分页的详细过程。

如下图所示,就是线性地址通过page director  和 page table转化成物理地址的过程:

这张图是从虚拟地址来的,所以包含了分段的过程。其实,分段过程也比较简单,以C程序举例,在C中,所有的指针,它的值是一个偏移量,这个偏移量要加上段基址,得到一个线性地址。而前面的偏移量+段基址的过程,就是分段的过程。

在一个程序中,一般分为堆,栈,代码段,数据段(.date和.bss等),而指针的值,就是相应的段上的偏移量,如一个指针指向的是一个全局变量,则它的线性地址位P+.date的基址。这个过程就是分段。在lab2里面,分段基址好像暂时没怎么涉及,所以暂且不管它。好像想在操作系统多是分页,分段应该不多了。分段和分页主要的区别就是分页的页框是固定大小的,不变的。而分段,每一段的大小都是不定的。分段有利于程序的编译。这一块还要在看看书,还是有点不了解。

分页:

在lab2中,主要就是分页的各种东西。在jos系统里面,采用二级页表的分页形式。即分为page directory 和 page table两级页表。

二级页表好处:在32位系统中,理论上来说,每个进程都拥有独立的地址空间,其大小是2^32=4G,如果采用一级页表,则以4K的页框大小为例,要分配2^20个页面来给程序使用,每个页面占4字节,则光地址转换的页面就需要4*2^20=4M大小(page table的大小)了。这对于以前比较小的内存来说,是非常的大的。虽然现在内存都有几个G,但是如果64位操作系统也用一级页表分页的话,内存塞满了都放不下转换页……。

对于大多数的程序,我并不需要使用4G的内存空间,比如编写一个非常简单的排序程序,如果数据量不是很大的话,应该总共加起来连1M的内存都用不到,这样,总共实际用到的页面就只有2^8=256个页面,占的内存只有256*4=1024=1k,剩下的大部分存这的转换部分的内存都是没用的,这就表明了一级页表的空间利用率其实是非常低的,存在着大量的浪费。

所以,要使用二级页表来进行分页。二级页表实在一级页表的基础上进一步转化而来。以32位系统为例,假设页面大小位4K,一级页表是把低位的12位作为页内偏移,高位的20位作为页索引。而二级页表,把低位的12位作为页内偏移,高位的10位作为page directory(PDE)的索引,中间的的10位作为page table(PTE)。所以,以上面那个排序程序为例,如果他只用到了部分的页面,根据程序页面的局部性原理,这些页面会集中在某几个”块“内,所以对于第一级的PDE来说,这些页面都会集中在少数的几个PDE中,只需要为那几个映射到的PDE创建相应的二级页表(即PTE),而其他没有被映射到的PDE都不用创建对应的二级页表,这样,相对于一级页表的创建所有的页面映射,二级页表只创建相应的页面映射,虽然也会有所浪费,当相对来说还是节省了大量的内存空间。

二级页表分页过程:

二级页表分页过程比较简单,首先,PDE的入口地址存储在CR3寄存器中,读取CR3寄存器的高位(20位),低12位根据线性地址的高10位得到(由于32位系统中,地址占4字节,所以每一个页表占4字节,和数组是同理:int a[10]; a[1]的地址是a[0]+4而不是+1,所以2^10个页表需要12位地址)。

通过上述过程得到的PDE,取出存在PDE中的PTE的地址,将PTE的低12位清零,然后中间10位作为索引,得到相应的物理地址的基址,最后通过低12位相加,得到对应的物理地址。转换过程不涉及很难的地方,比较简单。

这里说一下CR3,CR3保存PDE的地址,所以在进程切换之后,只需要改变CR3中的值,就可以直接切换进程的地址空间,非常的方便。

而上面的PWT表示是否采用回写策略,若PWT置位,则表示采用通写策略,即写缓存数据的同时,必须写外存。PWT=0表示回写,即写缓存数据,不必改变外存,等到缓存页面被置换,在写外存。

PCD表示是否开启缓存页。PCD=1表示禁用缓存页。PCD=0,表示启用缓存页。这个主要是因为有些页面对应的I/O端口需要实时采集数据,不能缓存数据,因为缓存的数据和实时数据有差别,所以需要禁用缓存页。这个在嵌入式里面应该出现的比较多。

最后一点,这些过程为了保证快速性,全部都是由硬件完成的,而在CR3寄存器,PDE,PGE中存储的地址,都是物理地址,而不是相对应的虚拟地址。

版权声明:本文为博主原创文章,未经博主允许不得转载。

MIT6.828 虚拟地址转化为物理地址——二级分页的更多相关文章

  1. MIT6.828 JOS系统 lab2

    MIT6.828 LAB2:http://pdos.csail.mit.edu/6.828/2014/labs/lab2/ LAB2里面主要讲的是系统的分页过程,还有就是简单的虚拟地址到物理地址的过程 ...

  2. MIT6.828 Lab2 内存管理

    Lab2 0. 任务介绍 你将编写一个内存管理代码.主要分为两大部分.分别对物理内存和虚拟内存的管理. 对于物理内存,每次分配内存分配器会为你分配4096bytes.也称为一个页(在大部分操作系统中一 ...

  3. MIT6.828课程JOS在macOS下的环境配置

    本文将介绍如何在macOS下配置MIT6.828 JOS实验的环境. 写JOS之前,在网上搜寻JOS的开发环境,很多博客和文章都提到"不是32位linux就不好配置,会浪费大量时间在配置环境 ...

  4. Linux下如何在进程中获取虚拟地址对应的物理地址【转】

    转自:http://blog.csdn.net/kongkongkkk/article/details/74366200 如果让你编写一个程序,来获取虚拟地址对应的物理地址..你会试着操作MMU吗.. ...

  5. 【MIT6.828】centos7下使用Qemu搭建xv6运行环境

    title:[MIT6.828]centos7下使用Qemu搭建xv6运行环境 date: "2020-05-05" [MIT6.828]centos7下搭建xv6运行环境 1. ...

  6. MIT6.828准备:MacOS下搭建xv6和risc-v环境

    本文介绍在MacOS下搭建Mit6.828/6.S081 fall2019实验环境的详细过程,包括riscv工具链.qemu和xv6,对于Linux系统同样可以参考. 介绍 只有了解底层原理才能写好上 ...

  7. mit-6.828 Lab Tools

    Lab Tools 目录 Lab Tools 写在前面 GDB GNU GPL (通用公共许可证) QEMU ELF 可执行文件的格式 Verbose mode Makefile 写在前面 操作系统小 ...

  8. mit-6.828 Lab01:Booting a PC exercise1.1

    Lab01:Booting a PC 目录 Lab01:Booting a PC JOS BIOS 背景知识 8086的基本知识 GDB 常用调试指令 Real mode && Pro ...

  9. MIT6.828 Preemptive Multitasking(上)

    Lab4 Preemptive Multitasking(上) PartA : 多处理器支持和协作多任务 在实验的这部分中,我们首先拓展jos使其运行在多处理器系统上,然后实现jos内核一些系统功能调 ...

随机推荐

  1. 畅通project(杭电1863)

    畅通project Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  2. Android二维码开源项目zxing编译

    ZXing是一个开放源代码的,用Java实现的多种格式的1D/2D条码图像处理库,它包括了联系到其它语言的port.Zxing能够实现使用手机的内置的摄像头完毕条形码的扫描及解码.该项目可实现的条形码 ...

  3. 初识动画animation

    工作半年了,基本没怎么用到动画,现在对已学到的动画做一个总结(真的非常非常基础啊啊啊),准备之后再慢慢研究一下动画(有好的教程可以推荐给我咩~~). animation animation:mymov ...

  4. Android环境开发搭建

    今天第一次接触安卓,从开发环境的配置到程序的运行,足足搞了一天,也没有整出来. 1.安装JDK 在JDK官网上下载了最新的JDK,安装成功后进行环境的配置.JAVA_HOME:C:\Program F ...

  5. mysql 重启

    /etc/init.d/mysql restart /etc/init.d/mysql stop /etc/init.d/mysql start

  6. Subsets,Subsets II

    一.Subsets Given a set of distinct integers, nums, return all possible subsets. Note: Elements in a s ...

  7. 内存泄漏工具VLD1.0_要点分析

    0X01 关闭FPO优化 // Frame pointer omission (FPO) optimization should be turned off for this // entire fi ...

  8. linux下的gdb调试工具--内存调试

    接着上一节的代码,在while(1)的循环里面增加代码:sum=0 #include <stdio.h> int main(void) { int sum = 0, i = 0; char ...

  9. 关于ASP .Net Core 引用dll 一

    一:ASP.Net Core 引用dll文件,不可以直接引用,必须在NuGet中引用才行. 二:如果想引用自己的dll文件,则需要注册NeGet账号,获取到API Key 才行,还需要下载NuGet安 ...

  10. 如何创建javascript只读变量

    最近学习了一下ES标准,发现其实有很多直接间接的方法实现一个只读变量,这里总结一下. 1.最直接的是利用对象属性的特性来实现: var obj = {pro1:1}; Object.definePro ...