欢迎来到天天文库
浏览记录
ID:15403207
大小:157.50 KB
页数:6页
时间:2018-08-03
《linux内核中内存相关的操作函数》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、linux内核中内存相关的操作函数作者:harveywang邮箱:harvey.perfect@gmail.com新浪博客地址:http://blog.sina.com.cn/harveyperfect,有关于减肥和学习英语相关的博文,欢迎交流1、kmalloc()/kfree()static__always_inlinevoid*kmalloc(size_tsize,gfp_tflags)内核空间申请指定大小的内存区域,返回内核空间虚拟地址。在函数实现中,如果申请的内存空间较大的话,会从buddy系统申请若干内存页面,如果申请的内存空间大小较小的话,会从sla
2、b系统中申请内存空间。有关buddy和slab,请参见《linux内核之内存管理.doc》gfp_tflags的选项较多。参考内核文件gfp.h。在函数kmalloc()实现中,如果申请的空间较小,会根据申请空间的大小从slab中获取;如果申请的空间较大,如超过一个页面,会直接从buddy系统中获取。2、vmalloc()/vfree()void*vmalloc(unsignedlongsize)函数作用:从高端(如果存在,优先从高端)申请内存页面,并把申请的内存页面映射到内核的动态映射空间。vmalloc()函数的功能和alloc_pages(_GFP_HIG
3、HMEM)+kmap()的功能相似,只所以说是相似而不是相同,原因在于用vmalloc()申请的物理内存页面映射到内核的动态映射区(见下图),并且,用vmalloc()申请的页面的物理地址可能是不连续的。而alloc_pages(_GFP_HIGHMEM)+kmap()申请的页面的物理地址是连续的,被映射到内核的KMAP区。vmalloc分配的地址则限于vmalloc_start与vmalloc_end之间。每一块vmalloc分配的内核虚拟内存都对应一个vm_struct结构体(可别和vm_area_struct搞混,那可是进程虚拟内存区域的结构),不同的内核
4、虚拟地址被4k大小的空闲区间隔,以防止越界——见下图)。与进程虚拟地址的特性一样,这些虚拟地址与物理内存没有简单的位移关系,必须通过内核页表才可转换为物理地址或物理页。它们有可能尚未被映射,在发生缺页时才真正分配物理页面。如果内存紧张,连续区域无法满足,调用vmalloc分配是必须的,因为它可以将物理不连续的空间组合后分配,所以更能满足分配要求。vmalloc可以映射高端页框,也可以映射底端页框。vmalloc的作用只是为了提供逻辑上连续的地址。。。注意:在申请页面时,如果注明_GFP_HIGHMEM,即从高端申请。则实际是优先从高端内存申请,顺序为(分配顺序是
5、HIGH,NORMAL,DMA)。3、alloc_pages()/free_pages()内核空间申请指定个数的内存页,内存页数必须是2^order个页。alloc_pages(gfp_mask,order)中,gfp_mask是flag标志,其中可以为__GFP_DMA、_GFP_HIGHMEM分别对应DMA和高端内存。注:该函数基于buddy系统申请内存,申请的内存空间大小为2^order个内存页面。参见《linux内核之内存管理.doc》通过函数alloc_pages()申请的内存,需要使用kmap()函数分配内核的虚拟地址。4、__get_free_pa
6、ges()/__free_pages()unsignedlong__get_free_pages(gfp_tgfp_mask,unsignedintorder)作用相当于alloc_pages(NORMAL)+kmap(),但不能申请高端内存页面。__get_free_page()只申请一个页面。5、kmap()/kunmap()返回指定页面对应内核空间的虚拟地址。#includevoid*kmap(structpage*page);voidkunmap(structpage*page); kmap为系统中的任何页返回一个内核虚
7、拟地址. 对于低端内存页,它只返回页的逻辑地址; 对于高端内存页,kmap在“内核永久映射空间”中创建一个特殊的映射. 这样的映射数目是有限,因此最好不要持有过长的时间. 使用kmap创建的映射应当使用kunmap来释放; kmap调用维护一个计数器,因此若2个或多个函数都在同一个页上调用kmap也是允许的. 通常情况下,“内核永久映射空间”是4M大小,因此仅仅需要一个页表即可,内核通过来pkmap_page_table寻找这个页表。注意:不用时及时释放。kmalloc()和vmalloc()相比,kmalloc()总是从ZONE_NORMAL(
8、下图中的直接映射区)申请
此文档下载收益归作者所有