boot memory allocator——自举内存分配器(一:基本介绍)

在启动过程期间,尽管内存管理尚未初始化,但内核仍然需要分配内存以创建各种数据结构。bootmem分配器用于在启动阶段早期分配内存。

显然,对该分配器的需求集中于简单性方面,而不是性能和通用性。因此内核开发者决定实现一个最先适配(first-fit)分配器用于在启动阶段管理内存。这是可能想到的最简单的方式。

该分配器使用一个位图来管理页,位图比特位的数目与系统中物理内存页的数目相同。比特位位1,表示页以用;比特位位0,表示页空闲。

在需要分配内存时,分配器逐位扫描位图,知道找到一个能提供足够连续页的位置,即所谓的最先最佳(first-best)或最先适配位置。

该过程不是很高效,因为每次分配都必须从头扫描比特链。因此在内核完全初始化之后,不能将该适配器用于内存管理。伙伴系统(连同slab、slub、或slob分配器)是一个好得多的备选方案。

即使最先适配分配器也必须管理一些数据。内核为系统中的每个结点都提供一个bootmem_data结构的实例,用于该用途。当然该结构所需的内存无法动态分配,必须在编译时分配给内核。bootmem_data结构定义如下:

typedef struct bootmem_data 
{
unsigned long node_boot_start;
unsigned long node_low_pfn;
void *node_bootmem_map;
unsigned long last_offset;
unsigned long last_pos;
unsigned long last_success;/* Previous allocation point.  To speed up searching */
struct list_head list;
} bootmem_data_t;


在下面提到的页时都是指的物理页帧。

node_boot_start:保存了系统中第一个页的编号,大多数体系结构下都是0。

node_low_pfn:可以直接管理的物理地址空间中最后一页的编号,换句话说,即ZONE_NORMAL的结束页。

node_bootmem_map:指向存储分配位图的内存区的指针,在IA-32系统上,用于该用途的内存区紧接着内核映像后。对应的地址保存在_end变量中,该变量在连接期间自动的地插入到内核映像之中。

last_pos:上一次分配的页的编号。如果没有请求分配整个页,则last_offset用作该页内部的偏移量。这使bbootmem分配器可以分配小于一整页的内存区(伙伴系统无法做到这一点)。

last_success:指定位图上一次成功分配内存的位置,新的分配将由此开始。尽管这使得最先适配算法稍微快了一点,但仍然无法真正代替更复杂的技术。

list:在该结构中嵌入一个list_head类型的变量,用于在全局变量bdata_list中操作该结点


内存不连续的系统可能需要多个bootmem分配器。一个典型的例子是NUMA计算机,集中每个结点注册一个bootmem分配器,但如果物理地址空间中散布着空洞,也可以为每个连续内存区注册一个bootmem分配器。

在阅读bootmem alloctor源码的过程中,经常遇到pfn,pfn是page frame number的缩写,内核把一个物理页看做一个page frame,一个物理页就是一个page frame,所以从0x0地址开始,给每个page frame一个编号,这个编号就是pfn,pfn从0开始。

// 页对齐
#define PFN_ALIGN(x)    (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
// 获取x所代表的物理地址的后一个PFN值,即x如果属于page 0, 则返回1.
#define PFN_UP(x)   (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
// 获取x所代表的物理地址的前一个PFN值,即x如果属于page 1, 则返回0.
#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
// 返回PFN的值为x时,所对应物理页的起始地址。
#define PFN_PHYS(x) ((x) << PAGE_SHIFT)

以上四个是和PFN相关的宏定义,内核使用这4个宏完成PFN到物理地址之间的映射。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值