当前位置: 首页 > news >正文

鸿蒙OpenHarmony【小型系统基础内核(物理内存管理)】子系统开发

物理内存管理

基本概念

物理内存是计算机上最重要的资源之一,指的是实际的内存设备提供的、可以通过CPU总线直接进行寻址的内存空间,其主要作用是为操作系统及程序提供临时存储空间。LiteOS-A内核管理物理内存是通过分页实现的,除了内核堆占用的一部分内存外,其余可用内存均以4KiB为单位划分成页帧,内存分配和内存回收便是以页帧为单位进行操作。内核采用伙伴算法管理空闲页面,可以降低一定的内存碎片率,提高内存分配和释放的效率,但是一个很小的块往往也会阻塞一个大块的合并,导致不能分配较大的内存块。

运行机制

如下图所示,LiteOS-A内核的物理内存使用分布视图,主要由内核镜像、内核堆及物理页组成。内核堆部分见堆内存管理一节。

图1 物理内存使用分布图

1

伙伴算法把所有空闲页帧分成9个内存块组,每组中内存块包含2的幂次方个页帧,例如:第0组的内存块包含2的0次方个页帧,即1个页帧;第8组的内存块包含2的8次方个页帧,即256个页帧。相同大小的内存块挂在同一个链表上进行管理。

  • 申请内存 系统申请12KiB内存,即3个页帧时,9个内存块组中索引为3的链表挂着一块大小为8个页帧的内存块满足要求,分配出12KiB内存后还剩余20KiB内存,即5个页帧,将5个页帧分成2的幂次方之和,即4跟1,尝试查找伙伴进行合并。4个页帧的内存块没有伙伴则直接插到索引为2的链表上,继续查找1个页帧的内存块是否有伙伴,索引为0的链表上此时有1个,如果两个内存块地址连续则进行合并,并将内存块挂到索引为1的链表上,否则不做处理。

    图2 内存申请示意图

    2

  • 释放内存 系统释放12KiB内存,即3个页帧,将3个页帧分成2的幂次方之和,即2跟1,尝试查找伙伴进行合并,索引为1的链表上有1个内存块,若地址连续则合并,并将合并后的内存块挂到索引为2的链表上,索引为0的链表上此时也有1个,如果地址连续则进行合并,并将合并后的内存块挂到索引为1的链表上,此时继续判断是否有伙伴,重复上述操作。

    图3 内存释放示意图

    3

开发指导

接口说明

表1 物理内存管理模块接口

功能分类接口描述
申请物理内存- LOS_PhysPageAlloc:申请一个物理页 - LOS_PhysPagesAlloc:申请物理页并挂在对应的链表上 - LOS_PhysPagesAllocContiguous:申请多页地址连续的物理内存
释放物理内存- LOS_PhysPageFree:释放一个物理页 - LOS_PhysPagesFree:释放挂在链表上的物理页 - LOS_PhysPagesFreeContiguous:释放多页地址连续的物理内存
查询地址- LOS_VmPageGet:根据物理地址获取其对应的物理页结构体指针 - LOS_PaddrToKVaddr:根据物理地址获取其对应的内核虚拟地址

开发流程

内存申请时根据需要调用相关接口,小内存申请建议使用堆内存申请相关接口,4KiB及以上内存申请可以使用上述物理内存相关接口。

说明:

  • 物理内存申请相关接口需要在OsSysMemInit接口完成初始化之后再使用;
  • 内存申请的基本单位是页帧,即4KiB;
  • 物理内存申请时,有地址连续要求的使用LOS_PhysPagesAllocContiguous接口,无地址连续的要求尽量使用LOS_PhysPagesAlloc接口,将连续的大块内存留给有需要的模块使用。

编程实例

编程示例主要是调用申请、释放接口对内存进行操作,包括申请一个页以及多个页的示例。

