From 87f3d00c4eaf62a9e43a7bb041dff8557ceb488a Mon Sep 17 00:00:00 2001 From: leefige Date: Wed, 4 Apr 2018 00:54:31 +0800 Subject: [PATCH] Fix typo in lab3; visual improvement. --- SUMMARY.md | 2 +- lab3/lab3_2_2_files.md | 2 +- lab3/lab3_3_2_labs_steps.md | 2 +- lab3/lab3_3_3_data_structures.md | 6 +++--- lab3/lab3_4_page_fault_handler.md | 2 +- lab3/lab3_5_2_page_swapping_principles.md | 10 +++++----- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/SUMMARY.md b/SUMMARY.md index e7d31fc..de41c66 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -116,7 +116,7 @@ * [Page Fault异常处理](lab3/lab3_4_page_fault_handler.md) * [页面置换机制的实现](lab3/lab3_5_swapping.md) * [页替换算法](lab3/lab3_5_1_page_swapping.md) - * [页面置换机制实验报告要求](lab3/lab3_5_2_page_swapping_principles.md) + * [页面置换机制](lab3/lab3_5_2_page_swapping_principles.md) * [实验报告要求](lab3/lab3_6_labs_requirement.md) ## Lab 4 diff --git a/lab3/lab3_2_2_files.md b/lab3/lab3_2_2_files.md index e34d2a3..9aa8889 100644 --- a/lab3/lab3_2_2_files.md +++ b/lab3/lab3_2_2_files.md @@ -51,7 +51,7 @@ fault处理相关的do\_pgfault函数是本次实验需要涉及完成的。 * kern/mm/swap.[ch]:定义了实现页替换算法类框架struct swap\_manager。swap.c包含了对此页替换算法类框架的初始化、页换入/换出等各种函数实现。重点是要理解何时调用swap\_out和swap\_in函数。和如何在此框架下连接具体的页替换算法实现。check\_swap函数以及被此函数调用的\_fifo\_check\_swap函数完成了对本次实验中的练习2:FIFO页替换算法基本正确性的检查,可了解,便于知道为何产生错误。 * kern/mm/swap\_fifo.[ch]:FIFO页替换算法的基于页替换算法类框架struct swap\_manager的简化实现,主要被swap.c的相关函数调用。重点是\_fifo\_map\_swappable函数(可用于建立页访问属性和关系,比如访问时间的先后顺序)和\_fifo\_swap\_out\_victim函数(可用于实现挑选出要换出的页),当然换出哪个页需要借助于fifo\_map\_swappable函数建立的某种属性关系,已选出合适的页。 -* kern/mm/mmu.h:其中定义额也页表项的各种属性位,比如PTE\_P\\PET\_D\\PET\_A等,对于实现扩展实验的clock算法会有帮助。 +* kern/mm/mmu.h:其中定义了页表项的各种属性位,比如PTE\_P\\PET\_D\\PET\_A等,对于实现扩展实验的clock算法会有帮助。 本次实验的主要练习集中在vmm.c中的do\_pgfault函数和swap\_fifo.c中的\_fifo\_map\_swappable函数、\_fifo\_swap\_out\_victim函数。 diff --git a/lab3/lab3_3_2_labs_steps.md b/lab3/lab3_3_2_labs_steps.md index de984eb..9abdefd 100644 --- a/lab3/lab3_3_2_labs_steps.md +++ b/lab3/lab3_3_2_labs_steps.md @@ -4,7 +4,7 @@ 首先是初始化过程。参考ucore总控函数init的代码,可以看到在调用完成虚拟内存初始化的vmm\_init函数之前,需要首先调用pmm\_init函数完成物理内存的管理,这也是我们lab2已经完成的内容。接着是执行中断和异常相关的初始化工作,即调用pic\_init函数和idt\_init函数等,这些工作与lab1的中断异常初始化工作的内容是相同的。 -在调用完idt\_init函数之后,将进一步调用三个lab3中才有的新函数vmm\_init、ide\_init和swap\_init。这三个函数设计了本次实验中的两个练习。第一个函数vmm\_init是检查我们的练习1是否正确实现了。为了表述不在物理内存中的“合法”虚拟页,需要有数据结构来描述这样的页,为此ucore建立了mm\_struct和vma\_struct数据结构(接下来的小节中有进一步详细描述),假定我们已经描述好了这样的“合法”虚拟页,当ucore访问这些“合法”虚拟页时,会由于没有虚实地址映射而产生页访问异常。如果我们正确实现了练习1,则do\_pgfault函数会申请一个空闲物理页,并建立好虚实映射关系,从而使得这样的“合法”虚拟页有实际的物理页帧对应。这样练习1就算完成了。 +在调用完idt\_init函数之后,将进一步调用三个lab3中才有的新函数vmm\_init、ide\_init和swap\_init。这三个函数涉及了本次实验中的两个练习。第一个函数vmm\_init是检查我们的练习1是否正确实现了。为了表述不在物理内存中的“合法”虚拟页,需要有数据结构来描述这样的页,为此ucore建立了mm\_struct和vma\_struct数据结构(接下来的小节中有进一步详细描述),假定我们已经描述好了这样的“合法”虚拟页,当ucore访问这些“合法”虚拟页时,会由于没有虚实地址映射而产生页访问异常。如果我们正确实现了练习1,则do\_pgfault函数会申请一个空闲物理页,并建立好虚实映射关系,从而使得这样的“合法”虚拟页有实际的物理页帧对应。这样练习1就算完成了。 ide\_init和swap\_init是为练习2准备的。由于页面置换算法的实现存在对硬盘数据块的读写,所以ide\_init就是完成对用于页换入换出的硬盘(简称swap硬盘)的初始化工作。完成ide\_init函数后,ucore就可以对这个swap硬盘进行读写操作了。swap\_init函数首先建立swap\_manager,swap\_manager是完成页面替换过程的主要功能模块,其中包含了页面置换算法的实现(具体内容可参考5小节)。然后会进一步调用执行check\_swap函数在内核中分配一些页,模拟对这些页的访问,这会产生页访问异常。如果我们正确实现了练习2,就可通过do\_pgfault来调用swap\_map\_swappable函数来查询这些页的访问情况并间接调用实现页面置换算法的相关函数,把“不常用”的页换出到磁盘上。 diff --git a/lab3/lab3_3_3_data_structures.md b/lab3/lab3_3_3_data_structures.md index c85329b..7d8fe50 100644 --- a/lab3/lab3_3_3_data_structures.md +++ b/lab3/lab3_3_3_data_structures.md @@ -12,7 +12,7 @@ fault异常时,可获得访问的内存的方式(读或写)以及具体的 在ucore中描述应用程序对虚拟内存“需求”的数据结构是vma\_struct(定义在vmm.h中),以及针对vma\_struct的函数操作。这里把一个vma\_struct结构的变量简称为vma变量。vma\_struct的定义如下: -``` +```c struct vma_struct { // the set of vma using the same PDT struct mm_struct *vm_mm; @@ -26,7 +26,7 @@ struct vma_struct { vm\_start和vm\_end描述了一个连续地址的虚拟内存空间的起始位置和结束位置,这两个值都应该是PGSIZE 对齐的,而且描述的是一个合理的地址空间范围(即严格确保 vm\_start < vm\_end的关系);list\_link是一个双向链表,按照从小到大的顺序把一系列用vma\_struct表示的虚拟内存空间链接起来,并且还要求这些链起来的vma\_struct应该是不相交的,即vma之间的地址空间无交集;vm\_flags表示了这个虚拟内存空间的属性,目前的属性包括: -``` +```c #define VM_READ 0x00000001 //只读 #define VM_WRITE 0x00000002 //可读写 #define VM_EXEC 0x00000004 //可执行 @@ -34,7 +34,7 @@ vm\_start和vm\_end描述了一个连续地址的虚拟内存空间的起始位 vm\_mm是一个指针,指向一个比vma\_struct更高的抽象层次的数据结构mm\_struct,这里把一个mm\_struct结构的变量简称为mm变量。这个数据结构表示了包含所有虚拟内存空间的共同属性,具体定义如下 -``` +``` c struct mm_struct { // linear list link which sorted by start addr of vma list_entry_t mmap_list; diff --git a/lab3/lab3_4_page_fault_handler.md b/lab3/lab3_4_page_fault_handler.md index c6f7511..bb23789 100644 --- a/lab3/lab3_4_page_fault_handler.md +++ b/lab3/lab3_4_page_fault_handler.md @@ -24,6 +24,6 @@ ![image](../lab3_figs/image002.png) -产生页访问异常后,CPU把引起页访问异常的线性地址装到寄存器CR2中,并给出了出错码errorCode,说明了页访问异常的类型。ucore OS会把这个值保存在struct trapframe 中tf\_err成员变量中。而中断服务例程会调用页访问异常处理函数do\_pgfault进行具体处理。这里的页访问异常处理是实现按需分页、页换入换出机制的关键之处。 +产生页访问异常后,CPU把引起页访问异常的线性地址装到寄存器CR2中,并给出了出错码errorCode,说明了页访问异常的类型。ucore OS会把这个值保存在struct trapframe 中tf\_err成员变量中。而中断服务例程会调用页访问异常处理函数do\_pgfault进行具体处理。这里的页访问异常处理是实现按需分页、页换入换出机制的关键之处。 ucore中do\_pgfault函数是完成页访问异常处理的主要函数,它根据从CPU的控制寄存器CR2中获取的页访问异常的物理地址以及根据errorCode的错误类型来查找此地址是否在某个VMA的地址范围内以及是否满足正确的读写权限,如果在此范围内并且权限也正确,这认为这是一次合法访问,但没有建立虚实对应关系。所以需要分配一个空闲的内存页,并修改页表完成虚地址到物理地址的映射,刷新TLB,然后调用iret中断,返回到产生页访问异常的指令处重新执行此指令。如果该虚地址不在某VMA范围内,则认为是一次非法访问。 diff --git a/lab3/lab3_5_2_page_swapping_principles.md b/lab3/lab3_5_2_page_swapping_principles.md index 6a09afb..4f3a746 100644 --- a/lab3/lab3_5_2_page_swapping_principles.md +++ b/lab3/lab3_5_2_page_swapping_principles.md @@ -27,7 +27,7 @@ swap_entry_t ------------------------- | offset | reserved | 0 | ------------------------- -24 bits 7 bits 1 bit +24 bits 7 bits 1 bit ``` 考虑到硬盘的最小访问单位是一个扇区,而一个扇区的大小为512(2\^8)字节,所以需要8个连续扇区才能放置一个4KB的页。在ucore中,用了第二个IDE硬盘来保存被换出的扇区,根据实验三的输出信息 @@ -53,11 +53,11 @@ ucore认为合法的所有虚拟内存空间集合,而mm中的每个vma表示 到实验二为止,我们知道目前表示内存中物理页使用情况的变量是基于数据结构Page的全局变量pages数组,pages的每一项表示了计算机系统中一个物理页的使用情况。为了表示物理页可被换出或已被换出的情况,可对Page数据结构进行扩展: -``` +```c struct Page { …… -list\_entry\_t pra\_page\_link; -uintptr\_t pra\_vaddr; +list_entry_t pra_page_link; +uintptr_t pra_vaddr; }; ``` @@ -67,7 +67,7 @@ pra\_page\_link可用来构造按页的第一次访问时间进行排序的一 为了实现各种页替换算法,我们设计了一个页替换算法的类框架swap\_manager: -``` +```c struct swap_manager { const char *name;