MIT6.828_Lab2_Part3
Part3:内核地址空间
JOS将32位线性空间分成两部分,以ULIM符号为界限,ULIM以上的部分由内核完全控制,用户层没有权限访问,除了为内核保留的堆栈等空间之外,ULIM以上还为内核预留了大约256M的虚拟地址空间,[UTOP,ULIM)的区域用于保存某些对用户层公开的内核数据结构,例如pageinfo结构体,UTOP下方的部分供用户层使用,这部分的访问权限由用户层环境设置。
根据上面的描述,参考memlayout.h,我们要补充pmap.c中的mem_init函数来设置合适的线性地址到物理地址的映射关系。
练习5:补充mem_init()中check_page()后的代码,代码需要通过check_kern_pgdir()和check_page_installed_pgdir()的测试。
补充的代码主要建立了三个映射关系:
建立UPAGES和pageinfo结构体数组间的映射关系:
建立KSTACKTOP和bootstack物理地址的映射关系:
建立ULIM上方为内核预留的256M虚拟地址空间和从0起始的物理地址的映射关系:
执行make qemu进行测试,第一次测试没有通过:
仔细检查代码发现原来是Part2部分编写的boot_map_region函数中犯了一个低级错误:
将红框中的pgcount改成size就行了,还是不够细心呀,找了半天。。。
测试通过:
问题:
1.填充页目录表的映射关系表
2.我们已经将内核和用户环境放置在相同的地址空间中。 为什么用户程序不能读取或写入内核的内存? 哪些特定机制可以保护内核内存?
答:如果用户程序可以读取或写入内核的内存,可能导致内核中存储的数据如pageinfo发生改变,进而OS发生一些不可预知的错误如分页机制不能正常执行,OS崩溃等,限制寻址范围(U/S位)和对页面设置读写权限(R/W位)可以保护内核内存。
3.该操作系统可以支持的最大物理内存量是多少? 为什么?
答:根据Memlayout.h中的空间布局可知pageinfo数组占了PTSIZE(4M)大小的空间,则共有4M/8 = 0.5M个pageinfo结构体,对应0.5M个物理页面,则最大物理内存量为4K*0.5Mb = 2gb。
4.如果我们实际拥有最大的物理内存量,那么管理内存有多少空间开销?
答:管理内存的空间开销主要在页表和页目录表和记录页信息的数据结构上,JOS下采用的是二级页表,虚拟地址空间大小为4GB,故页目录表共一张占4K,页表共1024张,占4M,pginfo数组占PTSIZE(4M)大小的空间,所以内存管理有10M+4K的空间开销。
5.重新回顾kern / entry.S和kern / entrypgdir.c中的页表设置。 打开分页后,EIP仍然是一个很小的
数字(略大于1MB)。 在什么时候我们要过渡到以KERNBASE以上的EIP运行? 在启用分页与开始在高于KERNBASE的EIP之间运行之间,有什么可能使我们能够以较低的EIP继续执行? 为什么这种过渡是必要的?
答:如下图1所示,在执行entry.S中的jmp *%eax后,开始从高地址运行,如下图2,图3所示,最开始启动分页
机制时,cr3中加载的是entry_pgdir,entrypgdir.c中将虚拟地址 [0, 4M)和[KERNBASE, KERNBASE+4M)都映射到了物理地址 [0, 4M),所以能够在较低的EIP继续执行,后面cr3加载的是kern_pgdir,所以需要转变。
图1:
图2:
图3: