1 memblock数据结构
memblock --> memblock_type --> memblock_region
+---------------------------+ +---------------------------+
| memblock | | |
| _______________________ | | |
| | memory | | | Array of the |
| | memblock_type |-|-->| memblock_region |
| |_______________________| | | |
| | +---------------------------+
| _______________________ | +---------------------------+
| | reserved | | | |
| | memblock_type |-|-->| Array of the |
| |_______________________| | | memblock_region |
| | | |
+---------------------------+ +---------------------------+
/* Definition of memblock flags. */
enum {
MEMBLOCK_NONE = 0x0, /* No special request */
MEMBLOCK_HOTPLUG = 0x1, /* hotpluggable region */
MEMBLOCK_MIRROR = 0x2, /* mirrored region */
MEMBLOCK_NOMAP = 0x4, /* don't add to kernel direct mapping */
};
struct memblock_region {
phys_addr_t base; //region的开始物理地址
phys_addr_t size; //region的大小
unsigned long flags; //region的标志,上面枚举定义
#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
int nid;
#endif
};
struct memblock_type {
unsigned long cnt; /* number of regions */ //该类型内存的regions数量
unsigned long max; /* size of the allocated array */ //当前集合中记录内存区域最大大小
phys_addr_t total_size; /* size of all regions */ //regions总大小
struct memblock_region *regions; //指向region数组
char *name;
};
struct memblock {
bool bottom_up; /* is bottom up direction? */ //表明分配器的分配方式,true表示从低地址向高地址
phys_addr_t current_limit; //内存块大小的限制
struct memblock_type memory; //可用内存类型
struct memblock_type reserved; //预留内存类型
#ifdef CONFIG_HAVE_MEMBLOCK_PHYS_MAP
struct memblock_type physmem;
#endif
};
2 memblock结构初始化:
#define INIT_MEMBLOCK_REGIONS 128
#define INIT_PHYSMEM_REGIONS 4
#ifndef INIT_MEMBLOCK_RESERVED_REGIONS
# define INIT_MEMBLOCK_RESERVED_REGIONS INIT_MEMBLOCK_REGIONS
#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,
}
3 memblock分配释放API
其中对不同类型memblock的分配释放主要有如下:
memblock.memory分配释放API:memblock_add()和memblock_remove();
memblock.reserved分配释放API:memblock_reserve()和memblock_free()。
4 memblock debug
在内核启动bootargs,可以加入"memblock=debug",启动过程会打开memblock的log,通过打印可以看出memblock的预留、分配等操作。
在内核编译时使能了内核debug功能后,还可以通过以下操作查看memblock信息。
mount -t debugfs none /sys/kernel/debug
cat /sys/kernel/debug/memblock/memory
cat /sys/kernel/debug/memblock/reserved