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完成映射。
阅读(2115) | 评论(0) | 转发(0) |