内存释放:
memblock过渡到buddy
从memblock中将标记为MEMBLOCK_FREE的内存添加到buddy。
/* 把memblock管理的空闲页面都添加到伙伴系统中 */
for_each_memblock_region(mrg) {
if (mrg->flags != MEMBLOCK_FREE)
continue;
count += memblock_free_memory(mrg->base, mrg->base + mrg->size);
}
得到每一个memblock标记为MEMBLOCK的内存,一个一个添加到buddy系统。
根据memblock提供的内存起始地址和结束地址,计算出start_pfn和end_pfn。其中start_pfn利用ffs函数计算出所属的order。
ffs函数作用是查找第一个bit位为1的位置。参考https://blog.csdn.net/dai_xiangjun/article/details/118784652
比如ffs的参数是8,那么置位的位置是4,对应page就是放入order = 4的位置。2^4 = 16, 有16个4K页面。
释放的内存按照order添加到zone->free_area[order].list链表中。上图的描述虽然不是实际情况,但是很形象,原因是每一个4k page都是用struct page结构管理的。
页面合并:
页面合并是查找当前页面后面的页面来合并,而不是查找前面的页面,合并的页面必须是order相同且是未分配的页面。
如上图,前面两个order2可以合后为order3,但是中间间隔了order1,所有无法再和后面的order3合并为order4
内存分配:
假如现在我们的伙伴系统中的内存分布如上图,order4只有一个page,order3没有page,现在需要分配一个32K的连续的物理内存如何操作呢?
需要将order4上的一个page取下来,然后平均切割成两份,将后半部放入order3, 前半部分分配出去。
参考笨叔BenOS实现