Analysisofinuxmemoryallocationmethod
内存映射结构:1, 32位地址线的地址4G的内存空间,其中0-3g是用户程序独特,和3g-4g是内核的内核。
2、页面结构:在整个物理初始化,每一个4KB的页面生成相应的页面结构结构。这个页面的结构表示的物理内存页独特,并存储在mem_map全局数组。
3部分:首先,根据映射代码段选择器CS指数与GDT值作为起始地址的描述,选择相应的段描述符表,然后根据基地的段描述符,长度,许可信息检查,抵消了CS的success.32点后检查:偏移量直接与段基础阶段的积累,得到最终的访问地址。
对0-3g和mem_map映射:
因为在linux下使用的段映射平面模式,没有从逻辑地址到线性地址的变化。从部分到页面,每个用户进程有一个页目录表(PDT),和运行时存储在cr3.cr3(页目录)+ 10 + 10 = >页表= >页表基+ 12 = >物理页地址
对mem_map 3g-4g和映射:
它分为三种类型:低端存储器/普通存储器/高端存储器。
低端内存:3g-3g+16M DMA __pa线性映射
常见的内存:3G 16m-3g + 896m __pa线性映射(如果物理内存小于896m分界点,然后在3G +真实的记忆)
高端内存:3G 896-4g采用动态分配
4,高端内存(假设3G + 896是高端内存地址)
功能:访问1G以外的物理内存空间。
线性地址分为三段:vmalloc段 / / kmap_atomic KMAP段段(不同的内存分配方法)
从内存分配功能的结构上,主要分为以下几个部分:
合作伙伴算法(最原始的面向页面分配)
alloc_pages接口:
页面结构* alloc_page(unsigned int gfp_mask)-页面结构指针分配一个页面的物理内存并返回到页面的物理内存。
页面结构* alloc_pages(unsigned int gfp_mask,unsigned int命令),分配一个连续的物理页面并返回第一个物理页的页结构指针。
U3000 U3000
在内核中定义:#定义alloc_page(gfp_mask)alloc_pages(gfp_mask,0)
最后的电话是打__alloc_pages。
max_order 11,并分配到页面的最大数量是2 ^ 10(米)。
当页面被分配时,它不能直接使用。它需要获取页面的虚拟地址。
void * page_address(struct页页);
低端内存映射:__va((unsigned long)(页mem_map)<12)
高端内存映射:结构page_address_map分配一个动态的结构来管理高端内存。具体映射(内核在VMA的3G虚拟地址)是由开麦/ kmap_atomic执行。
get_free_page接口:(对alloc_pages接口两步替代功能)
无符号长get_free_page(unsigned int gfp_mask)
无符号长__get_free_page(unsigned int gfp_mask)
无符号长__get_free_pages(unsigned int unsigned int gfp_mask,顺序)
U3000 U3000
从alloc_page最大的区别(S)系列是不能申请高端内存,因为它返回一个线性地址,高端存储需要额外的映射。
b.slab缓存(重新分配大量的内存大小相同):少用
kmem_cache_t * xx_cache;
创建:xx_cache = kmem_cache_create(name sizeof(struct;XX),slab_hwcache_align,null,null);
分布:kmem_cache_alloc(xx_cache,gfp_kernel);
发布:kmem_cache_free(xx_cache,地址);
内存池
mempool不使用它。
C.kmalloc(最常用的分布接口)注:必须小于128kb
gfp_atomic冬眠,用于中断处理等。
gfp_kernel休眠,和一般情况使用这个标签
gfp_user休眠
__gfp_dma分配DMA存储器
kmalloc和kfree
d.vmalloc / vfree
vmalloc使用高端内存保留虚拟空间收集不连续的物理内存页的内存碎片造成的,这是用于不连续的物理内存分配。
对kmalloc时可以采用不分配内存和物理内存不连续的要求。(优先查找从高端内存)
E.ioremap()/()iounmap
ioremap()的作用是图的设备登记和内存的内核虚拟区域并返回的内核虚拟地址的物理地址范围。用线性地址区间也在vmmlloc段
注:
Vmalloc()和alloc_pages(_gfp_highmem)+ K图();前者是不连续的,而后者只能地图高端的内存页
__get_free_pages和alloc_pages(正常)+ page_address();两者都是完全相同的
内核地址直接映射到中、低内存通过__va / __pa
高端内存是在开麦/ kmap_atomic方式映射
个人摘要如下:
A.使用kmalloc在<< 128kb总内存分配
让睡眠:gfp_kernel
无眠:gfp_atomic
当B分配内存大于128KB,它使用get_free_pages得到页面,直接返回到虚拟地址(<4m)(或alloc_pages + page_address)。
C. B失败了,
如果你想要分配高端内存:alloc_pages(_gfp_highmem)+ K图(只有一个页面可以映射)
如果记忆是不是需要不断:vmalloc来分配大块的逻辑连续性。(不推荐)/较慢的分发速度和较慢的访问速率。
频繁使用平板创建和销毁许多大型数据结构。
E.高端内存映射:
让睡眠:Kmap(永久映射)
无眠:kmap_atomic(临时映射)将覆盖以前的地图(不推荐)