首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

boot memory allocator——自举内存分配器(二:在IA-32系统上的初始化)

2012-09-23 
boot memory allocator——自举内存分配器(二:在IA-32系统下的初始化)bootmem分配器的初始化时一个特定于体

boot memory allocator——自举内存分配器(二:在IA-32系统下的初始化)

bootmem分配器的初始化时一个特定于体系结构的过程,此外还取决于所述计算机的内存布局,在IA-32系统下使用setup_memory,该函数又调用setup_bootmem_allocator来初始化bootmem分配器,如下所示的代码流程图说明了IA-32系统上初始化bootmem分配器涉及的各个步骤。

boot memory allocator——自举内存分配器(二:在IA-32系统上的初始化)

bootmem分配器。这个函数实际上是init_bootmem_core()函数的封装函数。init_bootmem()函数的参数start表示内核pages表示物理内存顶点所在的页面号。而函数init_bootmem_core()就是对contig_page_data变量进行初始化。下面我们来看一下对该变量的定义:

contig_page_data的类型就是前面介绍过的pg_data_t数据结构。每个pg_data_t数据结构代表着一片均匀的、连续的内存空间。在连续空间UMA结构中,只有一个节点contig_page_data,而在NUMA结构或不连续空间UMA结构中,有多个这样的数据结构。系统中各个节点的pg_data_t数据结构通过node_next连接在一起成为一个链。有一个全局量pgdata_list则指向这个链。从上面的定义可以看出,contig_page_data是链中的第一个点。pg_data_t结构中有个指针bdata,contig_page_data被初始化为指向bootmem_data_t数据结构。注册新的自举分配器可使用init_bootmem_core,所有注册的分配器保存在一个链表中,表头就是前面所说的bdata_list。下面我们来看init_bootmem_core()函数的具体代码:

static void __init reserve_bootmem_core(bootmem_data_t *bdata, unsigned long addr,unsigned long size){unsigned long sidx, eidx;unsigned long i;BUG_ON(!size);BUG_ON(PFN_DOWN(addr) >= bdata->node_low_pfn);BUG_ON(PFN_UP(addr + size) > bdata->node_low_pfn);sidx = PFN_DOWN(addr - bdata->node_boot_start);eidx = PFN_UP(addr + size - bdata->node_boot_start);for (i = sidx; i < eidx; i++)if (test_and_set_bit(i, bdata->node_bootmem_map)) {#ifdef CONFIG_DEBUG_BOOTMEMprintk("hm, page %08lx reserved twice.\n", i*PAGE_SIZE);#endif}}

而reserve_bootmem_core()实现的内容,就是将制定内存节点内addr ~ addr+size范围内的内存标记成保留。

你会发现,它和free_bootmem_core()的实现方法如出一辙,但这里有一些细节问题需要分析一下:

eidx = PFN_UP(addr + size - bdata->node_boot_start);

对于这个结束位置的索引,free_bootmem_core()是向前保留,也就是说没有被完整释放的页将被认为是保留状态, 而reserve_bootmem_core()是向后保留,也就是说部分被占用的页将被认为是整页保留。

热点排行