从物理内存角度描述内存之间的关系(bootmem_init)

来源:互联网 发布:文心雕龙数据库有吗 编辑:程序博客网 时间:2024/06/13 22:25

1.内存条(bank):由内存插槽组成
2.节点(node):从一个cpu 访问速度相同的内存的集合,包含多个bank,使用pg_data_t 表示,称为节点描述符
3.uma:cpu 对所以内存访问的速度一致
numa:cpu 对所以内存访问的速度不一致
4.zone:节点中具有相同内存属性的区域,有zone 结构管理
一般分为dma,normal,hight 三个区域
5.page frame:zone 管理内存的最小物理单位,由page 结构体管理。
通过mem_map 全局数组访问
内存管理结构之间的关系

新版本里bootmem_init 改动很大,但是最终都调用
void __paginginit free_area_init_node(int nid, unsigned long *zones_size,unsigned long node_start_pfn, unsigned long *zholes_size)
函数来调用free_area_init_core 函数来初始化free_area.
调用的关键函数:memmap_init—–>memmap_init_zone

新版:zone_sizes_init()函数干这事情
在较新的内核中还引入了一种新的机制来在启动阶段分配预留内存,这就是memblock。memblock这个部件在初始化阶段会获取系统的所有物理内存的信息,并将它们分为两类,常规内存和保留内存,在内存刚被发现时它都是常规内存,内核部件可以通过memblock_alloc这个API来申请并预留一片内存区域,通过memblock_free可以释放相应的内存区域,它们的工作机制类似于bootmem。不同于bootmem的是:
bootmem需要在bootmem分配器初始化完成后才能调用,从代码上来说,bootmem在start_kernel->setup_arch->do_init_bootmem中进行初始化,也就是直到这一步之后它才能使用。而memblock的初始化则在:early_setup->early_init_devtree->early_init_dt_scan_memory_ppc(PPC为例),在PPC中,early_setup是在start_kernel之前的。从两者的功能上来说,也可以看出其先后,bootmem是一个内存分配器,它本身就需要使用物理内存,而memblock则完成物理内存的检测,因而bootmem可用的时间点必定在memblock之后。
memblock用链表来维护保留区域以及常规内存,而bootmem的管理则使用位图来管理,相对而言memblock更灵活(bootmem每次分配进行搜索时可能会从上一次分配结束的地址开始找到一块满足分配的连续区域,因而可能引入碎片,而且如果有大量分配,搜索位图也比较慢,这也是这个简单的分配器的一个弊端。