zoukankan      html  css  js  c++  java
  • Linux内核中常见内存分配函数(二)

    常用内存分配函数
    __get_free_pages
    unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order)
    __get_free_pages函数是最原始的内存分配方式,直接从伙伴系统中获取原始页框,返
    回值为第一个页框的起始地址。__get_free_pages在实现上只是封装了alloc_pages函 数, Linux培训
    从代码分析,alloc_pages函数会分配长度为1<
    kmem_cache_alloc
    struct kmem_cache *kmem_cache_create(const char *name, size_t size,
    size_t align, unsigned long flags,
    void (*ctor)(void*, struct kmem_cache *, unsigned long),
    void (*dtor)(void*, struct kmem_cache *, unsigned long))
    void *kmem_cache_alloc(struct kmem_cache *c, gfp_t flags)
    kmem_cache_create/ kmem_cache_alloc是基于slab分配器的一种内存分配方式,适用于反复分配释放同一大小内存块的场合。首先用kmem_cache_create创建一个高速缓存区域,然后用kmem_cache_alloc从 该高速缓存区域中获取新的内存块。 kmem_cache_alloc一次能分配的最大内存由mm/slab.c文件中的MAX_OBJ_ORDER宏 定义,在默认的2.6.18内核版本中,该宏定义为5, 于是一次最多能申请1<<5 * 4KB也就是128KB的 连续物理内存。分析内核源码发现,kmem_cache_create函数的size参数大于128KB时会调用BUG()。测试结果验证了分析结果,用kmem_cache_create分 配超过128KB的内存时使内核崩溃。 Linux培训
    kmalloc
    void *kmalloc(size_t size, gfp_t flags)
    kmalloc是内核中最常用的一种内存分配方式,它通过调用kmem_cache_alloc函 数来实现。kmalloc一次最多能申请的内存大小由include/linux/Kmalloc_size.h的 内容来决定,
    在默认的2.6.18内核版本中,kmalloc一 次最多能申请大小为131702B也就是128KB字 节的连续物理内存。测试结果表明,如果试图用kmalloc函数分配大于128KB的内存,编译不能通过。
    vmalloc
    void *vmalloc(unsigned long size)
    前面几种内存分配方式都是物理连续的,能保证较低的平均访问时间。但是在某些场合
    中,对内存区的请求不是很频繁,较高的内存访问时间也 可以接受,这是就可以分配一段线性连续,物理不连续的地址,带来的好处是一次可以分配较大块的内存。vmalloc对 一次能分配的内存大小没有明确限制。出于性能考虑,应谨慎使用vmalloc函数。在测试过程中, 最大能一次分配1GB的空间。
    Linux 内核部分内存分布
    dma_alloc_coherent
    void *dma_alloc_coherent(struct device *dev, size_t size,
    ma_addr_t *dma_handle, gfp_t gfp)
    DMA是一种硬件机制,允许外围设备和主存之间直接传输IO数据,而不需要CPU的参与,使用DMA机制能大幅提高与设备通信的 吞吐量。DMA操作中,涉及到CPU高速缓 存和对应的内存数据一致性的问题,必须保证两者的数据一致,在x86_64体系结构中,硬件已经很 好的解决了这个问题, dma_alloc_coherent和__get_free_pages函数实现差别不大,前者实际是调用__alloc_pages函 数来分配内存,因此一次分配内存的大小限制和后者一样。
    __get_free_pages分配的内 存同样可以用于DMA操作。测试结果证明,dma_alloc_coherent
    函数一次能分配的最大内存也为4M。
  • 相关阅读:
    第一个驱动
    call Eip 技巧
    Win32 XP 下和WIN7下获取Kernel32基址的方法
    利用伪造内核文件来绕过IceSword的检测
    HOOK IDT (1)第一种方法,Int 0x2e
    壳的编写 :【统一节区粒度】
    壳的编写 【文件打开选择对话框】
    71币值转换
    71打印沙漏
    介绍自己
  • 原文地址:https://www.cnblogs.com/riskyer/p/3246886.html
Copyright © 2011-2022 走看看