Skip to content

Latest commit

 

History

History
62 lines (37 loc) · 5.93 KB

lab2_report.md

File metadata and controls

62 lines (37 loc) · 5.93 KB

lab2实验报告

1. 实验思考题

Thinking 2.1

我们注意到我们把宏函数的函数体写成了 do { // ... } while(0)    的形式,而不是仅仅写成形如 {// ... } 的语句块,这样的写法好处是什么?
  1. 使用宏函数时,一般程序员的习惯会在行尾加分号,用{//……},b编译就会报错,而使用do { // ... } while(0),则不会。
  2. 查找宏定义,一般很多行,如果用普通的语句块书写,查找起来不方便,构造的正则表达式更加繁琐,如果改成这种形式,只要查找do while 0 ,就很容易超找到宏定义。
  3. do...while(0)可以消除goto语句。

Thinking 2.2

了解了二级页表页目录自映射的原理之后,我们知道,Win2k 内核的虚存管理也是采用了二级页表的形式,其页表所占的 4M 空间对应的虚存起始地址为 0xC0000000,那么,它的页目录的起始地址是多少呢? 

答案:0xC0300000

4M 虚拟空间的起始位置也就是第一个二级页表对应着页目录的第一个页目录项,同时,由于 1M 个页表项和 4G 地址空间是线性映射,可以算出 0xc0000000 这一地址对应的应该是第 (0xc0000000 » 12) 个页表项,这个页表项也就是第一个页目录项。一个页表项 32 位,占用 4 个字节的内存,因此,其相对于页表起始地址 0xc000000000的偏移为 (0xc0000000 » 12) * 4 = 0x300000 ,于是得到地址为 0xc0000000 + 0x300000 =0xc0300000 。也就是说,页目录的虚存地址为 0xc0300000。

Thinking 2.3

思考一下 tlb_out 汇编函数,结合代码阐述一下跳转到 NOFOUND 的流程?

TLB数据项使用了CP0的EntryHi,PageMask,EntryLo0,EntryLo1这四个寄存器,其中EntryHi包含VPN2(虚拟页号),EntryLo0,EntryLo1分别包含一个PFN(页帧号),tlb的作用也就是根据虚拟页号寻找物理页帧号。

CP0 的寄存器 Index(0号) 中的值决定了相应的指令要读的是哪一个TLB表项,取值从0一直到表项的总数减一。用tlbp软件搜索一个TLB表项时,Index也会自动重置。

Index的低位保存TLB的索引。这不需要很多位,因为还没有MIPS CPU有超过128项的TLB。最高位(位31)有特殊意义,当检测未能找到匹配项的时候,由tlbp置为1。位31选的很好,因为这样看起来像负值,很容易测试。

而我们在tlb_out中也是这么干的,下面我分析一下关键汇编指令的作用,也就是跳转到NOFOUND的流程:

mfc0 k1,CP0_ENTRYHI # CP0的CP0_ENTRYHI寄存器->GPR[K1],这个寄存器包含两个域,VPN2(虚拟页号)和ASID(地址空间标识符);这条命令将存在中CP0的指定寄存器的虚拟页号存入GPR[K1]中,为tlb处理做准备。

mtc0 a0,CP0_ENTRYHI # 将GPR[a0]中的值存入CP0的ENTRYHI寄存器,而GPR[a0]按照约定存的是调用tlb_out函数时传入的参数

tlbp # 软件搜索tlb表项,会自动设置CP0寄存器Index的值,并且如果未找到匹配项的话,Index的最高位会设置为1,也就是负数。

mfc0 k0,CP0_INDEX #将CP0_INDEX寄存器中的值装入GPR[k0]

bltz k0,NOFOUND #如果GPR[k0] < 0,也就是CP0_INDEX < 0,也就是tlbp未能成功找到虚拟页号对应的页帧号,跳转到NOFOUND

以上资料均参照了 see MIPS run linux,以MIPS32为准,MIPS64有些许不同.

补充关于以下3条指令的理解:

mtc0 zero,CP0_ENTRYHI 	# 将CP0_ENTRYHI寄存器置为0
mtc0 zero,CP0_ENTRYLO0  # 将CP0_ENTRYLO0寄存器置为0
tlbwi # write TLB entry at index

这3条指令会在TLB命中的情况下执行,此时CP0_INDEX存储着相应的TLB项,前两条指令将CP0_ENTRYHI和CP0_ENTRYLO0置为0,最后一条指令将其写入index对应的TLB项,也就是将这一项清0,实现tlb_out的功能,如果虚拟地址va对应的虚拟页号页存在于TLB,废止va对应的TLB项。

2. 实验难点图示

本次实验主要比较难理解的是,一个地址究竟什么时候是物理地址,什么时候是虚拟地址,还有两种地址之间的转换。 后来通过乾神在实验课上的讲解,恍然大悟,原来所有我们直接得到的地址都是虚拟地址,物理地址对程序员来说是不可见的(严格的说,不可直接见到,我们可以撰写函数来模拟mmu的地址转换,以得到物理地址,在实验中我们也就是这样做的),所有虚拟地址到物理地址的转换都是由mmu也就是硬件来完成的。我们在程序中所作的,把虚拟地址转换为物理地址,也是为了和mmu的结果互相对照,加深对地址转换的理解。

A picture showing what is difficult in lab2

https://github.com/YoungForest/BUAA_MIPS_OS_DOC/blob/master/lab2_difficulty.png

3. 体会与感想

本次实验lab2的难度比第一次的lab1难度上增加了很多。我花在lab2上的时间达到了20小时,当然还不算理论储备,我发现很多时间都花费在一些细节方面,但这些细节又是对于完成实验很重要的。

lab2的特点是需要阅读很多的代码,自己需要根据要求填很多的函数,这些函数都是相互关联的,这也就意味着错误会传导到意想不到的地方。此次思考题的难度也是略大,前两个求助百度,参考同学们分享的PPT,阅读指导书都还能解决,第三个思考题直接懵逼。后在大神的指导下阅读了 see MIPS run Linux ,成功解决了问题。see MIPS run Linux 果真是神器,去年计组实验,我只看了指定的几章就对我理解MPIS结构有很大帮助,今年一直都没有来得及看,现在看来,这本书对 操作系统 实验的完成也是有很大帮助的,我今后要多加看看,增进对操作系统的理解。

我在完成实验的时候发现,跟其他同学讨论问题可以使自己的思路变得更加清晰,于人于己都是百利而无一害的。