This is NACHOS#4

本文最后更新于:2022年7月7日 上午

通过考察系统加载应用程序过程,如何为其分配内存空间、创建页表并建立虚页与实页帧的映射关系

  • 理解Nachos的内存管理方法
  • 理解系统对空闲帧的管理方法
  • 理解如何加载另一个应用程序并为其分配地址空间,以支持多进程机制
  • 理解进程的pid
  • 理解进程退出所要完成的工作

Nachos多进程机制的实现

理解Nachos的内存管理方法

阅读protest.cc中函数StartProcess(char* filename)中为可执行程序分配内存空间的过程

StartProcess()

阅读为程序分配内存空间,创建页表的过程AddrSpace::AddrSpace()

AddrSpace()

可知Nachos为每个进程从0号页框开始按序分配,且物理页框和虚拟页框保持一致。这样的内存分配方法只适用于单进程,因为如果有多道进程并行时,后创建的进程也从0开始分配内存,这将会覆盖掉先前的进程,导致系统问题。而且这样的内存分配方法使物理地址和逻辑地址的对应关系失去了意义。

理解系统对空闲帧的管理方法

为了避免分配内存空间的过程中出现内存交换的问题,在为进程分配物理页框的时候我们只能为其分配空闲帧,所以需要对空闲帧进行管理,便于查找使用

参考在文件系统中对空闲磁盘块的管理方法,我们同样使用位图这一数据结构对物理内存进行管理,在类AddrSpace中实例化类BitMap的一个全局对象freeBitMap

Declare freeBitMap

初始化该位图,NumPhyPages为宏定义的物理页框数

1
BitMap* AddrSpace::freeBitMap = new BitMap(NumPhysPages);

当需要检索空闲帧时,调用BitMap::Find()方法,返回值为一个空闲帧号,同时将该空闲帧置1标记为已占用;若返回值为-1,则没有空闲帧

当需要释放i号帧时,调用BitMap::Clear(i),将i号帧置0标记为空闲

多进程机制下为应用程序分配地址空间

修改AddrSpace::AddrSpace(),在分配物理页框的时候,查找空闲帧进行分配

AddrSpace()

同时,在AddrSpace::~AddrSpace()的析构过程中,需要将该进程的内存空间释放

~AddrSpace()

多进程机制下将可执行文件写入内存

Nachos在写入内存之前将整个内存空间都置0,是为了将未初始化的数据段和栈段置0,然后再将代码段和已初始化的数据段写入内存

在单进程机制下这样做是没有问题的,但在多进程机制中这样做则会清空整个内存,导致其他正在运行中的进程出错,所以需要将该条语句删除

zero out

在写入内存的过程中,Nachos直接将逻辑地址作为物理地址写入,对于原本一一对应的映射关系下是可行的,但在多进程机制下需要进行修改

copy into memory

将逻辑地址转换为物理地址:先将逻辑地址分成页号和页内偏移量两部分,根据页号查询页表得到块号,则物理地址=块号+页内偏移量。

已知逻辑地址virtualAddr = noffH.code.virtualAddr,则逻辑页号为virtualPage = virtualAddr / pageSize, 查询页表可得物理块号physicalPage = pageTable[virtualPage];页内偏移量为pageOffset = virtualAddr % pageSize

则物理地址physicalAddr = physicalPage * pageSize + pageOffset

copy into memory

理解进程的pid

pid(Process Identification) 是进程标识符,每个进程都有唯一的pid,进程创建时由系统分配

SpaceId是为可执行程序分配并装入内存空间时进程地址空间的首地址。由于该首地址是唯一的,理论上可以使用该值作为pid,但该值不连续且值过大,并不是非常合适

可以借鉴UNIX的思想,只要为每个进程分配一个唯一的整数作为pid就可以,例如0~99预留为核心进程使用,用户进程号从100开始使用

理解进程退出所要完成的工作

根据进程创建时系统为其所做的工作,当一个进程退出时,应当释放其所占用的内存空间及页表等信息,并且收回为其分配的pid,供后续进程使用


本文作者: 31
本文链接: http://uuunni.github.io/2022/04/24/This-is-NACHOS-4/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!