1) bootmem_init();
初始化bootmem内存分配器
typedef struct bootmem_data {
unsigned long node_min_pfn;
unsigned long node_low_pfn;
void *node_bootmem_map; //用于表示物理页框的使用情况,“1”表示该页框已用
unsigned long last_end_off;
unsigned long hint_idx;
struct list_head list;
} bootmem_data_t;
-------------------
FIXME:map_io中可以分配bootmem
-------------------
2) mm_init()初始化Buddy Allocator,当初始化完成后bootmem内存分配器被释放
typedef struct pglist_data {
struct zone node_zones[MAX_NR_ZONES];
struct zonelist node_zonelists[MAX_ZONELISTS];
int nr_zones;
#ifdef CONFIG_FLAT_NODE_MEM_MAP /* means !SPARSEMEM */
struct page *node_mem_map; //被Buddy Allocator使用表示物理页框的使用情况
#ifdef CONFIG_CGROUP_MEM_RES_CTLR
struct page_cgroup *node_page_cgroup;
#endif
#endif
#ifndef CONFIG_NO_BOOTMEM
struct bootmem_data *bdata;
#endif
#ifdef CONFIG_MEMORY_HOTPLUG
spinlock_t node_size_lock;
#endif
unsigned long node_start_pfn;
unsigned long node_present_pages; /* total number of physical pages */
unsigned long node_spanned_pages;
/* total size of physical page range, including holes */
int node_id;
wait_queue_head_t kswapd_wait;
struct task_struct *kswapd;
int kswapd_max_order;
} pg_data_t;
3) struct zone数据结构
struct free_area free_area[MAX_ORDER];
//空闲页框的数据结构,MAX_ORDER=11,标识连续的物理页框(2^0 ~ 2^10)
struct free_area {
struct list_head free_list[MIGRATE_TYPES]; //连接空闲的物理页框
unsigned long nr_free;
};
4) kmalloc
使用slab分配器
5) vmalloc
分配虚拟地址连续,物理地址不连续的地址
FIXME:小于4096Bytes,可用kmallc,用vmalloc得到大于1page的连续虚拟地址。
KVM Allocator(使用red-black tree)
http://en.wikipedia.org/wiki/Red_black_tree
cat /proc/buddyinfo
cat /proc/zoneinfo
Author:Woodpecker <[email protected]>