Chinaunix首页 | 论坛 | 博客
  • 博客访问: 281854
  • 博文数量: 57
  • 博客积分: 1764
  • 博客等级: 上尉
  • 技术积分: 660
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-09 18:14
文章分类

全部博文(57)

文章存档

2012年(24)

2011年(33)

分类: LINUX

2011-12-03 23:34:54

      内核中常用的内存分配函数有:kmalloc, __get_free_pages, vmalloc, alloc_pages, page_address

    kmalloc:分配基于slab机制,但受限于slab一次最大分配的内存上限为128KB,最小为3264字节。该函数返回的是虚拟地址,在3GB~high_memory内核空间中,即NORMALDMA区(另外还有个是HIGH),因此要取得相应的物理地址,只需要减去PAGE_OFFSET即可,因此分配的时候,不需要设置页表,效率高。kmalloc分配的内存,在物理和虚拟空间上是连续的,有可能被阻塞,不能用在原子上下文中。

    vmalloc返回的也是虚拟地址,在 VMALLOC_START~4GB内核空间中。保证的是在虚拟地址空间上的连续,一般作为交换区、模块的分配vmalloc 中调用了 kmalloc GFPKERNEL),因此也不能应用于原子上下文。vmalloc使用的正确场合是分配一大块,连续的,只在软件中存在的,用于缓冲的内存区域。不能在微处理器之外使用。Vmalloc能分配的大小相对较大

举个例子:

    内核空间中,从3Gvmalloc_start这段地址是物理内存映射区域(该区域中包括了内核镜像、物理页框表mem_map等等),好比我们使 用的 VMware虚拟系统内存是160M,那么3G3G+160M这片内存就应当映射物理内存。在物理内存映射区之后,就是vmalloc区域。对于 160M的系统而言,vmalloc_start位置应在3G+160M邻近(在物理内存映射区与vmalloc_start期间还存在一个8Mgap 来避免跃界),vmalloc_end的位置濒临4G(最后地位系统会保存一片128k大小的区域用于专用页面映射


    要获得物理连续的大块内存,可以考虑直接分配页

        __get_free_page:返回的是页的虚拟地址,所在空间跟kmalloc一样,但是能获得更多连续的物理内存(<4M)。该函数是基于alloc_pages分配的。alloc_pages返回的是页描述符的虚拟地址,可以通过page_address将页描述符的地址,转换为页的地址。__get_free_page相当于这两者的封装

     page_address该函数进行转换的时候,要分清是lowmem还是higtmem。如果是前者,直接__va(page_to_pfn(page) << PAGE_SHIFT),若是后者,需要在page_address_htable映射表中查找。


参考资料

http://blog.csdn.net/tigerjb/article/details/6412881

http://blog.csdn.net/cnctloveyu/article/details/4256446

http://blog.chinaunix.net/space.php?uid=20583479&do=blog&id=1920147

阅读(1667) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~