鸿蒙轻内核M核的动态内存介绍
芯片片内RAM大小无法满足要求,需要使用片外物理内存进行扩充。对于多段非连续性内存,需要内存管理模块统一管理,应用使用内存接口时不需要关注内存分配属于哪块物理内存,不感知多块内存。
多段非连续性内存如下图所示:
鸿蒙轻内核M核新增支持了多段非连续性内存区域,把多个非连续性内存逻辑上合一,用户不感知底层的不同内存块。
1. 结构体和宏定义
在文件kernel/include/los_memory.h中新增了结构体LosMemRegion用于维护多个非连续的内存区域,包含各个内存区域的开始地址和大小。如下:
typedef struct {
VOID *startAddress; /* 内存区域的开始地址 */
UINT32 length; /* 内存区域的长度 */
} LosMemRegion;
需要注意这个结构体的定义需要开启宏LOSCFG_MEM_MUL_REGIONS的情况下才生效,这个宏也是支持非连续内存区域的配置宏,定义在文件kernel/include/los_config.h中。
定义了一个魔术字OS_MEM_GAP_NODE_MAGIC,用于表示两个不连续内存区域之前的间隔Gap区域。⑵和⑶处定义2个宏,分别用于设置魔术字,验证魔术字。
#if (LOSCFG_MEM_MUL_REGIONS == 1)
/**
- When LOSCFG_MEM_MUL_REGIONS is enabled to support multiple non-continuous memory regions, the gap between two memory regions
- is marked as a used OsMemNodeHead node. The gap node could not be freed, and would also be skipped in some DFX functions. The
- 'ptr.prev' pointer of this node is set to OS_MEM_GAP_NODE_MAGIC to identify that this is a gap node.
*/
⑴ #define OS_MEM_GAP_NODE_MAGIC 0xDCBAABCD
⑵ #define OS_MEM_MARK_GAP_NODE(node) (((struct OsMemNodeHead *)(node))->ptr.prev = (struct OsMemNodeHead *)OS_MEM_GAP_NODE_MAGIC)
⑶ #define OS_MEM_IS_GAP_NODE(node) (((struct OsMemNodeHead *)(node))->ptr.prev == (struct OsMemNodeHead *)OS_MEM_GAP_NODE_MAGIC)
#else
⑵ #define OS_MEM_MARK_GAP_NODE(node)
⑶ #define OS_MEM_IS_GAP_NODE(node) FALSE
#endif
2.动态内存
算法示意图如下:
根据示意图,非连续性内存合并的过程大致有以下几个步骤:
- 1、把多段内存区域的第一块内存区域调用LOS_MemInit进行初始化
- 2、获取下一个内存区域的开始地址和长度,计算该内存区域和上一块内存区域的间隔大小gapSize。
- 2、获取下一个内存区域的开始地址和长度,计算该内存区域和上一块内存区域的间隔大小gapSize。
- 4、把当前内存区域划分为一个空闲内存块和一个尾节点,把空闲内存块插入到空闲链表。并设置各个节点的前后链接关系。
- 5、有更多的非连续内存块,重复上述步骤2-4。
一个使能变量的设置 : LOSCFG_MEM_MUL_REGIONS。
当该变量为0的时候不支持多端非连续性内存的合并。
当置为1的时候支持非连续性内存,可以实现代码的使能,实现内存的合并。调用相关接口可以实现内存池合一。
相关文章
本文章借鉴来自知乎社区华为云开发者社区。
点击查看知乎原文