#include "los_vm_phys.h"#define PHYS_PAGE_SIZE 0x4000// 申请一个页
VOID OsPhysPagesAllocTest3(VOID)
{PADDR_T newPaddr;VOID *kvaddr = NULL;LosVmPage *newPage = NULL;newPage = LOS_PhysPageAlloc();if (newPage == NULL) {printf("LOS_PhysPageAlloc fail\n");return;}printf("LOS_PhysPageAlloc success\n");newPaddr = VM_PAGE_TO_PHYS(newPage);kvaddr = OsVmPageToVaddr(newPage);// Handle the physical memory// Free the physical memoryLOS_PhysPageFree(newPage);
}// 申请多个页,不要求连续
VOID OsPhysPagesAllocTest2(VOID)
{UINT32 sizeCount;UINT32 count;UINT32 size = PHYS_PAGE_SIZE;LosVmPage *vmPageArray[PHYS_PAGE_SIZE >> PAGE_SHIFT] = { NULL };UINT32 i = 0;LosVmPage *vmPage = NULL;PADDR_T pa;size = LOS_Align(size, PAGE_SIZE);if (size == 0) {return;}sizeCount = size >> PAGE_SHIFT;LOS_DL_LIST_HEAD(pageList);count = LOS_PhysPagesAlloc(sizeCount, &pageList);if (count < sizeCount) {printf("failed to allocate enough pages (ask %zu, got %zu)\n", sizeCount, count);goto ERROR;}printf("LOS_PhysPagesAlloc success\n");while ((vmPage = LOS_ListRemoveHeadType(&pageList, LosVmPage, node))) {pa = vmPage->physAddr;vmPageArray[i++] = vmPage;// Handle the physical memory}// Free the physical memoryfor (i = 0; i < sizeCount; ++i) {LOS_PhysPageFree(vmPageArray[i]);}return;ERROR:(VOID)LOS_PhysPagesFree(&pageList);
}// 申请多个连续页
VOID OsPhysPagesAllocTest1(VOID)
{VOID *ptr = NULL;LosVmPage *page = NULL;UINT32 size = PHYS_PAGE_SIZE;ptr = LOS_PhysPagesAllocContiguous(ROUNDUP(size, PAGE_SIZE) >> PAGE_SHIFT);if (ptr == NULL) {printf("LOS_PhysPagesAllocContiguous fail\n");return;}printf("LOS_PhysPagesAllocContiguous success\n");// Handle the physical memory// Free the physical memorypage = OsVmVaddrToPage((VOID *)ptr);LOS_PhysPagesFreeContiguous((VOID *)ptr, size >> PAGE_SHIFT);
}UINT32 ExamplePhyMemCaseEntry(VOID)
{OsPhysPagesAllocTest1();OsPhysPagesAllocTest2();OsPhysPagesAllocTest3();return LOS_OK;
}

结果验证

编译运行得到的结果为:

LOS_PhysPagesAllocContiguous success
LOS_PhysPagesAlloc success
LOS_PhysPageAlloc success

以上就是本篇文章所带来的鸿蒙开发中一小部分技术讲解;想要学习完整的鸿蒙全栈技术。可以在结尾找我可全部拿到!
下面是鸿蒙的完整学习路线,展示如下:
1

除此之外,根据这个学习鸿蒙全栈学习路线,也附带一整套完整的学习【文档+视频】,内容包含如下

内容包含了:(ArkTS、ArkUI、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、鸿蒙南向开发、鸿蒙项目实战)等技术知识点。帮助大家在学习鸿蒙路上快速成长!

鸿蒙【北向应用开发+南向系统层开发】文档

鸿蒙【基础+实战项目】视频

鸿蒙面经

2

为了避免大家在学习过程中产生更多的时间成本,对比我把以上内容全部放在了↓↓↓想要的可以自拿喔!谢谢大家观看!
3

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 23中设计模式,以及三种常见的设计模式demo
  • 【C++】C++库:如何链接外部库、静态链接和动态链接,以及如何自建库并使用
  • 这些主流的销售管理系统,能够有效提升客户管理效率!
  • Python范例总结
  • Nginx 限流实战教程和技巧
  • Apache Airflow如何使用
  • 如何在算家云搭建text-generation-webui(文本生成)
  • uniapp中<map>地图怎么实现点位聚合?
  • 【Qwen2-VL】通义多模态新作速读
  • 创建游戏暂停菜单
  • 力扣(leetcode)每日一题 LCR 187 破冰游戏(还是考的约瑟夫环)
  • UWA支持鸿蒙HarmonyOS NEXT
  • 【Spring】条件装配 @ConditionalOnClass @ConditionalOnBean
  • 【Midjourney中文版】智能绘画,高效便捷
  • python日志搜集分析系统
  • 【译】JS基础算法脚本:字符串结尾
  • 「译」Node.js Streams 基础
  • Android Volley源码解析
  • CSS 三角实现
  • ERLANG 网工修炼笔记 ---- UDP
  • LintCode 31. partitionArray 数组划分
  • linux安装openssl、swoole等扩展的具体步骤
  • Map集合、散列表、红黑树介绍
  • MaxCompute访问TableStore(OTS) 数据
  • Node + FFmpeg 实现Canvas动画导出视频
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • PAT A1092
  • SegmentFault 2015 Top Rank
  • springboot_database项目介绍
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • webpack4 一点通
  • 分布式熔断降级平台aegis
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • ​业务双活的数据切换思路设计(下)
  • ## 1.3.Git命令
  • #APPINVENTOR学习记录
  • #我与Java虚拟机的故事#连载08:书读百遍其义自见
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (八十八)VFL语言初步 - 实现布局
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (附源码)基于SSM多源异构数据关联技术构建智能校园-计算机毕设 64366
  • (淘宝无限适配)手机端rem布局详解(转载非原创)
  • (一)C语言之入门:使用Visual Studio Community 2022运行hello world
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • .libPaths()设置包加载目录
  • .Net CoreRabbitMQ消息存储可靠机制
  • .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(二)...
  • .NET/C# 使窗口永不激活(No Activate 永不获得焦点)
  • .Net环境下的缓存技术介绍
  • .net开发日常笔记(持续更新)
  • .net连接oracle数据库
  • .Net面试题4
  • [ 隧道技术 ] 反弹shell的集中常见方式(四)python反弹shell
  • [3D基础]理解计算机3D图形学中的坐标系变换
  • [AIR] NativeExtension在IOS下的开发实例 --- IOS项目的创建 (一)