Linux内存管理之bootmem分配器

文章详细介绍了Linux内核中bootmem分配器在系统初始化期间的内存管理和分配作用,以及其与buddy系统和slab分配器的关系。重点讲解了bootmem的核心数据结构、初始化过程、内存注册、分配和释放机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为什么要使用bootmem分配器,内存管理不是有buddy系统和slab分配器吗?由于在系统初始化的时候需要执行一些内存管理,内存分配的任务,这个时候buddy系统,slab分配器等并没有被初始化好,此时就引入了一种内存管理器bootmem分配器在系统初始化的时候进行内存管理与分配,当buddy系统和slab分配器初始化好后,在mem_init()中对bootmem分配器进行释放,内存管理与分配由buddy系统,slab分配器等进行接管。

bootmem分配器使用一个bitmap来标记物理页是否被占用,分配的时候按照第一适应的原则,从bitmap中进行查找,如果这位为1,表示已经被占用,否则表示未被占用。为什么系统运行的时候不使用bootmem分配器呢?bootmem分配器每次在bitmap中进行线性搜索,效率非常低,而且在内存的起始端留下许多小的空闲碎片,在需要非常大的内存块的时候,检查位图这一过程就显得代价很高。bootmem分配器是用于在启动阶段分配内存的,对该分配器的需求集中于简单性方面,而不是性能和通用性。

一、bootmem分配器核心数据结构

bootmem核心数据结构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;
} bootmem_data_t;

系统内存的中每一个结点(如果是内存是UMA,就只有一个这样的结构)都有一个bootmem_data_t结构,它含有bootmem分配器给结点分配内存时所需的信息。

1、node_boot_start是这个结点内存的起始地址(如果内存是UMA的话,为0);

2、node_low_pfn是低端内存最后一个page的页帧号;

3、node_bootmem_map指向内存中bitmap所在的位置;

4、last_offset是分配的最后一个页内的偏移,如果该页完全使用,则offset为0;

5、last_pos是分配最后一个页帧号;

6、last_success是最后一次成功分配的位置。

二、bootmem分配器初始化

是在init_bootmem_core函数对bootmem分配器进行初始化的。

static unsigned long __init init_bootmem_core (pg_data_t *pgdat,
    unsigned long mapstart, unsigned long start, unsigned long end)
{
    bootmem_data_t *bdata = pgdat->bdata;
    unsigned long mapsize = ((end - start)+7)/8;  /*映射的字节数*/

    pgdat->pgdat_next = pgdat_list;
    pgdat_list = pgdat;

    mapsize = (mapsize + (sizeof(long) - 1UL)) & ~(sizeof(long) - 1UL);
    bdata->node_bootmem_map = phys_to_virt(mapstart << PAGE_SHIFT);
    bdata->node_boot_start = (start << PAGE_SHIFT);
    bdata->node_low_pfn = end;

    memset(bdata->node_bootmem_map, 0xff, mapsize);  //初始化所有内存都保留

    return mapsize;
}

linux系统初始化过程中通过init_bootmem_core(NODE_DATA(0), min_low_pfn, 0, max_low_pfn)来调用这个函数初始化bootmem分配器。其中min_low_pfn是临时页表后的第一个可用页框,max_low_pfn是低端内存结束的页框。

前面说的bootmem分配器核心数据结构bootmem_data_t是内嵌在pg_data_t数据结构中(也就是节点的描述符中)。内存中的节点描述符是通过链表pgdat_list链起来的,如果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值