版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
2022年操作系统大作业虚拟内存治理试验。Linux环境下编写一个内核模块,分别实现如下几个函数:staticvoidmtest_dump_vma_list(void):依次列出当前进程所占用的虚拟内存空间各段的读、写或执行权限。staticvoidmtest_find_vma(unsignedlongaddr):查找出虚拟地址addr所在的vma,并通过printk打印该段的起始地址、终止地址和段标志等信息。staticvoidmtest_find_(unsignedlongaddr)addr对应的物理地址并打印。mtest的/proc文件。mtest文件绑定的写函数mtest_write允许用户程序写入一串字符串:假设写入的字符串是listvma则调用函数mtest_dump_vma_list(void);findvma0xffffffff则调用函数mtest_find_vma(0xffffffff),字符串的后几个字符是传递给函数的参数;假设写入的字符串是find0xffffffff则调用函数mtest_find_(0xffffffff),同样字符串的后几个字符是参数。试验要求:为了测试以上模块的正确性,需要编写一个小型的test应用程序,它翻开/proc/mtest文件,并向其中写入字符串调用模块中的相关函数并给出相应的反响信息。学问储藏:虚拟存储空间治理的相关数据构造vm_area_struct和mm_struct/proc文件系统的相关学问内核模块的相关学问试验思路及过程:相关学问储藏:可以使用/proc文件系统和pmap工具查看给定进程的内存空间和其中所包含的内存区域mmap内核使用内存描述符构造表示进程的地址空间,由构造体mm_struct构造体表示,定义在linux/sched.h中,同时linux操作系统承受虚拟内存技术,全部进程之间以虚拟方式共享间彼此互不相干。但是进程之间也可以选择共享地址空间,这样的进程就叫做线程。Linux供给了内存映射函数mmap,它把文件内容映射到一段内存上(准确说是虚拟内存上),通过对这段内存的读取和修改,实现对文件的读取和修改,unlikely的作用就是告知编译器,a<b的可能性很小所以这里在编译时,将fun2的二进制代码尽量不要和前边的编译在一块if(likely(a>b))和if(a>b)在功能上等if(unlikely(a<b))和if(a<b)likely和unlikely的功能就是添加cache提高系统执行速度。数据构造vm_area_structmm_struct的图文表示如下。具体数据构造定义如下:structmm_struct{structvm_area_struct*mmap;//建立虚存空间的单链队列structvm_area_struct*mmap_avl;structvm_area_struct*mmap_cache//最近一次使用的虚存空间,pgd_t*pgd;//指向进程页面名目atomic_tmm_users;atomic_tmm_count;intmap_count;structsemaphoremmap_sem;//用于进程的间的互斥访问spinlock_t_table_lock;structlist_headmmlist;unsignedlongstart_code,end_code,start_data,end_dataunsignedlongstart_brk,brk,start_stack;unsignedlongarg_start,arg_end,env_start,env_end;unsignedlongrss,total_vm,locked_vm;unsignedlongdef_flags;unsignedlongcpu_vm_mask;unsignedlongswap_cnt;unsignedunsignedlongswap_address;mm_context_tcontext;};structvm_area_struct{structmm_struct*vm_mm; /*虚拟区域的参数*/unsignedlongvm_start; /*虚拟区域的起始地址*/unsignedlongvm_end; /*虚拟区域的完毕地址*/structvm_area_struct*vm_next/*指向下一个vm_area_struct构造的指针*/pgprot_tvm__prot;unsignedlongvm_flags; /*虚拟区域如何使用*/rb_node_tvm_rb;structvm_area_struct*vm_next_share;structvm_area_struct**vm_pprev_share;structvm_operations_struct*vm_ops;unsignedlongvm_pgoff;structfile*vm_file;unsignedlongvm_raend;void*vm_private_data;};
/*虚拟区域中的偏移量*/下面考虑具体函数的实现:第一个函数:staticvoidmtest_dump_vma_list(void)首先声明一个进程构造structtask_struct*pi,并将当前进程的指针赋给他。接下来定义一个进程虚拟空间的描述符structmm_struct*mmpi的虚拟空间pi->mmmm..然后申明一个vm_area_structvma,遍历链表,依次对每一段内存进展读、写或执行的权限的推断即可。同时,信号量的操作要合理掌握。具体代码:staticvoidmtest_dump_vma_list(void){structtask_struct*pi=current;//task_struct型的指针pi,并赋初值为当前进程structmm_struct*mm=pi->mm;//将当前进程的虚拟地址空间赋值给mmstructvm_area_struct*vma;printk(“Thecurrentprocessnameis:%s\n“,pi->comm);printk(“mtest_dump_vma_list\n“);down_read(&mm->mmap_sem);//对信号量进展P操作for(vma=mm->mmap;vma;vma=vma->vm_next)//给vma赋初值为指向线性区对象的链表头,并对VMA链表进展遍历{printk(“VMAfrom%pto%p:“,vma->vm_start,vma->vm_end);//输出每段的开头与完毕地址用于表示每段if(vma->vm_flags&VM_WRITE)printk(“WRITE“);if(vma->vm_flags&VM_READ)//flags进展and操作,当其满足条件时,输出相应的单词printk(“READ“);if(vma->vm_flags&VM_EXEC)printk(“EXEC“);if(vma->vm_flags&VM_GROWSDOWN)printk(“\nGROWSDOWN!\n“);printk(“\n“);}up_read(&mm->mmap_sem);//对信号量进展V操作}其次个函数:staticvoidmtest_find_vma(unsignedlongaddr)Linux内核虚拟空间既有分段机制也有分页机制,分段可以依据可读,可写,可执行等权限的关键是vma=find_vma(mm,addr);mm中找到,第一个尾地址大于addr的段。找到后再将其与该段的起始地址相比较,假设大于起始地址即可确定addr确实落在该段内。具体代码:staticvoidmtest_find_vma(unsignedlongaddr){structtask_struct*pi;//task_struct型的指针pi,并赋初值为当前进程pi=find_task_by_pid(1);structmm_struct*mm=pi->mm;//mmstructvm_area_struct*vma;printk(“mtest_find_vma\n“);down_read(&mm->mmap_sem);//P操作vma=find_vma(mm,addr);//find_vmamm中找到,第一个尾地址大于addr的段if(vma&&addr>=vma->vm_start)//addr,这该段为所找的段{printk(“vmahasbeenfound!\n“);printk(“thevmais:%p\n“,vma->vm_flags);printk(“Startaddressofvma:%p\n“,vma->vm_start);printk(“Finaladdressofvma:%p\n“,vma->vm_end);}else//假设不是,不存在符合条件的段{printk(“thereisnoVMAfoundfor%p\n“,addr);}up_read(&mm->mmap_sem);//V操作}第三个函数:static第三个函数:staticvoidmtest_find_(unsignedlongaddr)这个函数意在查找该虚拟地址对应的物理地址,linux承受四级页表:页全局名目、页上级名目、页中间名目、页表名目。图示如下:留意每找一级名目都要推断该名目是否已经映射,否则该虚拟地址所指向的物理地址不存名目中找到页表项对应的物理叶框号,再加上地址偏移量。即找到满足要求的物理地址。具体代码:staticvoidmtest_find_(unsignedlongaddr){structtask_struct*pi;//task_struct型的指针pi,pi=find_task_by_pid(1);//1的进程构造赋值给pistructmm_struct*mm=pi->mm;//mmunsignedlongphysical_address;//physical_address表示所找的物理地址physicaladdressstruct*=NULL;//给页框赋初值NULLpgd_t*pgd;//页全局名目项pud_t*pud;//页上级名目项pmd_t*pmd;//页中间名目项pte_t*pte;//页表项printk(“mtest_find_\n“);down_read(&mm->mmap_sem);//P操作pgd=pgd_offset(mm,addr);//offset函数找到pgd即页全局名目if(pgd_none(*pgd)||unlikely(pgd_bad(*pgd)))//pgd,则跳到exit处gotoexit;pud=pud_offset(pgd,addr);//offset函数找到页的上级名目项if(pud_none(*pud)||unlikely(pud_bad(*pud)))//pgd,则跳到exit处继续执行
gotoexit;pmd=pmd_offset(pud,addr);//offset函数找到页的中间名目项if(pmd_none(*pmd)||unlikely(pmd_bad(*pmd)))//假设不存在满足条件的pmd,则跳到exit处连续执行//unlikey表示根本不行能发生,likely表示很可能发生,用于优化代码,针对某些很少发生的状况使用//_none表示不存在,还未映射,_bad表示不在内存中gotoexit;pte=pte_offset_map(pmd,addr);//offset_map找到页表项if(!pte)//假设不存在满足条件的pte,则跳到exitgotoexit;if(!pte_present(*pte))//假设不存在满足条件的pte,即该页表不在内存中,跳到exitgotoexit;=pfn_to_(pte_pfn(*pte));//找到相应的页框,并找到页框对应的描述符if(!)//返回为空,则跳到exit处gotoexit;get_();//赋值exit:
if(!)//没有符合的页框,输出不存在,并跳到final处退出{printk(“cannotfoundfor%p\n“,addr);gotofinal;}physical_address=(unsignedlong)_address();//把页框基量〔即页框号〕复制给physical_addressphysical_address+=(addr&~_MASK);//physical_address上再加上offset=(addr&~_MASK(页大小))则为所求的物理地址printk(“Thephysicaladdressfor%pis%p\n“,addr,physical_address);final:up_read(&mm->mmap_sem);//V操作}3个函数,使用proc文件系统进展访问.mtest文件绑定的写函数mtest_write允许用户程序写入一串字符串:假设写入的字符串是listvma则调用函数mtest_dump_vma_list(void);findvma0xffffffff则调用函数mtest_find_vma(0xffffffff),字符串的后几个字符是传递给函数的参数;假设写入的字符串是find0xffffffff则调用函数mtest_find_(0xffffffff),同样字符串的后几个字符是参数。具体代码:/*proc3个函数的访问*/staticchar*proc_buf;//proc内核文件,static struct proc_dir_entry *mtest_proc_entry;/建立proc_dir_entry 型的mtest_proc_entrystatic ssize_t mtest_write(struct file *file,const char user * user_buffer,size_tcount,loff_t*data)//对mtest进展写入操作所使用的函数{unsignedlongaddr;//addr为实现mtest_find_vmamtest_find_的参数if(count>MAX_length)//假设字符串数目大于容量则返回return-EINVAL;//EINVAL:无效的参数if(copy_from_user(proc_buf,user_buffer,count))//函数copy_from_user完成用户空间到内核空间的复制,假设失败则返回return-EINVAL;if(memcmp(proc_buf,“listvma“,7)==0)//memcmp将proc_buf7个字节取出,假设是listvmamtest_dump_vma_listmtest_dump_vma_list;elseif(memcmp(proc_buf,“findvma“,7)==0)//假设buf为7个字母,并且为findvmamtest_find_vma7位后开头{if(sscanf(proc_buf+7,“%lx“,&addr)==1)//addr{mtest_find_vma(addr);}}elseif(memcmp(proc_buf,“find“,8)==0)//8个字母为find,则调用mtest_find_{if(sscanf(proc_buf+8,“%lx“,&addr)==1)//addr参数{mtest_find_(addr);}}returncount;}这个是mtest写函数初始化函数:staticintinit_mtest_write(void){printk(“begininitmtest_write!\n“);intret=0;proc_buf=(char*)vmalloc(MAX_length);//proc_buf数组安排最大的空间if(!proc_buf){ret=-ENOMEM;//假设安排失败就返回无效参数}else//否则安排成功{memset(proc_buf,0,MAX_length);//将缓冲区清零mtest_proc_entry=create_proc_entry(“mtest“,0777,NULL);//以0777 权限创立mtestpro_dir_entryif(mtest_proc_entry==NULL)//假设没有创立成功就返回无效参数,同时将proc_buf数组释放{}else{
printk(“Procentrycreatingerror\n“);ret=-ENOMEM;vfree(proc_buf);return-1;printk(“Procentrycreatingsuccess\n“);mtest_proc_entry->
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 钓鱼协会合同模板
- 球场改造合同模板
- 防水店铺转租合同模板
- 融资贷款居间协议合同模板
- 越南商务合同模板
- 店铺承接合同模板
- 杨陵租房合同模板
- 地税代理合同模板
- 贷款置换销售合同模板
- 板栗园转让合同模板
- 横向课题结题报告
- Unit4HobbiesGrammartime(课件)译林版英语五年级上册
- 柴油发电机安装施工技术交底
- 乌鲁木齐银行2023年招聘高层次人才笔试历年高频考点试题答案详解
- FAI 全尺寸检测报告
- GB/T 19973.1-2023医疗保健产品灭菌微生物学方法 第1部分:产品上微生物总数的确定
- 《国家中药饮片炮制规范》全文
- 解决冲突的关键技巧
- 池州市天峰精细化工有限公司1500吨年2,3-二甲基2,3-二苯基丁烷、1000吨年己二醇、600吨年乙基己基甘油产品项目环境影响报告书
- 《钴鉧潭西小丘记》教学设计(部级优课)语文教案
- 英文文献及翻译-Problems-of-incentive-mechanism-in-Chinas-small-an-medium-sized-enterprises
评论
0/150
提交评论