鸿蒙源码分析(四十七)

鸿蒙轻内核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的时候支持非连续性内存,可以实现代码的使能,实现内存的合并。调用相关接口可以实现内存池合一。

相关文章

本文章借鉴来自知乎社区华为云开发者社区。
点击查看知乎原文

猜你喜欢

转载自blog.csdn.net/m0_46976252/article/details/120091172