博客
关于我
(从进程/线程视角看内存)鸿蒙内核源码分析
阅读量:793 次
发布时间:2023-01-25

本文共 3508 字,大约阅读时间需要 11 分钟。

鸿蒙内核内存管理机制从进程和线程视角分析

概述

鸿蒙内核的内存管理机制涉及多个复杂概念,尤其是从进程和线程的角度来看,内存管理的实现细节尤为重要。本文将从进程和线程的创建视角,深入剖析鸿蒙内核内存管理的运作机制。


进程内存描述符LosVmSpace

进程使用的内存由LosVmSpace结构体描述,内部包含多个虚拟存储区域(region)。Linux内核从2.4.10版本起,采用红黑树(regionRbTree)组织虚拟区,提升操作效率。LosVmSpace还维护物理地址映射相关的信息,确保进程能够在用户空间和内核空间之间切换。

结构体定义

typedef struct LosVmSpace {    LOS_DL_LIST        node;       /* vm space dl list */    LOS_DL_LIST        regions;    /* region dl list */    LosRbTree          regionRbTree;/* region红黑树根 */    LosMux            regionMux;  /* region list_mutex */    VADDR_T           base;       /* vm space base address */    UINT32            size;       /* vm space size */    VADDR_T           heapBase;    /* heap base address */    VADDR_T           heapNow;     /* heap base address */    LosVmMapRegion    *heap;      /* heap region */    VADDR_T           mapBase;    /* mapping area base */    UINT32            mapSize;    /* mapping area size */    LosArchMmu        archMmu;    /* vm mapping物理内存 */    #ifndef LOSCFG_DRIVERS_TZDRIVER    VADDR_T           codeStart;   /* user process code area start */    VADDR_T           codeEnd;     /* user process code area end */    #endif} LosVmSpace;

分区机制

LosVmSpace将内存划分为多个虚拟存储区域,主要分为以下几种类型:

  • 匿名内存(anon):由进程直接分配的内存,通常用于栈和堆。
  • 文件映射(file):基于文件的内存分配,常用于共享或持久化存储。
  • 设备映射(device):通过设备文件访问的内存,例如类似 /dev/shm 的临时存储。

  • 用户态进程初始化与内存分配

    所有用户程序的父进程都是由init进程发fork而来的。本文将重点分析init进程的内存初始化过程,以及如何为进程分配初始栈和堆空间。

    栈和堆分配

    在进程创建时,首先需要分配栈空间和堆空间。栈用于存储函数调用信息(如返回地址、局部变量等),而堆则用于动态内存分配。

    栈分配代码
    static Void* OsUserInitStackAlloc(UINT32 processID, UINT32* size) {    LosVmMapRegion* region = NULL;    LosProcessCB* processCB = OS_PCB_FROM_PID(processID);    UINT32 stackSize = ALIGN(OS_USER_TASK_STACK_SIZE, PAGE_SIZE);    region = LOS_RegionAlloc(processCB->vmSpace, 0, stackSize,                            VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE,                            0);    if (region == NULL) {        return NULL;    }    LOS_SetRegionTypeAnon(region);    region->regionFlags |= VM_MAP_REGION_FLAG_STACK;    *size = stackSize;    return (Void*)(UINTPTR)region->range.base;}
    堆分配代码
    typedef struct VmMapRegion {    LosRbNode         rbNode;      /* 区域红黑树节点 */    LosVmSpace        *space;       /* 所属虚拟内存空间 */    LOS_DL_LIST       node;         /* 区域双向链表节点 */    VmMapRange         range;        /* 区域地址范围 */    VM_OFFSET_T       pgOff;       /* 区域相对于文件的页移位 */    UINT32           regionFlags;   /* 区域标志 */    UINT32           shmid;        /* 区域的共享内存ID */    UINT8            protectFlags;  /* 保护标志 */    UINT8            forkFlags;     /* 复制模式 */    UINT8            regionType;    /* 区域类型:anon,file,dev */    union {        struct VmRegionFile { /* 跟踪信息,省略详细内容 */ };        struct VmRegionAnon { /* 匿名内存结构,省略详细内容 */ };        struct VmRegionDev { /* 设备内存结构,省略详细内容 */ };    } unTypeData;} VmMapRegion;

    记录初始化与地址映射

    在用户进程初始化时,首先需要加载代码和数据段。这些段由内核映射到虚拟地址空间中,确保用户程序可以正常运行。具体来说,Los_VaddrToPaddrMmap函数负责将用户虚拟地址映射到物理地址。

    进程启动

    最后,通过OS_UserInitProcessStart函数启动新的用户任务,任务入口函数指向应用程序的main函数。


    相关概念解析

    逻辑地址(Logical Address)

    逻辑地址是程序使用的内存 references,通常是段中的偏移地址。例如,在C语言中使用指针时,指针的值即为逻辑地址。逻辑地址在保护模式下与物理地址不同,需要通过页表和段表进行转换。

    线性地址(Linear Address)

    线性地址是逻辑地址与物理地址之间的中间层。在分页或分段机制启用时,线性地址会被转换为物理地址。例如,在无分页机制的情况下,线性地址就是物理地址。

    物理地址(Physical Address)

    物理地址是CPU访问内存的最终地址,与地址总线相连接。无论是单个字节还是多个字节,物理地址都直接对应外存器的物理位置。

    虚拟内存(Virtual Memory)

    虚拟内存是操作系统为程序提供的逻辑内存扩展功能,使得程序可以运行于远超系统物理内存的虚拟空间中。通过交换、分页和页面技术,虚拟内存管理内存资源极为复杂。


    总结

    从进程和线程的视角分析鸿蒙内核的内存管理机制,核心是理解如何为进程分配和管理内存区域。本文从初始进程创建、内存分配到栈和堆、以及地址转换等方面展开讨论,为深入理解鸿蒙内核内存管理奠定基础。

    转载地址:http://rkryk.baihongyu.com/

    你可能感兴趣的文章
    java教育辅导班信息网(ssm)
    查看>>
    BurpSuite实战九之使用Burp Repeater
    查看>>
    Ceph企业级实战
    查看>>
    Ceph对象存储详解
    查看>>
    Cisco防火墙配置实战
    查看>>
    DDNS动态域名无固定IPSEC配置实战
    查看>>
    DELL笔记本UEFI+GPT安装window10与Ubuntu双系统
    查看>>
    Dockerfile 指令详解
    查看>>
    Docker安装MongoDB(附Docker虚拟机环境与MongoDB客户端连接工具)
    查看>>
    DRBL+Clonezilla全自动批量安装操作系统
    查看>>
    Dva员工增删改查Demo实现-优化
    查看>>
    EasyUi的使用与代码编写(一)
    查看>>
    ECSHOP实现收货国家省市由选择下拉菜单改为手动
    查看>>
    Edge浏览器打开控制台后程序总是停止进入debug模式关闭教程【八仙过海之又一过海方案】
    查看>>
    Educational Codeforces Round 28
    查看>>
    ed编辑器--适用于shell脚本内编辑文件的最最简单编辑器
    查看>>
    EF 资料
    查看>>
    Effective Modern C++:02auto
    查看>>
    efficientnet最合适的尺寸和最后一层的层数
    查看>>
    Ehcache Java开源缓存框架
    查看>>