您的位置:首页 > 运维架构 > Linux

Linux内存初始化:bootmem到buddy的过渡

2014-02-19 13:04 405 查看
Linux的内存管理是一个Masterpiece,想把它完全彻底的搞懂真的不容易,今天主要讲一下从bootmem到buddy的过渡。

众所周知,Linux内存管理的核心是伙伴系统(buddy system)。其实在linux启动的那一刻,内存管理就已经开始了,只不过不是buddy在管理。在内核中,实现物理内存管理的allocator包括:

连续物理内存管理buddy allocator
非连续物理内存管理vmalloc allocator
小块物理内存管理slab allocator
高端物理内存管理kmapper
初始化阶段物理内存管理bootmem

其中,采用buddy allocator可以解决外部碎片问题,采用slab allocator可以解决内部碎片问题。

在系统的初始化阶段,内存管理由bootmem负责,然后在一个合适的时机,将内存管理的任务和它的成果交给它的继任者——buddy。

bootmem初始化

bootmem维护了一个位图数组bitmap来表示系统中物理内存的使用情况。bootmem根据e820变量对物理内存进行标注:哪些可用,哪些不可用。对于可用的物理内存,最初都是“未分配”,然后会将内核代码和bootmem allocator所占用的物理页标志为“已分配”。

bootmem分配

在bootmem管理阶段,它也会进行一些内存分配操作,这些操作通过类似alloc_bootmem_core()的接口函数实现。

bootmem释放——释放给buddy,这是bootmem到buddy的过渡

释放接口的核心函数有两个:free_all_bootmem_core和free_bootmem_core。

这里一定要说明白哪些物理页会被释放给buddy。

bootmem allocator中所有标识为“未分配”的页首先会被释放给buddy allocator,最后bootmem_map所占用的内存也会被释放给buddy allocator。

由于bootmem分配的页里面的数据基本上都是用于内存基本结构(例如内核、初始页表、pkmap页表、struct page实例、ramdisk、percpu变量、entry_hashtable、inode_hash_table),在系统运行期间会一直被用到,所以不会被释放。不过像__init这种类型的数据段只在系统开机的时候被使用,所以系统初始化完成之后就可以释放掉了。

另外bootmem释放给buddy的时候,调用的是buddy的释放接口,所以在buddy初始化之前不能调用free_bootmem_core函数。

一旦伙伴系统初始化完成之后,bootmemallocator就要停止使用了,系统是通过函数free_all_bootmem()来停止的,有如下调用流程:

start_kernel -> mm_init -> mem_init -> free_all_bootmem -> free_all_bootmem_core -> __free_pages_bootmem -> __free_pages

参考资料:
1、http://blog.csdn.net/kris_fei/article/details/8703433

2、http://www.cnblogs.com/openix/p/3346399.html

3、http://read.pudn.com/downloads137/doc/585334/Linux%CE%EF%C0%ED%C4%DA%B4%E6%B9%DC%C0%ED.pdf

        
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: