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

server/2024/9/25 19:00:52/

物理内存管理

基本概念

物理内存是计算机上最重要的资源之一,指的是实际的内存设备提供的、可以通过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


http://www.ppmy.cn/server/121958.html

相关文章

tauri开发软件中,使用tauri自带的api用浏览器打开指定的url链接

有能力的可以看官方文档&#xff1a;shell | Tauri Apps 就是使用这个api来打开指定的url链接&#xff0c;要在tauri.config.json中配置打开这个api&#xff1a; 然后在前端页面中导入使用&#xff1a; import { open } from tauri-apps/api/shell; // opens the given URL o…

apache paimon简介(官翻)

介绍 如下架构所示: 读/写操作: Paimon 支持多样化的数据读写方式,并支持 OLAP 查询。 读取: 支持从历史快照(批处理模式)中消费数据,从最新偏移量(流处理模式)中读取数据,或以混合方式读取增量快照。写入: 支持从数据库变更日志(CDC)进行流式同步,从离线数据中…

el-table多选,分页切换时,选中内容不变;清空多选的内容

el-table中添加:row-key“getRowKeys” 设置true【 :reserve-selection“true”】 :row-key"getRowKeys" <el-table-column type"selection" :reserve-selection"true" width"55" align"center" fixed"left" …

Python提供内置正则表达式库

正则表达式是一种强大的文本处理工具&#xff0c;可以匹配文本片段的模式 最简单的正则表达式就是普通的字符串&#xff0c;可以匹配自身 要注意的是&#xff0c;正则表达式并不是一个程序&#xff0c;它使用一种特定的语法模式来描述在搜索文本时要匹配的一个或多个字符串。正…

解锁零售业中的AI力量:7个经过验证的增长策略

目录 将AI整合到实体零售店的好处7个经过验证的AI零售增长策略 1. 顾客行为分析2. 动态定价3. AI驱动的聊天机器人和虚拟助手4. AI驱动的库存管理5. 视觉搜索和图像识别6. 自动化的供应链优化7. 通过AR和VR增强的店内体验 中小零售企业实施AI解决方案在零售中实施AI的挑战为未…

ProgrammerAI—AI辅助编程学习指南

前言 随着AIGC&#xff08;AI生成内容&#xff09;技术的快速发展&#xff0c;诸如ChatGPT、MidJourney和Claude等大语言模型相继涌现&#xff0c;AI辅助编程工具正逐步改变程序员的工作方式。这些工具不仅可以加速代码编写、调试和优化过程&#xff0c;还能帮助解决复杂的编程…

用Java提取PDF表格到文本、CSV、Excel工作表

如何精准地提取PDF格式中嵌入的表格数据&#xff0c;并将其无缝转换为更加易于分析和操作的形式&#xff0c;如纯文本、CSV文件或Excel工作表&#xff0c;是一项重要的文档处理技巧。使用Java&#xff0c;我们可以简单地实现这一过程。本文将介绍如何利用Java从PDF文档提取表格…

清理C盘缓存,电脑缓存清理怎么一键删除,操作简单的教程

清理C盘缓存是维护电脑性能、释放磁盘空间的重要步骤。以下是一个详细且操作简单的教程&#xff0c;旨在帮助用户通过一键或几步操作完成C盘缓存的清理。 1.使用Windows系统自带工具 磁盘清理 1.打开磁盘清理工具&#xff1a; -按下“WinE”打开文件资源管理器…