操作系统JOS实习第二次报告

虚拟内存设置多少最好  时间:2021-01-19  阅读:()

张弛00848231,zhangchitc@gmail.
comMay30,2011Contents1Introduction22PhysicalPageManagement22.
1Physicalpageanditsdatastructure22.
2Physicalmemorylayout43VirtualMemory93.
1Virtual,Linear,andPhysicalAddresses103.
2Referencecounting103.
3PageTableManagement134KernelAddressSpace204.
1PermissionsandFaultIsolation204.
2InitializingtheKernelAddressSpace204.
3AddressSpaceLayoutAlternatives231操作系统实习报告张弛,008482311Introduction我在实验中主要参考了华中科技大学邵志远老师写的JOS实习指导,在邵老师的主页上http://grid.
hust.
edu.
cn/zyshao/OSEngineering.
htm可以找到.
但是这次实验的指导远远不如lab1的指导详尽,所以我这里需要补充的内容会很多.
2PhysicalPageManagementExercise1.
Inthefilekern/pmap.
c,youmustimplementcodeforthefollowingfunctions.
boot_alloc()page_init()page_alloc()page_free()Youalsoneedtoaddsomecodetoi386_vm_init()inpmap.
c,asindicatedbycommentsthere.
Fornow,justaddthecodeneededleadinguptothecalltocheck_page_alloc().
Youprobablywanttoworkonboot_alloc(),theni386_vm_init(),thenpage_init(),page_alloc(),andpage_free().
check_page_alloc()testsyourphysicalpageallocator.
YoushouldbootJOSandseewhethercheck_page_alloc()reportssuccess.
Fixyourcodesothatitpasses.
Youmayfindithelpfultoaddyourownassert()stoverifythatyourassumptionsarecorrect.
这部分实验的内容暂时和页面转换机制没有关系,我们需要重点关注的是物理页面的规划以及管理.
主要需要关注JOS内核代码中的inc/queue.
h文件以及kern/pmap.
c文件.
2.
1Physicalpageanditsdatastructure请仔细阅读邵老师的讲义中4.
3章第一节页面管理.
其中重点需要掌握以下内容:1.
物理页和Page数据结构的对应关系2.
对Page*页面链表的宏操作,在inc/queue.
h中里面我唯一碰到的问题就是没看懂为什么JOS给出的链表模板要写成下面这样的形式:inc/queue.
h§¤165/*166*Resetthelistnamed"head"totheemptylist.
2操作系统实习报告张弛,00848231167*/168#defineLIST_INIT(head)do{\169LIST_FIRST((head))=NULL;\170}while(0)这个宏的的目的是将链表初始化为空.
但我奇怪的是为什么要写成一个只执行一次的while循环的形式,而不是直接大括号包住这一段语句就可以了实验室的白光东师兄给出了一个详尽满意的答案.
他给了我下面这样的程序:test.
c§¤1#include23#defineMACRO()do{\4printf("hello\n");\5}while(0)67intmain(){8intx;9scanf("%d\n",&x);1011if(x)12MACRO();13else14printf("thisiselse\n");15return0;16}然后使用gcc-Etest.
c编译这段程序,参数E的目的是为了让编译器仅仅进行预编译以后即停下来,并输出预编译后的程序结果,那么我们得到这样的输出intmain(){intx;scanf("%d\n",&x);if(x)do{printf("hello\n");}while(0);elseprintf("thisiselse\n");return0;}zhangchi@zhangchi-desktop:/tmp/test$很明显我们看到相关的MACRO();调用变成了其相应的宏展开,请特别注意,调用的时候我们是以单个语句的形式调用MACRO()的,那么展开以后的形式还是满足了单个语句(一个while循环),并且,在其后面加上了分号.
如果我们把MACRO改成:test.
c§¤1#defineMACRO(){\2printf("hello\n");\3}那么再次展开的结果会变成:intmain(){intx;3操作系统实习报告张弛,00848231scanf("%d\n",&x);if(x){printf("hello\n");};elseprintf("thisiselse\n");return0;}zhangchi@zhangchi-desktop:/tmp/test$明显可以看出这样的转换造成语法错误,用大括号包裹的代码块后不需要分号.
这里出错的原因就在于我们调用MACRO()之前是当成一个单个语句,调用展开后变成了一个代码块.
那么相应的语法结构就出现了变化导致出错.

