利用Nachos操作系统研究和实验虚拟内存

减小字体 增大字体 作者:张鸿烈  来源:www.zhonghualunwen.com  发布时间:2009-09-03 10:55:32

关键词:操作系统;虚拟内存;实践教学;Nachos

摘要:本文分析和论述了如何利用教学指导型操作系统Nachos研究和实验虚拟内存。通过详细的实例设计与分析,阐述了在Nachos操作系统中如何构建虚拟内存,如何实现虚拟内存的各种调度算法;如何实验和分析虚拟内存的工作过程和性能。对虚拟内存的教学和科研具有一定的指导辅助作用。
  1引言
  
  虚拟内存的实现和运行同时涉及到内存管理、调度与中断、文件系统等内核诸多方面的问题。因此在操作系统的教学和实验中虚拟内存的讲解和实验是较为棘手和困难的一个问题。为了能够讲清虚拟内存的基本构造和工作原理或想独立实践一下虚拟内存的构造和各种虚拟内存策略,我们可以利用一下教学指导型操作系统Nachos。由于Nachos提供了一个自由构造虚拟内存的框架,可让我们在其上开发和构造自主设计的虚拟内存,辅助我们更好的开展好虚拟内存的教学和研究。
  
  2内存管理和虚拟内存构造机制
  
  Nachos在它的页表机制中仅提供了可让用户构造虚拟内存的基本机制。页表结构是由TranslationEntry 类定义的,该定义在文件machine/translation.h中:
  
  class TranslationEntry {
   public:
  int virtualPage; //逻辑页号
  int physicalPage; //物理页号
  bool valid; //有效位
  bool readOnly; //只读位
  bool use; //引用位
  bool dirty; //修改位
   };
  
  为了实现虚拟内存的页置换,我们需要在以上类中增加一个该页在文件中的块偏量:int inFilePage。
  原始的Nachos内存无法实现多道程序同时驻留内存,为此可以为其增设了分段式内存管理,从而实现了多道程序同时驻留内存并发执行。增设的段式内存管理
  
  机制的类结构为:
  
  class SegmentEntry { //段表
  public:
  int segID; //段号
  int segBase; //段基址
  int segPages; //段页数
  } ;
  class MemManager{ //段管理器
  public:
   MemManager();// 段构造
   ~MemManager(); // 段析构
   SegmentEntry * Allocate(int segPages,int pid);//分配一个段
   void Deallocate(int Pid); //回收一个段
   private:
   List *usedList; //已用内存页表链
   List *idleList; //空闲内存页表链
  };
  
  用户的可执行文件按段装入到模拟机的物理内存中并发执行的过程(无虚拟内存方案)可参见文献[1]。为了构造虚存,设定每个进程一个固定大小的工作集,限定每进程可用的实存页数,补充了宏定义:
  
   #define MemPages 4; //默认的工作集实存页数
  其中的装入构造函数AddrSpace中进行了如下的扩充:
  //当进程由shell命令创建时
   AddrSpace::AddrSpace(char *filename)
   {
  // 建立页表入口
   pageTable = new TranslationEntry
   [pageTableSize];
  //初始化页表项
  for (i = 0; i < pageTableSize; i++) {
  //填写页表项略……
  if(i < MemPages){//如果有实存
   pageTable[i].physicalPage = segment->segBase + i;//分配物理
   pageTable[i].valid = TRUE;
   inMemPage[i] =i ;
  }
   else{//如果无实存物理页号置为-1
   pageTable[i].physicalPage = -1;
   pageTable[i].valid = FALSE; }
  }
  //当进程由父进程创建时
  AddrSpace::AddrSpace(int pid)
  {
  //获取父进程页表入口
  TranslationEntry *pTp=currentThread->space->GetPageTable();
  //拷贝父进程页表
  pageTableSize = currentThread->space->GetPageSize();
  //建立子进程页表入口
  pageTable = new TranslationEntry[pageTableSize];
  for (j=0,i=0;i < pageTableSize; i++) {
   //复制父进程页表项,略……
   if(pTp[i].valid){//该页在实存
   pageTable[i].physicalPage = segment-> segBase + (pTp[i].physicalPage-pSg-> segBase);
   inMemPage[j++] = i ;
   }
   else//该页不在实存
   pageTable[i].physicalPage = -1;
   }
   .......
  
  这样当一个进程空间初始生成时就按照虚拟内存规定的工作集大小在内存中生成了初始进程映像。
  
  3地址变换和虚拟内存调度策略
  
  上节中由装入构造函数AddrSpace生成的地址空间是一个逻辑的地址空间。在程序执行时逻辑地址需要变换为物理空间。在真实的计算机中,这一工作是由 MMU硬件完成的。当变换发生错误时MMU会自动发出各种异常中断。
  Nachos 模拟带有 TLB 的页式内存管理。MMU 由函数 Translate 模拟。
  两个函数ReadMem和WriteMem 在访问物理内存之前都要调用函数Translate将要访问的逻辑地址变换为物理

[1] [2]  下一页

Tags:

作者:张鸿烈
  • 好的评价 如果您觉得此文章好,就请您
      100%(1)
  • 差的评价 如果您觉得此文章差,就请您
      0%(0)

文章评论评论内容只代表网友观点,与本站立场无关!

   评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论