HUNANUNIVERSITY操作系统实验报告操作系统实验报告1操作系统实验报告2目录一、内容.......................................................................................................................3二、目的.......................................................................................................................3三、实验设计思想和练习题.......................................................................................3练习0:填写已有实验......................................................3练习1:实现first-fit连续物理内存分配算法(需要编程)...................3练习2:实现寻找虚拟地址对应的页表项(需要编程)..........................8练习3:释放某虚地址所在的页并取消对应二级页表项的映射(需要编程).......11运行结果................................................................13四、实验体会.............................................................................................................13操作系统实验报告3一、内容本次实验包含三个部分。首先了解如何发现系统中的物理内存;然后了解如何建立对物理内存的初步管理,即了解连续物理内存管理;最后了解页表相关的操作,即如何建立页表来实现虚拟内存到物理内存之间的映射,对段页式内存管理机制有一个比较全面的了解。二、目的1.理解基于段页式内存地址的转换机制;2.理解页表的建立和使用方法;3.理解物理内存的管理方法。三、实验设计思想和练习题练习0:填写已有实验使用eclipse中的diff/merge工具将实验1的代码填入本实验中代码中有“LAB1”的注释相应部分。练习1:实现first-fit连续物理内存分配算法(需要编程)在实现firstfit内存分配算法的回收函数时,要考虑地址连续的空闲块之间的合并操作。提示:在建立空闲页块链表时,需要按照空闲页块起始地址来排序,形成一个有序的链表。可能会修改default_pmm.c中的default_init,default_init_memmap,default_alloc_pages,default_free_pages等相关函数。请仔细查看和理解default_pmm.c中的注释。请在实验报告中简要说明你的设计实现过程。请回答如下问题:你的firstfit算法是否有进一步的改进空间。解答:分析思路:(1)数据结构:A.每个物理页利用一个Page结构体表示,查看kern/mm/memlayout.h包括:操作系统实验报告4ref:引用计数,即映射此物理页的虚拟页个数;flags:描述物理页属性,bit0设置为1,即为“被保留”项,bit1设置为1,即为空闲项;property:记录某连续内存块的大小,即地址连续的空闲页的个数;page_link:将多个连续内存链接在一起的双向链表指针,即构建双向链接各个Page结构的双向链表。B.所有的连续内存空闲块可用一个双向链表管理,利用一个free_area_t结构体表示,查看kern/mm/memlayout.h包括:list_entry:双向链表指针,指向空闲的物理页;nr_free:记录当前空闲页的个数的无符号整形变量。(2)连续物理内存分配思路:物理内存页管理器顺着双向链表进行搜索空闲内存区域,直到找到一个足够大的空闲区域,这是一种速度很快的算法,因为它尽可能少地搜索链表。如果空闲区域的大小和申请分配的大小正好一样,则把这个空闲区域分配出去,成功返回;否则将该空闲区分为两部分,一部分区域与申请分配的大小相等,把它分配出去,剩下的一部分区域形成新的空闲区。其释放内存的设计思路是把这块区域重新放回双向链表中。(3)具体设计:bootloader进行探测物理格局后,利用kern_entry()函数设置堆栈,并临时建立一个段映射关系,调用kern_init()函数输出检查后,pmm_init()函数完成物理内存的管理,假定page_init()函数是按照地址从小到大的顺序传递连续内存空闲块,根据page_init()函数中传递的参数(某个连续的空闲块的起始页,页个数),default_init_memmap()来建立一个连续内存空闲块的双向链表,链表头设free_area.free_list,链表项设Page的base-page_link。操作系统实验报告5代码分析:(1)default_init_memmap:用于构建空闲页链表;A.步骤:(1)初始化每一个空闲页,注意使用头插法是因为地址是从低到高地址增长;(2)计算空闲页的总数。B.具体实现:(2)default_alloc_pages:用于为进程分配空闲页;A.步骤:(1)从空闲链表表头开始查找最小的地址,寻找足够大的空闲块;(2)如果找到,获得指向分配的页,重新设置标志位,从空闲链表中删除此页;(3)判断空闲块大小是否合适;(4)如果合适,不操作;如果不合适,分割页块;(5)计算剩余空闲页个数,返回分配的页块地址。B.具体实现:操作系统实验报告6注:算法改进空间:第一页重置标志位操作被注释后,依然可以编译运行。(3)default_free_pages:用于释放已经使用完的页,使其合并到free_list中;A.步骤:(1)在free_list中查找合适位置,用以插入;操作系统实验报告7(2)改变被释放页的标志位flags及计数器ref;(3)在free_list中向高地址或第地址合并。B.具体实现:操作系统实验报告8练习2:实现寻找虚拟地址对应的页表项(需要编程)通过设置页表和对应的页表项,可建立虚拟内存地址和物理内存地址的对应关系。其中的get_pte函数是设置页表项环节中的一个重要步骤。此函数找到一个虚地址对应的二级页表项的内核虚地址,如果此二级页表项不存在,则分配一个包含此项的二级页表。本练习需要补全get_pte函数inkern/mm/pmm.c,实现其功能。请回答如下问题:请描述页目录项(PagDirectorEntry)和页表(PageTableEntry)中每个组成部分的含义和以及对ucore而言的潜在用处。如果ucore执行过程中访问内存,出现了页访问异常,请问硬件要做哪些事情?解答:分析思路:pde_t为pagedirectoryentry,也就是一级页表的表项。pte_t为pagetableentry,表示二级页表的表项。uintptr_t表示为线性地址,由于段式管理只做直接映射,所以它也是逻辑地址。pgdir(一级页表)给出页表起始地址。通过查找这个页表,我们需要给出二级页表中对应项的地址。虽然目前我们只有boot_pgdir一个页表,但是引入进程的概念之后每个进程都会有自己的页表。有可能根本就没有对应的二级页表的情况,所以二级页表不必要一开始就分配,而是等到需要的时候再添加对应的二级页表。如果在查找二级页表项时,发现对应的二级页表不存在,则需要根据create参数的值来处理是否创建新的二级页表。如果create参数为0,则get_pte返回NULL;如果create参数不为0,则get_pte需要申请一个新的物理页(通过alloc_page来实现,可在mm/pmm.h中找到它的定义),再在一级页表中添加页目录项指向表示二级页表的新物理页。注,新申请的页必须全部设定为零,因为这个页所代表的虚拟地址都没有被映射。当建立从一级页表到二级页表的映射时,需要注意设置控制位。这里应该设置同时设置上PTE_U、PTE_W和PTE_P(定义在mm/mmu.h):PTE_U:表示用户态的软件可以读取对应地址的物理内存页内容;PTE_W:表示物理内存页内容可写;PTE_P:表示物理内存页存在如果原来就有二级页表,或者新建立了页表,则只需返回对应项的地址即可。代码分析:A.步骤:操作系统实验报告9(1)尝试获取页表起始地址;(2)若不成功则直接返回NULL,若成功则申请一个物理页;(3)获得物理页的线性地址,在一级页表中添加页目录项指向表示二级页表的新物理页;(4)返回页表地址。B.具体实现:问题解答:(1)请描述页目录项(PagDirectorEntry)和页表(PageTableEntry)中每个组成部分的含义和以及对ucore而言的潜在用处。答:高20位表示下一级页表(或物理页表)的基址(4K对齐),后12位为标志位,分别为操作系统实验报告10从低位起第0~6位为ucore内核占用,表示指向的下一级页面的某些特性(是否存在、是否可写……);对于PDE,第7位表示如果pde的PTE_PS位为1,那么pde中所存的就不是下一级页表,而是一张4M页的起始地址;对于PTE,第7、8位强制位0;第9~11位供内核以外的软件使用。(2)如果ucore执行过程中访问内存,出现了页访问异常,请问硬件要做哪些事情?答:出现页访问异常会触发缺页中断,缺页中断发生时的事件顺序如下:1)硬件陷入内核,在内核堆栈中保存程序计数器。大多数机器将当前指令的各种状态信息保存在特殊的CPU寄存器中。2)启动一个汇编代码例程保存通用寄存器和其他易失的信息,以免被操作系统破坏。3)当操作系统发现一个缺页中断时,尝试发现需要哪个虚拟页面。通常一个硬件寄存器包含了这一信息,如果没有的话,操作系统必须检索程序计数器,取出这条指令,用软件分析这条指令,看看它在缺页中断时正在做什么。4)一旦知道了发生缺页中断的虚拟地址,操作系统检查这个地址是否有效,并检查存取与保护是否一致。如果不一致,向进程发出一个信号或杀掉该进程。如果地址有效且没有保护错误发生,系统则检查是否有空闲页框。如果没有空闲页框,执行页面置换算法寻找一个页面来淘汰。5)如果选择的页框“脏”了,安排该页写回磁盘,并发生一次上下文切换,挂起产生缺页中断的进程,让其他进程运行直至磁盘传输结束。无论如何,该页框被标记为忙,以免因为其他原因而被其他进程占用。6)一旦页框“干净”后(无论是立刻还是在写回磁盘后),操作系统查找所需页面在磁盘上的地址,通过磁盘操作将其装入。该页面被装入后,产生缺页中断的进程仍然被挂起,并且如果有其他可运行的用户进程,则选择另一个用户进程运行。操作系统实验报告117)当磁盘中断发生时,表明该页已经被装入,页表已经更新可以反映它的位置,页框也被标记为正常状态。8)恢复发生缺页中断指令以前的状态,程序计数器重新指向这条指令。9)调度引发缺页中断的进程,操作系统返回调用它的汇编语言。10)该例程恢复寄存器和其他状态信息。练习3:释放某虚地址所在的页并取消对应二级页表项的映射(需要编程)当释放一个包含某虚地址的物理内存页时,需要让对应此物理内存页的管理数据结构Page做相关的清除处理,使得此物理内存页成为空闲;另外还需把表示虚地址与物理地址对应关系的二级页表项清除。请仔细查看和理解page_remove_pte函数中的注释。为此,需要补全在kern/mm/pmm.c中的page_remove_pte函数。请回答如下问题:数据结构Page的全局变量(其实是一个数组)的每一项与页表中的页目录项和页表项有无对应关系?如果有,其对应关系是啥?如果希望虚拟地址与物理地址相等,则需要如何修改lab2,完成此事?解答:分析思路:使用pte2page宏即可