真是考虑得非常细致!
感谢师兄!
2.
2Physicalmemorylayout请仔细阅读邵老师的讲义中的4.
3章第一节页面管理中"页面管理链表在内存中的存储和放置"小节.
重点理解1.
pages数组和Page*链表的对应关系2.
pages所在的空间是怎样分配的3.
整个物理内存的布局这里要说的是,在做完lab1以后,我们知道了在实模式下物理页面前640KB的一些分配情况,如BIOS的载入地址、bootloader载入地址、操作系统内核ELF文件头的临时存放空间等等,具体的布局应该如下图所示:在lab1完成后,我们从0x000100000这个位置放入内核,直到end结束.
end是链接器作链接时得到的内核结束地址.
那么在建立物理页面对应的Page*链表时,我们需要为这个链表分配实际的物理内存空间,在二级页地址映射机制中,系统还需要一个页目录存下所有二级页表的地址,这个也是需要操作系统预先分配空间的,所以结合上图,我们第一步完成之后物理内存布局应该如下图所示:4操作系统实习报告张弛,00848231我们第一步的目的就是为页目录和pages分配好空间,并建立起空闲页表pagefreelist.
开始写代码的时候,首先需要弄清楚kern/pmap.
c中的几个基本的变量:kern/pmap.
c§¤12//Thesevariablesaresetbyi386_detect_memory()13staticphysaddr_tmaxpa;//Maximumphysicaladdress14size_tnpage;//Amountofphysicalmemory(inpages)15staticsize_tbasemem;//Amountofbasememory(inbytes)16staticsize_textmem;//Amountofextendedmemory(inbytes)1718//Thesevariablesaresetini386_vm_init()19pde_t*boot_pgdir;//Virtualaddressofboottimepagedirectory20physaddr_tboot_cr3;//Physicaladdressofboottimepagedirectory21staticchar*boot_freemem;//Pointertonextbyteoffreemem2223structPage*pages;//Virtualaddressofphysicalpagearray24staticstructPage_listpage_free_list;//Freelistofphysicalpages这里只需要知道两个变量,bootfreemem和bootpgdir,前者是当前可用内存的开始地址(也就是说,内核载入以后,系统管理所需要的内容就从end以后开始分配,即从一开始bootfreemem是等于end,这个在接下来的代码里就能看到);bootpgdir则是系统页目录所在空间的开始地址.
注注注意意意,,,两两两者者者地地地址址址都都都是是是虚虚虚拟拟拟地地地址址址!
!
!
在在在这这这次次次lab中中中一一一定定定要要要搞搞搞清清清楚楚楚的的的一一一个个个细细细节节节就就就是是是虚虚虚拟拟拟地地地址址址,,,线线线性性性地地地址址址和和和物物物理理理地地地址址址的的的区区区别别别,,,以以以及及及我我我们们们使使使用用用的的的地地地址址址变变变量量量哪哪哪些些些是是是虚虚虚拟拟拟地地地址址址,,,哪哪哪些些些是是是物物物理理理地地地址址址.
.
.
接下来我们可以看到i386vminit(),从这里开始我们这次的lab.
一开始就看到关于页目录的初始化代码:kern/pmap.
c:i386vminit()§¤12//createinitialpagedirectory.
3pgdir=boot_alloc(PGSIZE,PGSIZE);45memset(pgdir,0,PGSIZE);6boot_pgdir=pgdir;7boot_cr3=PADDR(pgdir);5操作系统实习报告张弛,00848231其中bootalloc()为其分配内存空间地址,然后将分配的地址段清空.
然后将其物理地址(PADDR)放入bootcr3准备启动x86的页面地址转换机制.
这里要注意几点:PGSIZE为一个物理页的大小4KB=4096B,定义在inc/mmu.
h中,其中还有我们后面要用的重要常量PTSIZE,为一个页表对应实际物理内存的大小,即1024*4KB=4MB从bootalloc()得到的页面是不会作相应的初始化工作的,所以如果对分配到的空间有要求清空,必须自己亲自动手memset接受的清空地址是pgdir即一个虚拟地址,这个在我们后面的工作中对实际分配到的物物物理理理页页页面面面进行初始化时提醒,清空时使用memset也一定要使用实际物理页面对应的内内内核核核虚虚虚拟拟拟地地地址址址bootcr3得到的是一个物物物理理理地地地址址址,这个和我们前面强调的分清每个地址变量到底是虚拟地址还是物理地址有密切联系接下来我们来看一下第一个需要实现的函数bootalloc()kern/pmap.
c:bootalloc()§¤1staticvoid*2boot_alloc(uint32_tn,uint32_talign)3{4externcharend[];5void*v;67//Initializeboot_freememifthisisthefirsttime.
8//'end'isamagicsymbolautomaticallygeneratedbythelinker,9//whichpointstotheendofthekernel'sbsssegment-10//i.
e.
,thefirstvirtualaddressthatthelinker11//did_not_assigntoanykernelcodeorglobalvariables.
12if(boot_freemem==0)13boot_freemem=end;1415//LAB2:Yourcodehere:16//Step1:roundboot_freememuptobealignedproperly17//(hint:lookintypes.
hforsomehandymacros)18//Step2:savecurrentvalueofboot_freememasallocatedchunk19//Step3:increaseboot_freememtorecordallocation20//Step4:returnallocatedchunk2122v=ROUNDUP(boot_freemem,align);23boot_freemem=(char*)v+n;2425returnv;26}这个函数的问题不大.
看接下来的代码:kern/pmap.
c:i386vminit()§¤12//RecursivelyinsertPDinitselfasapagetable,toform3//avirtualpagetableatvirtualaddressVPT.
6操作系统实习报告张弛,008482314//(Fornow,youdon'thaveunderstandthegreaterpurposeofthe5//followingtwolines.
)67//Permissions:kernelRW,userNONE8pgdir[PDX(VPT)]=PADDR(pgdir)|PTE_W|PTE_P;910//sameforUVPT11//Permissions:kernelR,userR12pgdir[PDX(UVPT)]=PADDR(pgdir)|PTE_U|PTE_P;131415//Allocateanarrayofnpage'structPage'sandstoreitin'pages'.
16//Thekernelusesthisarraytokeeptrackofphysicalpages:for17//eachphysicalpage,thereisacorrespondingstructPageinthis18//array.
'npage'isthenumberofphysicalpagesinmemory.
19//User-levelprogramswillgetread-onlyaccesstothearrayaswell.
20//Yourcodegoeshere:212223pages=boot_alloc(npage*sizeof(structPage),PGSIZE);242526//Nowthatwe'veallocatedtheinitialkerneldatastructures,weset27//upthelistoffreephysicalpages.
Oncewe'vedoneso,allfurther28//memorymanagementwillgothroughthepage_*functions.
In29//particular,wecannowmapmemoryusingboot_map_segmentorpage_insert30page_init();3132check_page_alloc();3334page_check();前两句对pgdir的操作我们可以先不用管他,在后来设置页表的时候我们会回过头来看这两句话的含义.
在23行里为pages分配空间以后,就进入倒pageinit()对链表进行初始化了.
在进行接下来的编码之前,我们先需要了解JOS对于地址编码的一些规定,在inc/mmu.
h中,我们可以找到一组详尽的宏:inc/mmu.
h§¤16//Alinearaddress'la'hasathree-partstructureasfollows:17//1810-10-12-19//|PageDirectory|PageTable|OffsetwithinPage|20//|Index|Index||2122//\---PDX(la)PTX(la)PGOFF(la)----/23PPN(la)24//25//ThePDX,PTX,PGOFF,andPPNmacrosdecomposelinearaddressesasshown.
26//ToconstructalinearaddresslafromPDX(la),PTX(la),andPGOFF(la),27//usePGADDR(PDX(la),PTX(la),PGOFF(la)).
2829//pagenumberfieldofaddress30#definePPN(la)(((uintptr_t)(la))>>PTXSHIFT)31#defineVPN(la)PPN(la)//usedtoindexintovpt[]3233//pagedirectoryindex34#definePDX(la)((((uintptr_t)(la))>>PDXSHIFT)&0x3FF)35#defineVPD(la)PDX(la)//usedtoindexintovpd[]3637//pagetableindex38#definePTX(la)((((uintptr_t)(la))>>PTXSHIFT)&0x3FF)397操作系统实习报告张弛,0084823140//offsetinpage41#definePGOFF(la)(((uintptr_t)(la))&0xFFF)4243//constructlinearaddressfromindexesandoffset44#definePGADDR(d,t,o)((void*)((d)=npage)79panic("pa2pagecalledwithinvalidpa");80return&pages[PPN(pa)];81}8283staticinlinevoid*84page2kva(structPage*pp)85{86returnKADDR(page2pa(pp));87}我们知道每个物理页面对应一个Page的struct和一个物理页号PPN和唯一的物理首地址,这组宏就是作这几个量之间的对应关系的,其中:一个Page对应的PPN就是page2ppn(structPage),而一个PPN对应的structPage则是pages[PPN]一个Page对应的物理地址是page2pa(structPage),而一个物理地址对应的structPage则是pa2page(pa)最后还提供了一个页面到内核虚拟地址的转换宏page2kva,这个也很好用.
根据Exercise的提示,我们先来看看要填写的第一个函数pgdirwalk()kern/pmap.
c:pgdirwalk()§¤14操作系统实习报告张弛,008482311pte_t*2pgdir_walk(pde_t*pgdir,constvoid*va,intcreate)3{4pde_t*pt=pgdir+PDX(va);5void*pt_kva;67if(*pt&PTE_P){8pt_kva=(void*)KADDR(PTE_ADDR(*pt));9return(pte_t*)pt_kva+PTX(va);10}1112structPage*newpt;1314if(create==1&&page_alloc(&newpt)==0){1516memset(page2kva(newpt),0,PGSIZE);17newpt->pp_ref=1;1819*pt=PADDR(page2kva(newpt))|PTE_U|PTE_W|PTE_P;20pt_kva=(void*)KADDR(PTE_ADDR(*pt));21return(pte_t*)pt_kva+PTX(va);22}2324returnNULL;25}简单说一下这个函数的作用,其实这个函数就是实现虚拟地址到实际物理地址的翻译过程.
根据给出的虚拟地址,返回其二级页表中对应的页表项.
根据参数create的值,如果等于1,则如果虚拟地址还没有对应的物理页面,则分配一个给它.
代码中有几个地方需要注意:1.
第7行代码:判断页目录中va对应二级页表是否存在应该看页目录的对应PDX(va)项最后一位状态位present是否为0,我一开始写成了if(*pt!
=0)了,这样显然不对2.
第16行代码:一定记得memset参数使用的是内核虚拟地址3.
第19行代码:这里我们为新建的物理页设置页目录表项时,页目录后12位的权限位为什么是PTEU|PTEW|PTEP呢第三条提出的问题在注释中其实已经提示了,但是我还是查询了Intelx86的手册:在Reference里的IA-32IntelArchitectureSoftwareDeveloper'sManuals,其中的Volume3A:SystemProgrammingGuide,Part1.
在里面的COMBININGPAGEANDSEGMENTPROTECTION一节里,提到了分段分页保护机制的实现.
当一个程序试图访问一个虚拟地址的数据时,x86系统的保护机制运行为:先检查段权限位DPL,这个是所访问数据段或者Callgate的权限级别,和当前权限级别CPL进行比较,如果不够则产生权限异常(具体机制请参考手册,在这个问题上我们不用管它),否则进入下一步再检查页目录相应表项的访问权限,如果不够也产生异常15操作系统实习报告张弛,00848231最后检查二级页表相应表项的访问权限,不够就产生异常可以看到,在任意一次检查上违例了,那么访问失效.
实际上我们知道页目录中一个表项代表的就是内存中的1024个物理页,这些页中很可能对访问的控制各不相同,比如有的可以给用户写权限,有的只能读,有的连读都不行.
那么在无法提前知道这些需求的话,最明智的办法就是不在页目录这一环节限制太多,让最终的访问控制在二级页表这一环节上再去具体设置.
实际上Intel手册上给出了一个页目录加页表的访问控制的组合控制效果:这个图应该是很容易看明白的,只有一个不太清楚的地方,就是为什么当最终组合效果的权限要求是内核态时,读写权限全部是可读也可写的助教告诉我,因为在内核态下,内核想要写入任意地址都是可行的.
即便内核在写入一个表项时发现该页表项权限只能允许它读的话,通过修改CR0.
WP寄存器,内核也能最终写入这个地址,所以访问类型就显得没有意义了,感谢张顺廷师兄的解释!
!
接下来看看要填的第二个函数bootmapsegment():kern/pmap.
c:bootmapsegment()§¤1staticvoid2boot_map_segment(pde_t*pgdir,uintptr_tla,size_tsize,physaddr_tpa,intperm)16操作系统实习报告张弛,008482313{4intoffset;5pte_t*pte;67for(offset=0;offsetpp_ref--;14}else{15page_remove(pgdir,va);16}17}1819*pte=page2pa(pp)|perm|PTE_P;20pp->pp_ref++;2122return0;23}这个函数负责将一个虚拟地址映射到它实际对应的物理页面上去,这里有几种调用的情况:1.
这个虚拟地址所在地址在二级页表上没有挂载页面,那么这时直接修改相应的二级页表表项即可2.
如果已经挂载了页面,且页面和当前分配的物理页面不一样,那么就卸下原来的页面,再挂载新的页面.
3.
如果已经挂载了页面,而且已挂载页面和当前分配的物理页面是同样的,这是什么情况呢这种情况非常普遍,就是当内核要修改一个页面的访问权限时,它会将同一个页面重新插入一次,传入不同的perm参数,即完成了权限修改.

