1.页 <linux/mm_types.h> struct page; 内核把物理页作为内存管理的基本单位;内存管理单元(MMU)把虚拟地址转换为物理地址, 通常以页为单位进行处理。MMU以页大小为单位来管理系统中的也表。 内核struct page管理系统中所有的页. 2.区 <linux/mmzone.h> struct zone; Linux将内核空间地址划分为三个区:ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM。 在x86结构中,三种类型的区域如下: ZONE_DMA 0-16MB ZONE_NORMAL 16MB-896MB ZONE_HIGHMEM 896MB - tail 3.页操作 static inline struct page *alloc_pages(gfp_t gfp_mask, unsigned int order) 分配2**order个连续的物理页,返回指向第一个页的page结构体指针,max(order)=11,12 void *page_address(const struct page *page) 返回指向给定物理页当前所在的逻辑地址 extern unsigned long get_zeroed_page(gfp_t gfp_mask); extern void free_pages(unsigned long addr, unsigned int order); 4.内存操作 kmalloc分配以字节为单位的一块内核内存,分配的内存物理上连续: void *kmalloc(size_t size, gfp_t flags) void kfree(const void *addr) vmalloc分配的内存虚拟地址是连续的,而物理地址则无需连续: void *vmalloc(unsigned long size) void vfree(const void *addr) 5.slab层 Linux内核提供了slab来管理频繁分配释放的内存: slab创建高速缓存组,每个高速缓存被划分不同状态的slab,slab由一个或多个物理上连续的页组成。 每个slab处于三种状态之一:满,部分满,空。 高速缓存,slab,对象之间的关系:

slab数据结构和接口:
每个高速缓存用kmem_cache结构来表示:
struct kmem_cache {
struct kmem_list3 **nodelists;
}
缓存区包含三种slab:满,未满,空闲
struct kmem_list3 {
struct list_head slabs_partial; /* partial list first, better asm code */
struct list_head slabs_full;
struct list_head slabs_free;
};
每一个slab包含多个对象:
struct slab {
struct list_head list;
unsigned long colouroff;
void *s_mem; /* including colour offset */
unsigned int inuse; /* num of objs active in slab */
kmem_bufctl_t free;
unsigned short nodeid;
};
6.slab操作
kmem_cache_create用来创建一个新缓存:
struct kmem_cache *kmem_cache_create (const char *name, size_t size, size_t align, unsigned long flags, void (*ctor)(void *))
flags 参数指定了为缓存启用的选项:
SLAB_RED_ZONE :在对象头、尾插入标志,用来支持对缓冲区溢出的检查。
SLAB_POISON :使用一种己知模式填充slab,允许对缓存中的对象进行监视(对象属对象所有,不过可以在外部进行修改)。
SLAB_HWCACHE_ALIGN :指定缓存对象必须与硬件缓存行对齐。
kmem_cache_alloc从缓存中返回一个对象:
void kmem_cache_alloc( struct kmem_cache *cachep, gfp_t flags );
如果缓存目前为空,那么这个函数就会调用 cache_alloc_refill 向缓存中增加内存。
7.高端内存的映射
kmap永久映射,可能阻塞,映射一个给定的page结构到内核地址空间
void *kmap(struct page *page)
void kunmap(struct page *page)
临时映射:不会阻塞
void *kmap_atomic(struct page *page)