资源描述:
《从mmap分析arm的分页机制》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库。
1、首先先说明mmap分配的虚拟地址在哪里呢?我们知道内核的内存的地址范围在3G-4G的空间。其中这1G的内存分为ZONE_DMA(内存开始的16mb),Z0NE_N0RMAL(16mb-896mb)和ZONE_HIGHMEM(896mb-结束),其中低端内存和虚拟内存空间是一一映射的,也就是说低端内存和虚拟内存之间的转换是相差一个固定的偏移量(OxcOOOOOOO)o我们可以用_va宏和_pa宏把低端内存的物理地址转化为虚拟地址或将低端内存的虚拟地址转化为物理地址。那为什么系统要引入高端内存呢?如果内核没有高端内存,只
2、有低端内存,那么内核的物理地址空间和虚拟地址空间都是一一对应的。那么内核只能访问自己的1GB物理内存。但是我们需要内核访问的是整个4GB的空间。于是就引入了高端内存这个概念。高端内存地址并不和物理内存进行一一映射,而是采用动态映射的方式。当我们内核需要访问用户空间的内存时,我们只需要修改MMU,把属于用户空间的物理地址和内核空间的高端内存地址动态建立映射关系。然后内核就可以通过访问这块高端地址和访问用户空I'可的数据了。Mmu的代码可以查看/arch/arm/mm/mmu.c通过查看mmu的crcatc_mappin
3、g()函数我们可以知道arm平台是使用二级分页方式。如下是我在网上搜到的图:4095LIoffsetL2offsetPageoffset3120190LImasterpagetableVirtualaddressLIpagetableentryL2pagetableentryCoarseL2pagetablebaseaddressJ(baseaddressJ3112II0CopiedtoTLBSelectsphysicalmemory我们从上面已经了解了arm的大概的内存管理方式,那我们回归到我们的主题上,剖析系统
4、调用mmap的过程。SYSCALL_DEFINE6(mmap_pgoff,unsignedlong,addr,unsignedlong,len,unsignedlong,prot,unsignedlong,flags,unsignedlong,fd,unsignedlong,pgoff)down_write(¤t->mm->mmap_sem);retval=do_mmap_pgoff(file,addr,len,prot,flags,pgoff);up.write(&cuiTent->mm->mmap_s
5、em);}前面主要是一些标志的判断,我们先不关注他,我们看到真正的映射函数是do_mmap_pgoffounsignedlongdo_mmap_pgoff(structfile*file,unsignedlongaddr,unsignedlonglen,unsignedlongprot,unsignedlongflags,unsignedlongpgoff)returnmmap_region(file,addr,len,flags,vm_flags,pgoff);}前面主要是一些页面的对齐,映射大小的限制,映射权限的
6、判定。然后我们调用mmap_region()函数。mmap_region()才是真正映射的实现函数。unsignedlongmmap_region(structfile*file,unsignedlongaddr,unsignedlonglen,unsignedlongflags,vm_flags_tvm_flags,unsignedlongpgoff){munmap_back:vma=find_vma_prepare(mni,addr,&prev,&rb_link,&rb_parent);if(vma&&vma->
7、vm_stad8、->vm_mm=mm;vma->vm_start=addr;vma->vm_end=addr+len;vma->vm_flags=vm_flags;vma->vm_page_prot=vm_get_page_prot(vm_flags);vma->vm_pgoff=pgoff;INIT_LIST_HEAD(&vma・>anon_vma_chai