内核的几种内存分配与线性映射方式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lovelycheng/article/details/78359958
1. 内核中获取内存的几种方式
  
   a) 通过伙伴算法分配大片物理内存(分配 【物理页框】)
   alloc_pages(gfp_mask, order): 获得连续的页框,返回页描述符地址,是其他类型内存分配的基础。
   __get_free_pages(gfp_mask, order): 获得连续的页框,返回页框对应的线性地址。线性地址与物理地址是内核直接映射方式。不能用于大于896M的高端内存。(分配 【伙伴 + 直接线性映射地址】)

   b) 通过Slab缓冲区分配小片物理内存(分配 【伙伴 + 直接线性映射地址】):
   kmem_cache_create: 建立slab的高速缓冲区
   kmem_cache_alloc: 申请slab内存块
   kmalloc(gfp_mask, size): 获得连续的以字节为单位的物理内存,返回线性地址。

   c) 非连续内存区分配(分配 【伙伴 + 非连续区线性映射地址】,物理内存是 __GFP_HIGHMEM(分配顺序是HIGH, NORMAL, DMA )):
   vmalloc(size): 分配非连续内存区,线性地址连续,物理地址不连续,减少外碎片,但是性能低,因为要打乱内核页表。通常只是分配大内存时,比如为活动的交互区分配数据结构、加载内核模块时分配空间、为IO驱动程序分配缓冲区。

   d) 高端内存映射(通常是512或1024个表项或线性地址)(仅分配 【线性地址】,要求页面是高端 );
   kmap(struct page * page): 获取高端内存永久内核映射的线性地址。
   kmap_atomic(struct page * page, enum km_type type): 获取高端内存临时内核映射的线性地址。

   e) 固定线性地址映射(通常也是指定几个线性地址)(仅分配 【线性地址】,页面无要求):
   set_fixmap(idx, phys): 把一个物理地址映射到一个固定的线性地址上。
   set_fixmap_nocache(idx, phys): 把一个物理地址映射到一个固定的线性地址上,禁用该页高速缓存。

2. 以上函数均修改主内核页表swapper_pg_dir完成映射。 

猜你喜欢

转载自blog.csdn.net/lovelycheng/article/details/78359958
今日推荐