物理内存管理 - 段页式管理 http://weharmonyos.com/openharmony/zh-cn/device-dev/kernel/kernel-small-basic-memory-physical.html 更多...
函数 | |
LosVmPhysSeg * | OsGVmPhysSegGet () |
获取段数组,全局变量,变量放在 .bbs 区 更多... | |
STATIC VOID | OsVmPhysLruInit (struct VmPhysSeg *seg) |
初始化Lru置换链表 更多... | |
STATIC INT32 | OsVmPhysSegCreate (paddr_t start, size_t size) |
创建物理段,由区划分转成段管理 更多... | |
VOID | OsVmPhysSegAdd (VOID) |
添加物理段 更多... | |
VOID | OsVmPhysAreaSizeAdjust (size_t size) |
段区域大小调整 更多... | |
UINT32 | OsVmPhysPageNumGet (VOID) |
获得物理内存的总页数 更多... | |
STATIC INLINE VOID | OsVmPhysFreeListInit (struct VmPhysSeg *seg) |
初始化空闲链表,分配物理页框使用伙伴算法 更多... | |
VOID | OsVmPhysInit (VOID) |
物理段初始化 更多... | |
STATIC VOID | OsVmPhysFreeListAddUnsafe (LosVmPage *page, UINT8 order) |
将页框挂入空闲链表,分配物理页框从空闲链表里拿 更多... | |
STATIC VOID | OsVmPhysFreeListDelUnsafe (LosVmPage *page) |
将物理页框从空闲链表上摘除,见于物理页框被分配的情况 更多... | |
STATIC VOID | OsVmPhysPagesSpiltUnsafe (LosVmPage *page, UINT8 oldOrder, UINT8 newOrder) |
本函数很像卖猪肉的,拿一大块肉剁,先把多余的放回到小块肉堆里去. 更多... | |
LosVmPage * | OsVmPhysToPage (paddr_t pa, UINT8 segID) |
通过物理地址获取所属参数段的物理页框 更多... | |
LosVmPage * | OsVmPaddrToPage (paddr_t paddr) |
VOID * | OsVmPageToVaddr (LosVmPage *page) |
通过page获取内核空间的虚拟地址 参考OsArchMmuInit #define SYS_MEM_BASE DDR_MEM_ADDR /* physical memory base 物理地址的起始地址 * / 本函数非常重要,通过一个物理地址找到内核虚拟地址 内核静态映射:提升虚实转化效率,段映射减少页表项 更多... | |
LosVmPage * | OsVmVaddrToPage (VOID *ptr) |
通过虚拟地址找映射的物理页框 更多... | |
STATIC INLINE VOID | OsVmRecycleExtraPages (LosVmPage *page, size_t startPage, size_t endPage) |
回收一定范围内的页框 更多... | |
STATIC LosVmPage * | OsVmPhysLargeAlloc (struct VmPhysSeg *seg, size_t nPages) |
大块的物理内存分配 更多... | |
STATIC LosVmPage * | OsVmPhysPagesAlloc (struct VmPhysSeg *seg, size_t nPages) |
申请物理页并挂在对应的链表上 更多... | |
VOID | OsVmPhysPagesFree (LosVmPage *page, UINT8 order) |
释放物理页框,所谓释放物理页就是把页挂到空闲链表中 更多... | |
VOID | OsVmPhysPagesFreeContiguous (LosVmPage *page, size_t nPages) |
连续的释放物理页框, 如果8页连在一块是一起释放的 更多... | |
STATIC LosVmPage * | OsVmPhysPagesGet (size_t nPages) |
OsVmPhysPagesGet 获取一定数量的页框 LosVmPage实体是放在全局大数组中的, LosVmPage->nPages 标记了分配页数 更多... | |
VOID * | LOS_PhysPagesAllocContiguous (size_t nPages) |
分配连续的物理页 更多... | |
VOID | LOS_PhysPagesFreeContiguous (VOID *ptr, size_t nPages) |
释放指定页数地址连续的物理内存 更多... | |
PADDR_T | OsKVaddrToPaddr (VADDR_T kvaddr) |
VADDR_T * | LOS_PaddrToKVaddr (PADDR_T paddr) |
通过物理地址获取内核虚拟地址 更多... | |
VOID | LOS_PhysPageFree (LosVmPage *page) |
释放一个物理页框 更多... | |
LosVmPage * | LOS_PhysPageAlloc (VOID) |
申请一个物理页 更多... | |
size_t | LOS_PhysPagesAlloc (size_t nPages, LOS_DL_LIST *list) |
LOS_PhysPagesAlloc 分配nPages页个物理页框,并将页框挂入list 返回已分配的页面大小,不负责一定能分配到nPages的页框 更多... | |
VOID | OsPhysSharePageCopy (PADDR_T oldPaddr, PADDR_T *newPaddr, LosVmPage *newPage) |
拷贝共享页面 更多... | |
struct VmPhysSeg * | OsVmPhysSegGet (LosVmPage *page) |
获取物理页框所在段 更多... | |
UINT32 | OsVmPagesToOrder (size_t nPages) |
获取参数nPages对应的块组,例如 7 -> 2^3 返回 3 更多... | |
size_t | LOS_PhysPagesFree (LOS_DL_LIST *list) |
释放双链表中的所有节点内存,本质是回归到伙伴orderlist中 更多... | |
变量 | |
STATIC struct VmPhysArea | g_physArea [] |
struct VmPhysSeg | g_vmPhysSeg [VM_PHYS_SEG_MAX] |
最大32段 更多... | |
INT32 | g_vmPhysSegNum = 0 |
段总数 更多... | |
物理内存管理 - 段页式管理 http://weharmonyos.com/openharmony/zh-cn/device-dev/kernel/kernel-small-basic-memory-physical.html
基本概念 物理内存是计算机上最重要的资源之一,指的是实际的内存设备提供的、可以通过CPU总线直接进行寻址的内存空间, 其主要作用是为操作系统及程序提供临时存储空间。LiteOS-A内核管理物理内存是通过分页实现的,除了内核堆占用的一部分内存外, 其余可用内存均以4KiB为单位划分成页帧,内存分配和内存回收便是以页帧为单位进行操作。内核采用伙伴算法管理空闲页面, 可以降低一定的内存碎片率,提高内存分配和释放的效率,但是一个很小的块往往也会阻塞一个大块的合并,导致不能分配较大的内存块。 运行机制 LiteOS-A内核的物理内存使用分布视图,主要由内核镜像、内核堆及物理页组成。内核堆部分见堆内存管理一节。 ----------------------------------------------------- kernel.bin | heap | page frames (内核镜像) | (内核堆) | (物理页框) ----------------------------------------------------- 伙伴算法把所有空闲页帧分成9个内存块组,每组中内存块包含2的幂次方个页帧,例如:第0组的内存块包含2的0次方个页帧, 即1个页帧;第8组的内存块包含2的8次方个页帧,即256个页帧。相同大小的内存块挂在同一个链表上进行管理。 申请内存 系统申请20KiB内存,按一页帧4K算,即5个页帧时,9个内存块组中索引为2的链表挂着一块大小为8个页帧的内存块满足要求,分配出20KiB内存后还剩余12KiB内存, 即3个页帧,将3个页帧分成2的幂次方之和,即0跟1,尝试查找伙伴进行合并。2个页帧的内存块没有伙伴则直接插到索引为1的链表上, 继续查找1个页帧的内存块是否有伙伴,索引为0的链表上此时有1个,如果两个内存块地址连续则进行合并,并将内存块挂到索引为0的链表上,否则不做处理。 释放内存 系统释放12KiB内存,即3个页帧,将3个页帧分成2的幂次方之和,即2跟1,尝试查找伙伴进行合并,索引为1的链表上有1个内存块, 若地址连续则合并,并将合并后的内存块挂到索引为2的链表上,索引为0的链表上此时也有1个,如果地址连续则进行合并, 并将合并后的内存块挂到索引为1的链表上,此时继续判断是否有伙伴,重复上述操作。
在文件 los_vm_phys.c 中定义.
LosVmPage * LOS_PhysPageAlloc | ( | VOID | ) |
申请一个物理页
在文件 los_vm_phys.c 第 566 行定义.
VOID LOS_PhysPageFree | ( | LosVmPage * | page | ) |
释放一个物理页框
在文件 los_vm_phys.c 第 546 行定义.
size_t LOS_PhysPagesAlloc | ( | size_t | nPages, |
LOS_DL_LIST * | list | ||
) |
LOS_PhysPagesAlloc 分配nPages页个物理页框,并将页框挂入list
返回已分配的页面大小,不负责一定能分配到nPages的页框
list | |
nPages |
在文件 los_vm_phys.c 第 581 行定义.
VOID * LOS_PhysPagesAllocContiguous | ( | size_t | nPages | ) |
分配连续的物理页
在文件 los_vm_phys.c 第 478 行定义.
size_t LOS_PhysPagesFree | ( | LOS_DL_LIST * | list | ) |
释放双链表中的所有节点内存,本质是回归到伙伴orderlist中
在文件 los_vm_phys.c 第 661 行定义.
VOID LOS_PhysPagesFreeContiguous | ( | VOID * | ptr, |
size_t | nPages | ||
) |
LosVmPhysSeg * OsGVmPhysSegGet | ( | ) |
拷贝共享页面
在文件 los_vm_phys.c 第 602 行定义.
在文件 los_vm_phys.c 第 267 行定义.
VOID * OsVmPageToVaddr | ( | LosVmPage * | page | ) |
通过page获取内核空间的虚拟地址 参考OsArchMmuInit
#define SYS_MEM_BASE DDR_MEM_ADDR /* physical memory base 物理地址的起始地址 * /
本函数非常重要,通过一个物理地址找到内核虚拟地址
内核静态映射:提升虚实转化效率,段映射减少页表项
page |
在文件 los_vm_phys.c 第 288 行定义.
VOID OsVmPhysAreaSizeAdjust | ( | size_t | size | ) |
将页框挂入空闲链表,分配物理页框从空闲链表里拿
在文件 los_vm_phys.c 第 196 行定义.
STATIC VOID OsVmPhysFreeListDelUnsafe | ( | LosVmPage * | page | ) |
将物理页框从空闲链表上摘除,见于物理页框被分配的情况
在文件 los_vm_phys.c 第 213 行定义.
STATIC INLINE VOID OsVmPhysFreeListInit | ( | struct VmPhysSeg * | seg | ) |
初始化空闲链表,分配物理页框使用伙伴算法
在文件 los_vm_phys.c 第 164 行定义.
VOID OsVmPhysInit | ( | VOID | ) |
物理段初始化
在文件 los_vm_phys.c 第 181 行定义.
STATIC VOID OsVmPhysLruInit | ( | struct VmPhysSeg * | seg | ) |
初始化Lru置换链表
在文件 los_vm_phys.c 第 95 行定义.
UINT32 OsVmPhysPageNumGet | ( | VOID | ) |
申请物理页并挂在对应的链表上
在文件 los_vm_phys.c 第 356 行定义.
释放物理页框,所谓释放物理页就是把页挂到空闲链表中
在文件 los_vm_phys.c 第 393 行定义.
连续的释放物理页框, 如果8页连在一块是一起释放的
在文件 los_vm_phys.c 第 420 行定义.
OsVmPhysPagesGet 获取一定数量的页框 LosVmPage实体是放在全局大数组中的, LosVmPage->nPages 标记了分配页数
nPages |
在文件 los_vm_phys.c 第 455 行定义.
本函数很像卖猪肉的,拿一大块肉剁,先把多余的放回到小块肉堆里去.
page | |
oldOrder | 原本要买 2^2肉 |
newOrder | 却找到个 2^8肉块 |
在文件 los_vm_phys.c 第 237 行定义.
VOID OsVmPhysSegAdd | ( | VOID | ) |
添加物理段
在文件 los_vm_phys.c 第 127 行定义.
LosVmPage * OsVmVaddrToPage | ( | VOID * | ptr | ) |
STATIC struct VmPhysArea g_physArea[] |
在文件 los_vm_phys.c 第 80 行定义.
struct VmPhysSeg g_vmPhysSeg[VM_PHYS_SEG_MAX] |
INT32 g_vmPhysSegNum = 0 |