memblock分配器

4. memblock

上文讲的内容都只是铺垫,为了能正确访问DTB文件并且解析得到物理地址信息。从入口到最终添加的调用过程如下图:

所以,这个章节的重点就是memblock模块,这个是早期的内存分配管理器,我不禁想起了之前在Nuttx中的内存池实现了,细节已然不太清晰了,但是框架性的思维都大同小异。

4.1 结构体

总共由三个数据结构来描述:

  • struct memblock定义了一个全局变量,用来维护所有的物理内存;
  • struct memblock_type代表系统中的内存类型,包括实际使用的内存和保留的内存;
  • struct memblock_region用来描述具体的内存区域,包含在struct memblock_type中的regions数组中,最多可以存放128个。

直接上个代码吧:

static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS] __initdata_memblock;
static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_REGIONS] __initdata_memblock;
#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
static struct memblock_region memblock_physmem_init_regions[INIT_PHYSMEM_REGIONS] __initdata_memblock;
#endif

struct memblock memblock __initdata_memblock = {
	.memory.regions		= memblock_memory_init_regions,
	.memory.cnt		= 1,	/* empty dummy entry */
	.memory.max		= INIT_MEMBLOCK_REGIONS,
	.memory.name		= "memory",

	.reserved.regions	= memblock_reserved_init_regions,
	.reserved.cnt		= 1,	/* empty dummy entry */
	.reserved.max		= INIT_MEMBLOCK_REGIONS,
	.reserved.name		= "reserved",

#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
	.physmem.regions	= memblock_physmem_init_regions,
	.physmem.cnt		= 1,	/* empty dummy entry */
	.physmem.max		= INIT_PHYSMEM_REGIONS,
	.physmem.name		= "physmem",
#endif

	.bottom_up		= false,
	.current_limit		= MEMBLOCK_ALLOC_ANYWHERE,
};

定义的memblock为全局变量,在定义的时候就进行了初始化。初始化的时候,regions指向的也是静态全局的数组,其中数组的大小为INIT_MEMBLOCK_REGIONS,也就是128个,限制了这些内存块的个数了,实际在代码中可以看到,当超过这个数值时,数组会以2倍的速度动态扩大。

初始化完了后,大体是这个样子的:

4.2 memblock_add/memblock_remove

memblock子模块,基本的逻辑都是围绕内存的添加和移除操作来展开,最终是通过调用memblock_add_range/memblock_remove_range来实现的。

  • memblock_add_range

图中的左侧是函数的执行流程图,执行效果是右侧部分。右侧部分画的是一个典型的情况,实际的情况可能有多种,但是核心的逻辑都是对插入的region进行判断,如果出现了物理地址范围重叠的部分,那就进行split操作,最终对具有相同flagregion进行merge操作。

  • memblock_remove_range
    该函数执行的一个典型case效果如下图所示:

假如现在需要移除掉一片区域,而该区域跨越了多个region,则会先调用memblock_isolate_range来对这片区域进行切分,最后再调用memblock_remove_region对区域范围内的region进行移除操作。

当调用memblock_alloc函数进行地址分配时,最后也是调用memblock_add_range来实现的,申请的这部分内存最终会添加到reserved类型中,毕竟已经分配出去了,其他人也不应该使用了。

5. arm64_memblock_init

当物理内存都添加进系统之后,arm64_memblock_init会对整个物理内存进行整理,主要的工作就是将一些特殊的区域添加进reserved内存中。函数执行完后,如下图所示:

  • 其中浅绿色的框表示的都是保留的内存区域, 剩下的部分就是可以实际去使用的内存了。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值