文章目录
伙伴系统初始化涉及两个方面:1.初始化与伙伴系统相关的数据结构,2.将memblock管理的内存空间释放到伙伴系统中去.
1.初始化与伙伴系统相关的数据结构
对于伙伴系统相关数据结构的初始化,在以前介绍的linux内核内存初始化时就基本完成,主要包括内存节点中以下几个方面的初始化:
- 每个zone区域的free_area中所有free list链表初始化
- 每个zone区域中所有的页框描述符struct page的初始化
- 每个zone区域中的所有pageblock对应迁移类型的初始化
- 内存分配时每个内存节点的优先级列表node_zonelists初始化
- 每个zone区域的每CPU成员pageset的初始化
bootm_init()
|--->zone_sizes_init():计算每个zone能够管理的页面数,以及起始pfn号,初始化zone的等待队列hash表, 以zone区域 | | 中free_area中的所有free list链表
| |--->free_area_init_node()
| | |--->free_area_init_core()
| | | |--->init_current_empty_zone:初始化每个zone的free_area域(free list链表)
| | | |--->memmap_init:初始化每个zone中所有页对应的struct page结构,并给设置zone中每个pageblock的 | | | | migrate type(默认都为MIGRATE_MOVABLE)
build_all_zonelists():1.给每个内存节点的备用内存域进行初始化(node_zonelists)
2.给每个zone区域的每CPU成员pageset进行初始化(用于伙伴系统单页分配)
2.将memblock管理的内存空间释放到伙伴系统中去
伙伴系统相关数据初始化完完成后,就需要将memblock管理的内存空间释放到伙伴系统中去.linux内核(arm64架构 sparse内存模型)通过函数free_all_bootmem来实现.
//start_kernel() -> mm_init() -> mem_init() -> free_all_bootmem()
// mm/nobootmem.c:由于linux内核系统初始化前期由memblock管理的内存,因此选择nobootmem.c下的函数
void __init mem_init(void)
{
......
#ifndef CONFIG_SPARSEMEM_VMEMMAP
free_unused_memmap();
#endif
/* this will put all unused low memory onto the freelists */
free_all_bootmem();
......
}
/**
* free_all_bootmem - release free pages to the buddy allocator
*
* Returns the number of pages actually released.
*/
unsigned long __init free_all_bootmem(void)
{
unsigned long pages;
//将所有node中每个zone的managed_pages设置为0,该函数只会被调用一次
reset_all_zones_managed_pages();
//将memblock中的所有空闲内存释放到伙伴系统中,完成伙伴系统的初始化
pages = free_low_memory_core_early();
//totalram_pages统计内核当前伙伴系统中当闲页的总量
totalram_pages += pages;
return pages;
}
//将membloc中的所有空闲内存释放到伙伴系统中,并返回最终伙伴系统管理的空闲页框数
static unsigned
Linux伙伴系统初始化

本文介绍Linux内核中伙伴系统的初始化过程,包括数据结构初始化及内存释放。重点讲述了初始化步骤、关键函数如reserve_bootmem_region与__free_memory_core的作用。
最低0.47元/天 解锁文章
377

被折叠的 条评论
为什么被折叠?