ShockHosting日本机房VPS测试点评

这个月11号ShockHosting发了个新上日本东京机房的邮件,并且表示其他机房可以申请转移到日本,刚好赵容手里有个美国的也没数据就发工单申请新开了一个,这里做个简单的测试,方便大家参考。ShockHosting成立于2013年,目前提供的VPS主机可以选择11个数据中心,包括美国洛杉矶、芝加哥、达拉斯、杰克逊维尔、新泽西、澳大利亚、新加坡、日本、荷兰和英国等。官方网站:https://shoc...

iON Cloud:七月活动,洛杉矶CN2 GIA线路85折优惠中,价格偏高/机器稳定/更新优惠码

iON Cloud怎么样?iON Cloud是Krypt旗下的云服务器品牌,成立于2019年,是美国老牌机房(1998~)krypt旗下的VPS云服务器品牌,主打国外VPS云服务器业务,均采用KVM架构,整体性能配置较高,云服务器产品质量靠谱,在线率高,国内直连线路,适合建站等用途,支付宝、微信付款购买。支持Windows server 2012、2016、2019中英文版本以及主流Linux发行...

HostKvm($4.25/月)俄罗斯/香港高防VPS

HostKvm又上新了,这次上架了2个线路产品:俄罗斯和香港高防VPS,其中俄罗斯经测试电信CN2线路,而香港高防VPS提供30Gbps攻击防御。HostKvm是一家成立于2013年的国外主机服务商,主要提供基于KVM架构的VPS主机,可选数据中心包括日本、新加坡、韩国、美国、中国香港等多个地区机房,均为国内直连或优化线路,延迟较低,适合建站或者远程办公等。俄罗斯VPSCPU:1core内存:2G...

