由于大家的操作系统设计思想都不一样,直接贴代码也没什么意思,就简单记录下自己的思路吧。
实验一
这个实验就是搭建环境,分析一下源码各个文件的作用。没什么好记录的。
实验二 具有优先级的线程调度
个人感觉这个实验比较简单。
- 修改thread文件,为线程增加成员优先级以及相应的set、get函数。按照自己的设计来就行
- 修改scheduler文件, 使得等待队列按照优先级将线程排序,而不是之前的直接插入。
- 修改ThreadTest文件,按照自己的设计改测试函数
PS:优先级调度分抢占式和非抢占式的。按照上面来只能实现非抢占式的,至于抢占式的的实现,估计还得修改machine下面的Interrupt文件。
实验三 信号量
实验比较简单,信号量的实现已经很明白了,直接拿来用就可。
prodcons++文件里面要改的地方也有英文的代码注释,很清晰。比如:
实验四 扩展文件
实验四和实验五就是有关文件系统的了,难度明显比之前的要大。
这个实验主要改的就是filehdr和openfile。
filehdr文件
这个类相当于inode,记录了文件基本信息。包括大小、占用了几个扇区、内容分别放在哪些扇区中。
openfile文件
用于实现文件的打开、读入等,使用一个filehdr对象。
- filehdr中就是多了扩充文件大小的函数,为了方便,还加了设置文件长度的函数。
- openfile中要新加一个inode请求空间函数,还加了WriteBack函数,用于将hdr修会磁盘
- openfile中要根据以上两步的修改,重写WriteAt函数
实验五 二级索引
这个我是在实验四的基础上就地修改的,只需要改filehdr。这个实现方案能百度到一大堆,我就记录下我的。
引入了一个新的类subhdr,基本成员类似于filehdr。原来的filehdr中的数组留出一个int的大小。数组前面的仍然为一级,最后一个指向的扇区是subhdr对象的扇区。
其实也可以直接最后一个指向filehdr对象,这样就实现了多级索引,就是类似于链表的实现,但是估计很出很多bug,有创新意识的读者可以试下。
这样子确定好思路后,就可以改.cc文件了,可以说是全部重写一遍了,除了FetchFrom
、WriteBack
和FileLength
,所有方法都改了,还需要根据你的设计重新定义宏。但说白了就是按照一级二级的边界划分改就行,就多了几个判断条件多了几种可能的情况罢了。
逻辑理清楚了,改的时候就很简单了,但是一定要仔细,我就是忘了改一个边界条件导致一用到二级的时候就报段错误,核心已转储,还不知道哪里错了,这是最要命的。(就是太菜了,一个bug在眼前就是看不出来。。。)
实验六
这两个实验都是关于内存管理的。
交叉编译环境的注意事项
我在按照实验指导书的步骤来,是获得不了Nachos下的用户可执行程序的,make时报错如下:
所以,我查看了../bin/arch/unknown-i386-linux/bin/
这个目录,发现两个可执行文件都是没有可执行权限的:
这样子Permission denied是理所当然的了,所以要先给他们可执行的权限
命令:chmod 764 *
。再次make,就OK了。
这个实验考察两个方面,一是内存中要有多个程序驻留,二是系统调用Exec的实现。这两个要求是相辅相成。一是二的基础,二是一实现的证明。
先说要求一,就是重新设计分配内存方案,目录中也有bitmap文件,就明示要用位图来记录,当然位图一个就ok,要么声明称全局变量,要么声明成AddrSpace的静态属性,我选了后者,因为前者要改别的文件,怕改乱了,再牵扯到其他实验。
要求二也很直白了,就是改exception.cc实现Exec的处理,就是要注意文件名的获得和PC的推进。(我就是忽视了这个,之前一直陷入死循环找不出错)。
实验七
我的思想是固定分配 + 局部置换
的策略。
看TranslateEntry类中用use
和dirty
,而且注释中也是写明了通过这两个位可以构造虚拟内存,很明显是在提示用二次机会法
。不过,用其他的牺牲页面选择方法(比如FIFO、LRU)也是可行的。
(上学期,h老师说二次机会法只需要两次循环,但我总是觉得是三次循环,没怎么想明白,有明白的小伙伴可以在下方留言,万分感谢)
写代码的时候,要注意的倒不是操作系统方面的问题,反倒是C++的语法问题(没办法就是菜。。。)
- 在AddrSpace的构造函数中,不仅要通过
file = executable;
来保存可执行文件,还要在progtest文件中,将delete exectuable
注释掉。 - 在二次机会法中,是不能将虚拟地址直接作为文件中的位置的。而且要根据数据类型(代码、初始化数据、未初始化数据、堆栈)的不同分别与原始可执行文件或者交换区文件进行页面的换入换出,就是说要修改TranslateEntry进行类型区别。