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

虚拟内存有什么用  时间:2021-01-16  阅读:()

张弛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参数,即完成了权限修改.

wordpress外贸企业主题 wordpress高级全行业大气外贸主题

wordpress高级全行业大气外贸主题,wordpress通用全行业高级外贸企业在线询单自适应主题建站程序,完善的外贸企业建站功能模块 + 高效通用的后台自定义设置,更实用的移动设备特色功能模块 + 更适于欧美国外用户操作体验 大气简洁的网站风格设计 + 高效优化的网站程序结构,更利于Goolge等SEO搜索优化和站点收录排名。点击进入:wordpress高级全行业大气外贸主题主题价格:¥398...

标准互联(450元)襄阳电信100G防御服务器 10M独立带宽

目前在标准互联这边有两台香港云服务器产品,这不看到有通知到期提醒才关注到。平时我还是很少去登录这个服务商的,这个服务商最近一年的促销信息比较少,这个和他们的运营策略有关系。已经从开始的倾向低价和个人用户云服务器市场,开始转型到中高端个人和企业用户的独立服务器。在这篇文章中,有看到标准互联有推出襄阳电信高防服务器100GB防御。有三款促销方案我们有需要可以看看。我们看看几款方案配置。型号内存硬盘IP...

PhotonVPS:美国Linux VPS半价促销2.5美元/月起,可选美国洛杉矶/达拉斯/芝加哥/阿什本等四机房

photonvps怎么样?photonvps现在针对旗下美国vps推出半价促销优惠活动,2.5美元/月起,免费10Gbps DDoS防御,Linux系统,机房可选美国洛杉矶、达拉斯、芝加哥、阿什本。以前觉得老牌商家PhotonVPS贵的朋友可以先入手一个月PhotonVPS美国Linux VPS试试了。PhotonVPS允许合法大人内容,支持支付宝、paypal和信用卡,30天退款保证。Photo...

虚拟内存有什么用为你推荐
广东虚拟主机有什么便宜又好用的虚拟主机吗?虚拟空间哪个好虚拟内存设在哪个盘最好重庆虚拟空间重庆合川宝龙城市广场有前途么asp虚拟空间ASP空间是什么意思?深圳网站空间求免费稳定空间网站?虚拟主机管理系统我也想和你学虚拟主机管理系统的操作北京虚拟主机租用租用虚拟主机在哪里租用比较好美国虚拟主机购买我公司需要购买美国的虚拟主机。但是为什么有的海外主机很便宜!有的却很贵呢。 质量如何区分!有没办法去虚拟主机99idc网站后台织梦系统重装、空间转移、及上传技巧有哪些?台湾虚拟主机香港虚拟主机和台湾虚拟主机比较,哪个更好!?
黑龙江域名注册 北京租服务器 金万维动态域名 香港bgp机房 zpanel 光棍节日志 空间服务商 免费smtp服务器 ca4249 工信部icp备案号 hinet 服务器干什么用的 免费私人服务器 学生服务器 国内空间 重庆服务器 网络速度 服务器托管价格 博客域名 葫芦机 更多