虚拟内存设置多少最好为你推荐
免费美国主机哪里有免费不限流量的国外主机虚拟主机代理请问虚拟主机的代理和虚拟主机分销有什么区别?分销的主机是不是可以把主机分给多个用户使用?我用的ResellerClub代理!!com域名空间域名解析,我是一个新手站长,我买了一个空间跟一个COM域名,空间自带一个2级域名,我想把这个COM域名绑定到空间上,咋么办?急急急!求大神帮我,我创建一个游戏论坛,也查不到资料,可以给20元,我的手机13685455534,谢谢域名备案域名需要备案吗?100m网站空间网站空间100M和1000M有什么区别 ?深圳网站空间求免费稳定空间网站?独立ip虚拟主机独立ip空间的虚拟主机一般多少钱虚拟主机管理系统急!高分!比较好用的虚拟主机管理系统有哪些?合肥虚拟主机虚拟主机是干嘛的?买了虚拟主机是否要一台电脑?虚拟主机试用30天需要一个免费的虚拟主机,稳定的
最新代理服务器ip 火山主机 warez z.com php探针 台湾谷歌网址 河南移动邮件系统 国外代理服务器地址 电信主机 paypal注册教程 域名与空间 lamp怎么读 国内空间 googlevoice godaddy退款 phpwind论坛 blaze wordpress安装 ddos攻击工具 我的世界免费服务器 更多